代码拉取完成,页面将自动刷新
"use strict";
// 加载相关模块
import AV, { Conversation } from "leancloud-storage";
import * as bootstrap from 'bootstrap';
import "./node_modules/bootstrap/dist/css/bootstrap.css";
import appConfig from "./config.json";
import "./style.css";
import { markdown } from 'markdown';
const { Query, User } = AV;
let ui = new Object();
ui.Status = "not-initialized";
// 初始化 leancloud-storage
AV.init({
// 此处的 appID、appKey、serverURL 等数据,需要时到 config.json 中修改。
appId: appConfig.AppID,
appKey: appConfig.AppKey,
serverURL: appConfig.ServerURL
});
const currentUser = AV.User.current();
const social = AV.Object.extend('social_data');
const social_reply = AV.Object.extend('social_reply');
// 如果有危险代码,返回true
function xssif(str) {
var patrn = new RegExp("<");
if (!patrn.test(str)) {
return false;
} else {
return true;
}
}
let viewMarkHelp = () => {
window.open("https://www.runoob.com/markdown/md-tutorial.html")
}
let publishConversation = (newConversationTitle, newConversationContent) => {
if (xssif(newConversationTitle) || xssif(newConversationContent)) {
window.alert("贴文中含有非法字符");
} else {
let newpost = new social();
newpost.set('title', newConversationTitle);
newpost.set('sender', AV.User.current());
newpost.set('content', newConversationContent);
newpost.save().then(() => {
ui.conversationList();
});
}
}
let userLogin = (username, passwd) => {
AV.User.logIn(username, passwd).then((user) => {
// 登录成功
window.location.reload();
}, (error) => {
alert("登录失败,可能是密码错误或者没有注册过。");
});
}
let userLogout = () => {
AV.User.logOut();
window.location.reload();
}
let userReg = (username, passwd) => {
let user = new AV.User();
user.setUsername(username);
user.setPassword(passwd);
user.signUp().then((user) => {
alert(`注册成功。`);
window.location.reload();
}, (error) => {
alert("注册失败。可能是用户名已被使用")
});
}
let publishReply = (conversationId, replyContent) => {
if (xssif(conversationId) || xssif(replyContent)) {
window.alert("回复中含有非法字符");
} else {
let newreply = new social_reply();
newreply.set('conversation_id', conversationId);
newreply.set('sender', AV.User.current());
newreply.set('replyContent', replyContent);
newreply.save().then(() => {
let query = new AV.Query('social_data');
query.equalTo('objectId', conversationId);
query.include("sender");
query.find().then((data) => {
ui.viewConversation(data[0].attributes.title, data[0].attributes.sender.attributes.username, data[0].attributes.content, conversationId, data[0].updatedAt);
})
})
}
}
let deleteConversation = (conversation_id) => {
let conversation = AV.Object.createWithoutData('social_data', conversation_id);
console.log(conversation);
conversation.destroy().then(() => {
ui.conversationList();
})
}
let deleteReply = (reply_id, conversation_id) => {
console.log(reply_id);
let reply = AV.Object.createWithoutData('social_reply', reply_id);
console.log(reply);
reply.destroy().then(() => {
let query = new AV.Query('social_data');
query.equalTo('objectId', conversation_id);
query.include("sender");
query.find().then((data) => {
ui.viewConversation(data[0].attributes.title, data[0].attributes.sender.attributes.username, data[0].attributes.content, conversation_id, data[0].updatedAt);
})
})
}
// 具体贴文的页面
ui.viewConversation = (conversation_title, conversation_sender, conversation_content, conversation_id, conversation_date) => {
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"></div>`;
if (xssif(conversation_title) || xssif(conversation_sender) || xssif(conversation_id) || xssif(conversation_content)) {
conversation_title = "[贴文不存在]";
conversation_sender = "[发布者不存在]";
conversation_content = "[此帖可能含有危险信息,已被过滤。]";
conversation_id = "[错误的id]";
// 刷新页面,防止进一步破坏页面
window.location.reload();
}
// 主题帖的内容
let CanvasBackBtn = document.createElement("button");
CanvasBackBtn.className = "btn btn-success";
CanvasBackBtn.innerText = "返回帖子列表";
CanvasBackBtn.onclick = ui.conversationList;
let CanvasFirstBr_A = document.createElement("br");
let CanvasFirstBr_B = document.createElement("br");
let CanvasConversationTitle = document.createElement("h3");
CanvasConversationTitle.innerText = conversation_title;
let CanvasConversationSender = document.createElement("p");
CanvasConversationSender.innerHTML = `此主题帖由<b>${conversation_sender}</b>于<b>${conversation_date}</b>发表:`;
CanvasConversationSender.style = "color:grey";
let CanvasConversationContent = document.createElement("div");
CanvasConversationContent.innerHTML = markdown.toHTML(conversation_content);
CanvasConversationContent.style = "background-color:whitesmoke;padding:8px";
document.getElementsByClassName("container")[0].appendChild(CanvasBackBtn);
document.getElementsByClassName("container")[0].appendChild(CanvasFirstBr_A);
document.getElementsByClassName("container")[0].appendChild(CanvasFirstBr_B);
document.getElementsByClassName("container")[0].appendChild(CanvasConversationTitle);
document.getElementsByClassName("container")[0].appendChild(CanvasConversationSender);
document.getElementsByClassName("container")[0].appendChild(CanvasConversationContent);
let CanvasConversationProfile = document.createElement("button");
CanvasConversationProfile.className = "btn btn-link btn-sm";
CanvasConversationProfile.innerText = `查看${conversation_sender}的个人主页`;
CanvasConversationProfile.onclick = () => {
ui.viewUserProfile(conversation_sender);
};
document.getElementsByClassName("container")[0].appendChild(CanvasConversationProfile);
if (conversation_sender === currentUser.attributes.username) {
// 用户可以删除自己的主题帖
let CanvasConversationDelete = document.createElement("button");
CanvasConversationDelete.className = "btn btn-link btn-sm";
CanvasConversationDelete.innerText = `删除该主题帖`;
CanvasConversationDelete.onclick = () => {
deleteConversation(conversation_id);
};
document.getElementsByClassName("container")[0].appendChild(CanvasConversationDelete);
}
// 查看已有的回复
let query = new AV.Query('social_reply');
query.equalTo('conversation_id', conversation_id);
query.include("sender");
query.find().then((data) => {
if (data.length !== 0) {
let CanvasHr_First = document.createElement("hr");
document.getElementsByClassName("container")[0].appendChild(CanvasHr_First);
let CanvasReplyHeader = document.createElement("h1");
CanvasReplyHeader.innerText = "回复列表";
document.getElementsByClassName("container")[0].appendChild(CanvasReplyHeader);
let CanvasReplyList = document.createElement("ul");
CanvasReplyList.className = "list-group";
// 回复是按时间正序排序
for (let i = 0; i < data.length; i++) {
if (xssif(data[i].attributes.conversation_id) || xssif(data[i].attributes.sender.attributes.username) || xssif(data[i].attributes.replyContent)) {
// 过滤回复
} else {
// new
let CanvasReplyListElement = document.createElement("li");
CanvasReplyListElement.className = "list-group-item list-group-item-action";
let CanvasReplyListElementSender = document.createElement("p");
CanvasReplyListElementSender.className = "mb-1";
CanvasReplyListElementSender.innerHTML = `此回复由<b>${data[i].attributes.sender.attributes.username}</b>于<b>${data[i].updatedAt}</b>发表:`;
let CanvasReplyListElementContent = document.createElement("p");
CanvasReplyListElementContent.className = "mb-1";
CanvasReplyListElementContent.innerHTML = markdown.toHTML(data[i].attributes.replyContent);
CanvasReplyListElementContent.style = "background-color:whitesmoke;padding:8px";
CanvasReplyListElement.appendChild(CanvasReplyListElementSender);
CanvasReplyListElement.appendChild(CanvasReplyListElementContent);
let CanvasReplyListElementProfile = document.createElement("button");
CanvasReplyListElementProfile.className = "btn btn-link btn-sm";
CanvasReplyListElementProfile.innerText = `查看${data[i].attributes.sender.attributes.username}的个人主页`;
CanvasReplyListElementProfile.onclick = () => {
ui.viewUserProfile(data[i].attributes.sender.attributes.username);
};
CanvasReplyListElement.appendChild(CanvasReplyListElementProfile);
console.log(data);
if (data[i].attributes.sender.attributes.username === currentUser.attributes.username) {
// 用户可以删除自己的回复
let CanvasReplyDelete = document.createElement("button");
CanvasReplyDelete.className = "btn btn-link btn-sm";
CanvasReplyDelete.innerText = `删除该回复`;
CanvasReplyDelete.onclick = () => {
deleteReply(data[i].id, conversation_id);
};
CanvasReplyListElement.appendChild(CanvasReplyDelete);
}
CanvasReplyList.appendChild(CanvasReplyListElement);
}
}
document.getElementsByClassName("container")[0].appendChild(CanvasReplyList);
}
// 发表回复
let CanvasNewReplyHeader = document.createElement("h1");
CanvasNewReplyHeader.innerText = "发表你的回复!";
let CanvasBr_A = document.createElement("br");
let CanvasBr_B = document.createElement("br");
document.getElementsByClassName("container")[0].appendChild(CanvasBr_A);
document.getElementsByClassName("container")[0].appendChild(CanvasBr_B);
let CanvasHr_Last = document.createElement("hr");
document.getElementsByClassName("container")[0].appendChild(CanvasHr_Last);
document.getElementsByClassName("container")[0].appendChild(CanvasNewReplyHeader);
if (currentUser) {
let CanvasNewReplySender = document.createElement("p");
CanvasNewReplySender.innerText = `以${AV.User.current().attributes.username}身份登录中`;
let CanvasNewReplyContent = document.createElement("textarea");
CanvasNewReplyContent.placeholder = "在这里输入你的回复,支持使用 Markdown 格式书写。";
CanvasNewReplyContent.className = "form-control";
CanvasNewReplyContent.style = "height:200px";
let CanvasReplyBtn = document.createElement("button");
CanvasReplyBtn.className = "btn btn-success";
CanvasReplyBtn.innerText = "发表回复";
CanvasReplyBtn.onclick = () => { publishReply(conversation_id, CanvasNewReplyContent.value.replaceAll("\n", "\n\n")) };
document.getElementsByClassName("container")[0].appendChild(CanvasNewReplySender);
document.getElementsByClassName("container")[0].appendChild(CanvasNewReplyContent);
document.getElementsByClassName("container")[0].appendChild(CanvasReplyBtn);
let viewMarkHelpBtn = document.createElement("button");
viewMarkHelpBtn.className = "btn btn-link";
viewMarkHelpBtn.innerText = "点击这里了解如何使用 Markdown。";
viewMarkHelpBtn.onclick = viewMarkHelp;
document.getElementsByClassName("container")[0].appendChild(viewMarkHelpBtn);
} else {
let CanvasHint = document.createElement("p");
CanvasHint.innerText = "若要发表回复,你必须先登录。"
document.getElementsByClassName("container")[0].appendChild(CanvasHint);
let loginBtn = document.createElement("button");
loginBtn.className = "btn btn-success";
loginBtn.innerText = "登录或注册账户";
loginBtn.onclick = ui.UserLogin;
document.getElementsByClassName("container")[0].appendChild(loginBtn);
}
});
}
// 发布新帖子的代码
ui.publishConversation = () => {
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"><h1>新建帖子</h1></div>`;
// 手动构建并组装相关元素
if (currentUser) {
let CanvasPublishConversationInputTitle = document.createElement("input");
CanvasPublishConversationInputTitle.className = "form-control";
CanvasPublishConversationInputTitle.placeholder = "在这里输入帖子的标题";
let CanvasPublishConversationInputSender = document.createElement("p");
CanvasPublishConversationInputSender.innerText = `以${AV.User.current().attributes.username}身份登录中`;
let CanvasPublishConversationInputContent = document.createElement("textarea");
CanvasPublishConversationInputContent.className = "form-control";
CanvasPublishConversationInputContent.placeholder = "在这里输入帖子的内容,支持使用 Markdown 格式书写。";
CanvasPublishConversationInputContent.style = "height: 300px"
document.getElementsByClassName("container")[0].appendChild(CanvasPublishConversationInputTitle);
document.getElementsByClassName("container")[0].appendChild(CanvasPublishConversationInputSender);
document.getElementsByClassName("container")[0].appendChild(CanvasPublishConversationInputContent);
let CanvasPublishBtn = document.createElement("button");
CanvasPublishBtn.className = "btn btn-primary";
CanvasPublishBtn.innerText = "提交";
CanvasPublishBtn.onclick = () => {
publishConversation(CanvasPublishConversationInputTitle.value, CanvasPublishConversationInputContent.value.replaceAll("\n", "\n\n"))
}
let CanvasCancelBtn = document.createElement("button");
CanvasCancelBtn.className = "btn btn-light";
CanvasCancelBtn.innerText = "返回帖子列表";
CanvasCancelBtn.onclick = ui.conversationList;
document.getElementsByClassName("container")[0].appendChild(CanvasPublishBtn);
document.getElementsByClassName("container")[0].appendChild(CanvasCancelBtn);
let viewMarkHelpBtn = document.createElement("button");
viewMarkHelpBtn.className = "btn btn-link";
viewMarkHelpBtn.innerText = "点击这里了解如何使用 Markdown。";
viewMarkHelpBtn.onclick = viewMarkHelp;
document.getElementsByClassName("container")[0].appendChild(viewMarkHelpBtn);
}
else {
let CanvasHint = document.createElement("p");
CanvasHint.innerText = "若要发表一个主题帖,你必须先登录。"
document.getElementsByClassName("container")[0].appendChild(CanvasHint);
let loginBtn = document.createElement("button");
loginBtn.className = "btn btn-success";
loginBtn.innerText = "登录或注册账户";
loginBtn.onclick = ui.UserLogin;
document.getElementsByClassName("container")[0].appendChild(loginBtn);
let CanvasCancelBtn = document.createElement("button");
CanvasCancelBtn.className = "btn btn-light";
CanvasCancelBtn.innerText = "返回帖子列表";
CanvasCancelBtn.onclick = ui.conversationList;
document.getElementsByClassName("container")[0].appendChild(CanvasCancelBtn);
}
}
// 加载帖子列表的代码
let numberOfConversation = new Number();
let conversationList = new Array();
ui.conversationList = () => {
// 获取全部帖子列表
let query = new AV.Query('social_data');
query.include("sender");
let CanvasConversationList = document.createElement("ul");
CanvasConversationList.className = "list-group";
query.find().then((data) => {
numberOfConversation = data.length;
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"><h1>帖子列表</h1></div>`;
// 条件判断,防止数组越界导致异常
if (numberOfConversation !== 0) {
// 倒序
for (let i = numberOfConversation - 1; i > -1; i = i - 1) {
conversationList[i] = data[i];
// 加载到视图中
// 手动构建并组装相关元素
if (xssif(data[i].attributes.title) || xssif(data[i].attributes.sender.attributes.username) || xssif(data[i].attributes.content)) {
// 过滤
} else {
let CanvasConversationListElement = document.createElement("li");
CanvasConversationListElement.className = "list-group-item list-group-item-action";
let CanvasConversationListElementChild = document.createElement("div");
CanvasConversationListElementChild.className = "d-flex w-100 justify-content-between";
let CanvasConversationListElementChildTitle = document.createElement("h5");
CanvasConversationListElementChildTitle.innerHTML = `<b>${data[i].attributes.title}</b>`;
CanvasConversationListElementChildTitle.className = "mb-1";
let CanvasConversationListElementSender = document.createElement("p");
CanvasConversationListElementSender.className = "mb-1";
CanvasConversationListElementSender.innerHTML = `此主题帖由<b>${data[i].attributes.sender.attributes.username}</b>于<b>${data[i].updatedAt}</b>发表`;
CanvasConversationListElementChild.appendChild(CanvasConversationListElementChildTitle);
CanvasConversationListElement.appendChild(CanvasConversationListElementChild);
CanvasConversationListElement.appendChild(CanvasConversationListElementSender);
CanvasConversationListElement.onclick = function () {
ui.viewConversation(data[i].attributes.title, data[i].attributes.sender.attributes.username, data[i].attributes.content, data[i].id, data[i].updatedAt)
}
CanvasConversationList.appendChild(CanvasConversationListElement);
}
}
}
let CanvasSubtitle = document.createElement("p");
CanvasSubtitle.innerText = `目前共有${numberOfConversation}条帖子;部分帖子可能被XSS过滤器隐藏。`;
document.getElementsByClassName("container")[0].appendChild(CanvasSubtitle);
// 发布新帖子的按钮
let publishBtn = document.createElement("button");
publishBtn.className = "btn btn-primary";
publishBtn.innerText = "新建帖子";
publishBtn.onclick = ui.publishConversation;
document.getElementsByClassName("container")[0].appendChild(publishBtn);
if (currentUser) {
let loginBtn = document.createElement("button");
loginBtn.className = "btn btn-success";
loginBtn.innerText = `编辑[${currentUser.attributes.username}]的个人主页`;
loginBtn.onclick = ui.UserCenter;
document.getElementsByClassName("container")[0].appendChild(loginBtn);
let logoutBtn = document.createElement("button");
logoutBtn.className = "btn btn-warning";
logoutBtn.onclick = userLogout;
logoutBtn.innerText = `退出登录`;
document.getElementsByClassName("container")[0].appendChild(logoutBtn);
} else {
let loginBtn = document.createElement("button");
loginBtn.className = "btn btn-success";
loginBtn.innerText = "登录或注册账户";
loginBtn.onclick = ui.UserLogin;
document.getElementsByClassName("container")[0].appendChild(loginBtn);
}
let CanvasBr_A = document.createElement("br");
let CanvasBr_B = document.createElement("br");
document.getElementsByClassName("container")[0].appendChild(CanvasBr_A);
document.getElementsByClassName("container")[0].appendChild(CanvasBr_B);
document.getElementsByClassName("container")[0].appendChild(CanvasConversationList);
});
}
ui.UserLogin = () => {
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"><h1>用户登录或注册</h1></div>`;
let CanvasInputUsername = document.createElement("input");
CanvasInputUsername.className = "form-control";
CanvasInputUsername.placeholder = "在这里输入你的用户名";
let CanvasInputPasswd = document.createElement("input");
CanvasInputPasswd.className = "form-control";
CanvasInputPasswd.type = "password";
CanvasInputPasswd.placeholder = "在这里输入你的密码";
document.getElementsByClassName("container")[0].appendChild(CanvasInputUsername);
document.getElementsByClassName("container")[0].appendChild(CanvasInputPasswd);
let CanvasHint = document.createElement("p");
CanvasHint.innerHTML = "如果你点击使用此账户登录,将尝试登录已有账户<br />如果你点击使用此账户注册,将尝试以你所填写的信息注册新账户。";
document.getElementsByClassName("container")[0].appendChild(CanvasHint);
let CanvasLoginBtn = document.createElement("button");
CanvasLoginBtn.innerText = "使用此账户登录";
CanvasLoginBtn.className = "btn btn-primary";
CanvasLoginBtn.onclick = () => { userLogin(CanvasInputUsername.value, CanvasInputPasswd.value) };
document.getElementsByClassName("container")[0].appendChild(CanvasLoginBtn);
let CanvasRegBtn = document.createElement("button");
CanvasRegBtn.innerText = "使用此账户注册";
CanvasRegBtn.className = "btn btn-info";
document.getElementsByClassName("container")[0].appendChild(CanvasRegBtn);
CanvasRegBtn.onclick = () => { userReg(CanvasInputUsername.value, CanvasInputPasswd.value) }
let CanvasBackBtn = document.createElement("button");
CanvasBackBtn.className = "btn btn-success";
CanvasBackBtn.innerText = "返回帖子列表";
CanvasBackBtn.onclick = ui.conversationList;
document.getElementsByClassName("container")[0].appendChild(CanvasBackBtn);
}
let changeUserDescription = (description) => {
currentUser.set("description", description);
currentUser.save().then(() => {
window.location.reload();
});
}
ui.UserCenter = () => {
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"><h1>个人主页</h1></div>`;
let CanvasUsername = document.createElement("h4");
CanvasUsername.innerText = `这里是${currentUser.attributes.username}的个人主页`;
let CanvasUserDescriptionHint = document.createElement("p");
CanvasUserDescriptionHint.innerText = `个人简介:`;
let CanvasInputUserDescription = document.createElement("textarea");
CanvasInputUserDescription.placeholder = "在这里输入你的个人简介";
CanvasInputUserDescription.className = "form-control";
if (currentUser.attributes.description != undefined && currentUser.attributes.description != "") {
CanvasInputUserDescription.value = currentUser.attributes.description;
}
document.getElementsByClassName("container")[0].appendChild(CanvasUsername);
document.getElementsByClassName("container")[0].appendChild(CanvasUserDescriptionHint);
document.getElementsByClassName("container")[0].appendChild(CanvasInputUserDescription);
let CanvasSubmitBtn = document.createElement("button");
CanvasSubmitBtn.className = "btn btn-success";
CanvasSubmitBtn.innerText = "保存更改";
CanvasSubmitBtn.onclick = () => {
changeUserDescription(CanvasInputUserDescription.value);
};
document.getElementsByClassName("container")[0].appendChild(CanvasSubmitBtn);
let CanvasBackBtn = document.createElement("button");
CanvasBackBtn.className = "btn btn-light";
CanvasBackBtn.innerText = "返回首页";
CanvasBackBtn.onclick = ui.conversationList;
document.getElementsByClassName("container")[0].appendChild(CanvasBackBtn);
}
ui.viewUserProfile = (username) => {
document.getElementsByTagName("body")[0].innerHTML = `<br /><div class="container"><h1>${username}的个人主页</h1></div>`;
let CanvasUsername = document.createElement("h4");
CanvasUsername.innerText = `这里是${username}的个人主页`;
let CanvasUserDescriptionHint = document.createElement("p");
CanvasUserDescriptionHint.innerText = `个人简介:`;
document.getElementsByClassName("container")[0].appendChild(CanvasUsername);
document.getElementsByClassName("container")[0].appendChild(CanvasUserDescriptionHint);
let query = new AV.Query('_User');
query.equalTo('username', username);
query.find().then((data) => {
let CanvasUserDescription = document.createElement("p");
if (data[0].attributes.description != undefined && data[0].attributes.description != "") {
CanvasUserDescription.innerText = data[0].attributes.description;
} else {
CanvasUserDescription.innerText = "该用户未填写个人简介~";
}
document.getElementsByClassName("container")[0].appendChild(CanvasUserDescription);
let CanvasBackBtn = document.createElement("button");
CanvasBackBtn.className = "btn btn-light";
CanvasBackBtn.innerText = "返回首页";
CanvasBackBtn.onclick = ui.conversationList;
document.getElementsByClassName("container")[0].appendChild(CanvasBackBtn);
})
}
// 初始化用户界面
window.onload = () => {
ui.status = "initializing";
ui.conversationList();
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。