refactor(components): 重构多个组件并优化公共样式

重构了item-head、item-bottom、item-offer、item-summary和item-tenement组件,优化了props传递和数据处理逻辑
将公共头部和导航样式提取到public.css中,避免重复代码
修复了item-tenement组件中图片显示和数据处理的问题
更新了item-bottom组件的点赞和收藏逻辑,增加错误提示
优化了item-head组件的用户信息显示逻辑
调整了多个组件的样式细节,包括间距、图标大小等
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-10-30 19:09:38 +08:00
parent 28c890cf94
commit d4244fc783
38 changed files with 2092 additions and 4485 deletions

View File

@@ -11,14 +11,11 @@ import { like } from "../component/like/like.js";
const appSectionIndex = createApp({
setup() {
let signInAlreadyState = ref(false);
let permissions = ref([]);
onMounted(() => {
getUserInfoWin();
setTimeout(() => (permissions.value = window["permissions"] || []), 1000);
setTimeout(() => (permissions.value = window["permissions"] || ["comment.edit", "comment.delete", "offercollege.hide", "offersummary.hide", "mj.hide", "topic:manager", "topic:hide"]), 1000);
});
let isLogin = ref(true);
@@ -34,6 +31,8 @@ const appSectionIndex = createApp({
uin: 4238049,
});
let permissions = ref([]);
const getUserInfoWin = () => {
const checkUser = () => {
const user = window.userInfoWin;
@@ -42,6 +41,7 @@ const appSectionIndex = createApp({
realname.value = user.realname;
userInfoWin.value = user;
if (user?.uin > 0 || user?.uid > 0) isLogin.value = true;
permissions.value = user?.authority || [];
};
document.addEventListener("getUser", checkUser);
};
@@ -307,10 +307,11 @@ const appSectionIndex = createApp({
data.data.forEach((element, index) => {
element.timestamp = strtimeago(element.created_at, 4);
element["picture"] = [];
element["isReplyBoxShow"] = 0;
if (element.child.length > 0) {
element.child.forEach((el) => {
el["picture"] = [];
el.timestamp = strtimeago(element.created_at, 4);
el["isReplyBoxShow"] = 0;
});
@@ -328,9 +329,6 @@ const appSectionIndex = createApp({
commentList.value = commentList.value.concat(data.data);
commentTotalCount.value = data.count;
console.log("commentTotalCount.value", commentTotalCount.value);
commentPage.value = data.count > commentList.value.length ? commentPage.value + 1 : 0;
})
.finally(() => {
@@ -338,7 +336,7 @@ const appSectionIndex = createApp({
});
};
let picture = ref({});
let picture = ref([]);
const openUserInfo = (index, i) => {
if (i != undefined && commentList.value[index].child[i].user["uin"] > 0) commentList.value[index].child[i]["avatarState"] = true;
@@ -428,14 +426,497 @@ const appSectionIndex = createApp({
creationAlertBox("success", res.message || "操作成功");
// if (status) this.$parent.openLikeGif();
if (data["status"]) {
isLikeGif.value = true;
setTimeout(() => (isLikeGif.value = false), 2000);
}
});
};
let emojiState = ref(false);
let emojiMaskState = ref(false);
let inputTextarea = ref("");
// 打开 Emoji
const openEmoji = (index, i) => {
if (!isLogin.value) {
goLogin();
return;
}
if (i != undefined) commentList.value[index].child[i]["emojiState"] = true;
else if (index != undefined) commentList.value[index]["emojiState"] = true;
else {
closeEmoji();
closeAnswerCommentsChild();
emojiState.value = true;
}
emojiMaskState.value = true;
};
// 关闭 Emoji
const closeEmoji = (index, i) => {
commentList.value.forEach((ele) => {
ele["emojiState"] = false;
if (ele["child"] && ele["child"].length != 0) {
ele["child"].forEach((el) => {
el["emojiState"] = false;
});
}
});
emojiState.value = false;
emojiMaskState.value = false;
editEmojiState.value = false;
};
const TAHomePage = (uin) => goHomePage(uin);
const sendMessage = (uin) => goSendMessage(uin);
return { closeAnswerCommentsChild, openAnswerCommentsChild, dialogSrc, handleAnswerText, sendMessage, TAHomePage, operateAnswerCommentsLike, closeUserInfo, openUserInfo, permissions, commentList, commentPage, commentTotalCount, picture, userInfoWin, relatedList, relatedTime, coinNubmer, coinList, coinAmount, coinSubmit, strategy, mybalance, coinsState, openCoinBox, closeCoinBox, isLikeGif, likeClick, collectClick, islike, iscollect, recentlyList, medal, count, sectionn, tags, signInAlreadyState, authorInfo, info, timestamp, updatedTime };
let emojiData = ref(["😀", "😁", "😆", "😅", "😂", "😉", "😍", "🥰", "😘", "🤥", "😪", "😵‍💫", "🤓", "🥺", "😋", "😜", "🤪", "😎", "🤩", "🥳", "😔", "🙁", "😭", "😡", "😳", "🤗", "🤔", "🤭", "🤫", "😯", "😵", "🙄", "🥴", "🤢", "🤑", "🤠", "👌", "✌️", "🤟", "🤘", "🤙", "👍", "👎", "✊", "👏", "🤝", "🙏", "💪", "❎️", "✳️", "✴️", "❇️", "#️⃣", "*️⃣", "1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟", "🆗", "🈶", "🉐", "🉑", "🌹", "🥀", "🌸", "🌺", "🌷", "🌲", "☘️", "🍀", "🍁", "🌙", "⭐", "🌍", "☀️", "⭐️", "🌟", "☁️", "🌈", "☂️", "❄️", "☃️", "☄️", "🔥", "💧", "🍎", "🍐", "🍊", "🍉", "🍓", "🍑", "🍔", "🍟", "🍕", "🥪", "🍜", "🍡", "🍨", "🍦", "🎂", "🍰", "🍭", "🍿", "🍩", "🧃", "🍹", "🍒", "🥝", "🥒", "🥦", "🥨", "🌭", "🥘", "🍱", "🍢", "🥮", "🍩", "🍪", "🧁", "🍵", "🍶", "🍻", "🥂", "🧋", "🎉", "🎁", "🧧", "🎃", "🎄", "🧨", "✨️", "🎈", "🎊", "🎋", "🎍", "🎀", "🎖️", "🏆️", "🏅", "💌", "📬", "🚗", "🚕", "🚲", "🛵", "🚀", "🚁", "⛵", "🚢", "🔮", "🧸", "🀄️"]);
const handleEditFile = () => {
editEmojiState.value = false;
judgeLogin();
};
// 选择 Emoji
const selectEmoji = (key, index, i) => {
closeEmoji();
if (i != undefined) {
if (!commentList.value[index]["child"][i]["commentInput"]) commentList.value[index]["child"][i]["commentInput"] = "";
commentList.value[index]["child"][i]["commentInput"] += key;
} else if (index != undefined) {
if (!commentList.value[index]["commentInput"]) commentList.value[index]["commentInput"] = "";
commentList.value[index]["commentInput"] += key;
} else inputTextarea.value += key;
};
const judgeLogin = () => {
if (!isLogin.value) goLogin();
};
const maxPicture = 10;
const handleFileUpload = (event, index, i) => {
closeEmoji();
const file = event.target.files[0]; // 获取选择的文件
if (!file) return;
if (file.size > maxSize) {
creationAlertBox("error", "文件大小不能超过 20MB");
return;
}
let target = [];
if (editCommentState.value) target = editPicture.value;
else {
if (i != undefined) target = commentList.value[index].child[i]["picture"];
else if (index != undefined) target = commentList.value[index]["picture"];
else target = picture.value;
}
if (target.length >= maxPicture) {
creationAlertBox("error", `最多只能上传 ${maxPicture} 张图片`);
return;
}
console.log("现有图片", target);
const reader = new FileReader();
reader.onload = (e) => {
const base64 = e.target.result;
uploadImg(file).then((res) => {
const obj = {
aid: res.aid || "",
url: res.url || "",
};
target.push(obj);
if (editCommentState.value) editPicture.value = target;
else {
if (i != undefined) commentList.value[index].child[i]["picture"] = target;
else if (index != undefined) commentList.value[index]["picture"] = target;
else picture.value = target;
}
creationAlertBox("success", "上传成功");
});
};
reader.readAsDataURL(file);
};
let uploadConfig = null;
const maxSize = 20 * 1024 * 1024; // 20MB
// 上传图片 获取图片url
const uploadImg = (file) => {
return new Promise((resolve, reject) => {
const upload = () => {
let config = uploadConfig;
const formData = new FormData();
formData.append(config.requestName, file); // 文件数据
formData.append("name", file.name); // 文件名
formData.append("type", "image"); // 文件名
formData.append("data", config.params.data); // 文件名
ajax(config.url, formData).then((res) => {
if (res.code != 200) {
creationAlertBox("error", "上传失败");
return;
}
let data = res.data;
resolve(data);
});
};
if (uploadConfig) upload();
else getUploadConfig().then(() => upload());
});
};
const getUploadConfig = () => {
return new Promise((resolve, reject) => {
ajax("https://api.gter.net/v1/config/upload?type=comment").then((res) => {
let data = res.data;
uploadConfig = data;
resolve();
});
});
};
// 删除上传的图片
const closeFileUpload = (aid, index, i) => {
let target = [];
if (i != undefined) target = [...commentList.value[index].child[i]["picture"]];
else if (index != undefined) target = [...commentList.value[index]["picture"]];
else target = [...picture.value];
let sub = target.findIndex((item) => item.aid == aid);
if (sub != -1) target.splice(sub, 1);
if (i != undefined) commentList.value[index].child[i]["picture"] = target;
else if (index != undefined) commentList.value[index]["picture"] = target;
else picture.value = target;
};
const closePictureUpload = (index) => picture.value.splice(index, 1);
// 提交回答-评论
const submitAnswerComments = (index, i) => {
if (realname.value == 0 && userInfoWin.value?.uin > 0) {
openAttest();
return;
}
if (!isLogin.value) {
goLogin();
return;
}
let content = "";
let parentid = null;
// let token = this.token;
let image = [];
if (i != null) {
content = commentList.value[index]["child"][i]["commentInput"];
parentid = commentList.value[index]["child"][i]["id"];
image = [...commentList.value[index]["child"][i]["picture"]];
} else if (index != null) {
content = commentList.value[index]["commentInput"];
parentid = commentList.value[index]["id"];
image = [...commentList.value[index]["picture"]];
} else {
content = inputTextarea.value;
image = [...picture.value];
}
// this.detailLoading = true;
const attachments = {
images: image,
};
ajax("/v2/api/forum/postComment", {
content,
token,
attachments,
replyid: parentid,
})
.then((res) => {
if (res.code != 200) {
creationAlertBox("error", res.message || "操作成功");
return;
}
let data = res.data;
const timestamp = strtimeago(new Date());
if (i != null) {
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: {
nickname: commentList.value[index]["child"][i]["nickname"],
},
...data,
attachments,
picture: [],
timestamp,
};
commentList.value[index]["child"].push(targetData);
commentList.value[index]["childnum"]++;
} else if (index != null) {
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: [],
...data,
attachments,
picture: [],
timestamp,
};
commentList.value[index]["child"].unshift(targetData);
commentList.value[index]["childnum"]++;
} else {
let targetData = {
id: data["commentid"],
content,
isauthor: 1,
islike: 0,
likenum: 0,
...data,
child: [],
attachments,
picture: [],
timestamp,
};
commentList.value.unshift(targetData);
inputTextarea.value = "";
picture.value = [];
}
commentTotalCount.value = data.count || 0;
// if (!inputTextarea.value) {
// const textarea = this.$refs["input-textarea"]
// textarea.style.height = "80px"
// }
closeAnswerCommentsChild();
creationAlertBox("success", res.message || "操作成功");
})
.finally(() => {
// this.detailLoading = false;
});
};
let editCommentState = ref(false);
let editToken = ref("");
let editPicture = ref([]);
let editInput = ref("");
let editEmojiState = ref(false);
const openEdit = (token, index, i) => {
const list = JSON.parse(JSON.stringify(commentList.value));
let target = {};
if (i != null) target = list[index]["child"][i];
else target = list[index];
console.log("target", target);
editToken.value = target.token || "";
editInput.value = target.content || "";
editPicture.value = target.attachments?.images || [];
console.log("editCommentState", editPicture.value);
editCommentState.value = true;
};
const closeEdit = () => {
editPicture.value = {};
editToken.value = "";
editInput.value = "";
editCommentState.value = false;
};
// 打开 Emoji
const openEditEmoji = (index, i) => {
if (!isLogin.value) {
goLogin();
return;
}
editEmojiState.value = true;
};
const closeEditEmoji = () => {
editEmojiState.value = false;
};
const selectEditEmoji = (key) => {
closeEmoji();
editInput.value += key;
};
const postEditComment = () => {
if (!isLogin.value) {
goLogin();
return;
}
const image = editPicture.value;
const attachments = {
images: image,
};
ajax("/v2/api/forum/postCommentEdit", {
content: editInput.value,
token: editToken.value,
attachments,
}).then((res) => {
if (res.code != 200) {
creationAlertBox("error", res.message || "操作失败");
return;
}
commentList.value.forEach((element) => {
if (element.token == editToken.value) {
element["content"] = editInput.value;
element["attachments"] = attachments;
}
element.child &&
element.child.forEach((ele) => {
if (ele.token == editToken.value) {
ele["content"] = editInput.value;
ele["attachments"] = attachments;
}
});
});
editPicture.value = [];
editToken.value = "";
editCommentState.value = false;
editEmojiState.value = false;
creationAlertBox("success", res.message || "操作成功");
});
};
const closeEditFileUpload = (aid) => {
let target = [...editPicture.value];
let sub = target.findIndex((item) => item.aid == aid);
if (sub != -1) target.splice(sub, 1);
editPicture.value = target;
};
const handleInputPaste = (event, index, ii) => {
const items = event.clipboardData.items; // 获取粘贴的内容
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.startsWith("image/")) {
event.preventDefault();
const file = item.getAsFile(); // 获取文件
if (file.size > maxSize) {
creationAlertBox("error", "文件大小不能超过 20MB");
return;
}
let target = [];
if (editCommentState.value) target = editPicture.value;
else {
if (ii != undefined) target = commentList.value[index].child[ii]["picture"];
else if (index != undefined) target = commentList.value[index]["picture"];
else target = picture.value;
}
if (target.length >= maxPicture) {
creationAlertBox("error", `最多只能上传 ${maxPicture} 张图片`);
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const base64 = e.target.result;
uploadImg(file).then((res) => {
const obj = {
aid: res.aid || "",
url: res.url || "",
};
target.push(obj);
if (editCommentState.value) editPicture.value = target;
else {
if (ii != undefined) commentList.value[index].child[ii]["picture"] = target;
else if (index != undefined) commentList.value[index]["picture"] = target;
else picture.value = target;
}
creationAlertBox("success", "上传成功");
});
};
reader.readAsDataURL(file);
}
}
};
// 自动输入框增高
const autoResize = (e) => {
e.target.style.height = "auto"; // 重置高度
e.target.style.height = `${e.target.scrollHeight}px`; // 设置为内容高度
};
let commemtDelete = {};
// 点击删除
const commentDelete = (token, index, i) => {
const post = () => {
ajax("/v2/api/forum/deleteComment", {
token,
}).then((res) => {
if (res.code != 200) {
creationAlertBox("error", res.message);
return;
}
if (i >= 0) {
commentList.value[index].child.splice(i, 1);
commentList.value[index].childnum -= 1;
} else {
commentList.value.splice(index, 1);
}
commentTotalCount.value -= 1;
creationAlertBox("success", res.message || "操作成功");
});
};
const isConfirmed = confirm(`确定要删除讨论吗?`);
if (isConfirmed) post();
};
const openDiscuss = () => {
let dom = document.querySelector(".answer-discuss");
if (!dom) return;
const rect = dom.getBoundingClientRect();
const scrollPosition = window.pageYOffset + rect.top - 50;
window.scrollTo({
top: scrollPosition,
behavior: "smooth",
});
};
return { openDiscuss, commentDelete, handleInputPaste, autoResize, editCommentState, selectEditEmoji, closeEditEmoji, openEditEmoji, closeEdit, openEdit, closeEditFileUpload, postEditComment, submitAnswerComments, closePictureUpload, closeFileUpload, picture, editToken, editPicture, editInput, editEmojiState, handleFileUpload, inputTextarea, judgeLogin, handleEditFile, selectEmoji, emojiData, emojiMaskState, emojiState, closeEmoji, openEmoji, closeAnswerCommentsChild, openAnswerCommentsChild, dialogSrc, handleAnswerText, sendMessage, TAHomePage, operateAnswerCommentsLike, closeUserInfo, openUserInfo, permissions, commentList, commentPage, commentTotalCount, picture, userInfoWin, relatedList, relatedTime, coinNubmer, coinList, coinAmount, coinSubmit, strategy, mybalance, coinsState, openCoinBox, closeCoinBox, isLikeGif, likeClick, collectClick, islike, iscollect, recentlyList, medal, count, sectionn, tags, authorInfo, info, timestamp, updatedTime };
},
});