feat: 新增详情页和个人主页功能及组件优化
- 添加详情页(details.html)和个人主页(homepage-me.html)的完整功能实现 - 新增多个图片资源用于UI展示 - 优化item-head、item-bottom等组件的数据绑定和交互逻辑 - 添加公共工具函数(public.js)包括时间处理和网络请求 - 完善CSS样式文件,增加响应式布局和交互效果 - 实现用户信息展示、帖子详情、相关帖子推荐等功能模块 - 添加签到、投币等交互功能 - 优化组件模板结构和数据传递方式
This commit is contained in:
75
js/details.js
Normal file
75
js/details.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch } = Vue;
|
||||
import { itemForum } from "../component/item-forum/item-forum.js";
|
||||
import { itemOffer } from "../component/item-offer/item-offer.js";
|
||||
import { itemSummary } from "../component/item-summary/item-summary.js";
|
||||
import { itemVote } from "../component/item-vote/item-vote.js";
|
||||
import { itemMj } from "../component/item-mj/item-mj.js";
|
||||
import { itemTenement } from "../component/item-tenement/item-tenement.js";
|
||||
|
||||
const appSectionIndex = createApp({
|
||||
setup() {
|
||||
let signInAlreadyState = ref(false);
|
||||
|
||||
let authorInfo = ref({});
|
||||
let info = ref({});
|
||||
let ismyself = ref(false);
|
||||
let labelList = ref({
|
||||
sectionn: "",
|
||||
tags: [],
|
||||
});
|
||||
|
||||
let timestamp = ref("");
|
||||
let updatedTime = ref("");
|
||||
let token = "";
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
const init = () => {
|
||||
ajaxget(`https://api.gter.net/v2/api/forum/getTopicDetails?uniqid=${"9GPSfyaGDTz5"}`).then((res) => {
|
||||
console.log("res", res);
|
||||
const data = res.data;
|
||||
|
||||
console.log("data", data);
|
||||
|
||||
let targetInfo = data.info;
|
||||
|
||||
if (!targetInfo.hidden) targetInfo.hidden = 0;
|
||||
|
||||
// 替换换行
|
||||
targetInfo.content = targetInfo.content?.replace(/\n/g, "<br>") || "";
|
||||
|
||||
if (!targetInfo.content) {
|
||||
targetInfo.content = targetInfo.title;
|
||||
targetInfo.title = "";
|
||||
}
|
||||
|
||||
authorInfo.value = Array.isArray(data.authorInfo) ? null : data.authorInfo;
|
||||
ismyself.value = data.ismyself || false;
|
||||
labelList.value = {
|
||||
sectionn: targetInfo.sectionn,
|
||||
tags: targetInfo.tags,
|
||||
};
|
||||
|
||||
timestamp.value = strtimeago(targetInfo.release_at, 4);
|
||||
updatedTime.value = targetInfo.updated_at ? strtimeago(targetInfo.updated_at, 4) : null;
|
||||
info.value = targetInfo;
|
||||
|
||||
token = data.token;
|
||||
|
||||
// if (this.islogin) this.getTopicOperation();
|
||||
});
|
||||
};
|
||||
|
||||
return { signInAlreadyState, authorInfo, info, timestamp, updatedTime, labelList };
|
||||
},
|
||||
});
|
||||
appSectionIndex.component("itemForum", itemForum);
|
||||
appSectionIndex.component("itemOffer", itemOffer);
|
||||
appSectionIndex.component("itemSummary", itemSummary);
|
||||
appSectionIndex.component("itemVote", itemVote);
|
||||
appSectionIndex.component("itemMj", itemMj);
|
||||
appSectionIndex.component("itemTenement", itemTenement);
|
||||
|
||||
appSectionIndex.mount("#details");
|
||||
1483
js/homepage-me.js
Normal file
1483
js/homepage-me.js
Normal file
File diff suppressed because it is too large
Load Diff
150
js/public.js
Normal file
150
js/public.js
Normal file
@@ -0,0 +1,150 @@
|
||||
const forumBaseURL = "https://api.gter.net";
|
||||
axios.defaults.withCredentials = true;
|
||||
|
||||
// 导出ajax函数
|
||||
const ajax = (url) => {
|
||||
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
||||
return new Promise(function (resolve, reject) {
|
||||
axios
|
||||
.post(url, data, {
|
||||
emulateJSON: true,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then(function (res) {
|
||||
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
|
||||
|
||||
if (data.code == 401) {
|
||||
// 需要登录
|
||||
showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, {
|
||||
cover: true,
|
||||
});
|
||||
reject();
|
||||
}
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.response.status == 401)
|
||||
showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, {
|
||||
cover: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 导出ajaxget函数
|
||||
const ajaxget = (url) => {
|
||||
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
||||
return new Promise(function (resolve, reject) {
|
||||
axios
|
||||
.get(
|
||||
url,
|
||||
{},
|
||||
{
|
||||
emulateJSON: true,
|
||||
withCredentials: true,
|
||||
}
|
||||
)
|
||||
.then(function (res) {
|
||||
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
|
||||
if (data.code == 401) {
|
||||
// 需要登录
|
||||
showWindow("login", "https://passport.gter.net/login/ajax", "get", -1, {
|
||||
cover: true,
|
||||
});
|
||||
reject();
|
||||
}
|
||||
resolve(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const strtimeago = (dateStr, type = 1) => {
|
||||
dateStr = dateStr + ""; // 反之传入的不是字符串
|
||||
dateStr = dateStr.replaceAll("-", "/"); // 修改格式
|
||||
var minute = 1000 * 60; // 把分,时,天,周,半个月,一个月用毫秒表示
|
||||
var hour = minute * 60;
|
||||
var day = hour * 24;
|
||||
var now = new Date().getTime(); // 获取当前时间毫秒
|
||||
let objectTime = new Date(dateStr).getTime();
|
||||
var diffValue = now - objectTime; // 时间差
|
||||
if (diffValue < 0) return "刚刚";
|
||||
|
||||
var minC = diffValue / minute; // 计算时间差的分,时,天,周,月
|
||||
var hourC = diffValue / hour;
|
||||
var dayC = diffValue / day;
|
||||
|
||||
const diffInMilliseconds = now - objectTime;
|
||||
const diffInYears = diffInMilliseconds / (1000 * 60 * 60 * 24 * 365);
|
||||
const diffInMonths = diffInYears * 12;
|
||||
|
||||
let result = "";
|
||||
if (dayC >= 7) {
|
||||
var datetime = new Date(dateStr);
|
||||
var Nyear = datetime.getFullYear();
|
||||
var Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
|
||||
var Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
|
||||
var Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
|
||||
var Nmin = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
|
||||
if (type == 4) {
|
||||
if (new Date().getFullYear() !== Nyear) result = `${Nyear}年${Nmonth}月${Ndate}日`;
|
||||
else result = `${Nmonth}月${Ndate}日 ${Nhour}:${Nmin}`;
|
||||
}
|
||||
if (type == 1) result = Nyear + "-" + Nmonth + "-" + Ndate;
|
||||
if (type == 2) {
|
||||
result = `${Nmonth}月${Ndate}日 ${Nhour}:${Nmin}`;
|
||||
if (new Date().getFullYear() !== Nyear) result = `${Nyear}年${result}`;
|
||||
}
|
||||
if (type == 3) {
|
||||
if (diffInYears >= 1) result = Math.floor(diffInYears) + "年前";
|
||||
else if (diffInMonths >= 1) result = Math.floor(diffInMonths) + "个月前";
|
||||
else result = parseInt(dayC) + "天前";
|
||||
}
|
||||
} else if (dayC >= 1) result = parseInt(dayC) + "天前";
|
||||
else if (hourC >= 1 && hourC <= 24) result = parseInt(hourC) + "小时前";
|
||||
else if (minC >= 1 && minC <= 60) result = parseInt(minC) + "分钟前";
|
||||
else result = "刚刚";
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const timeago = (dateTimeStamp, type = 1) => {
|
||||
if (!dateTimeStamp) return "刚刚";
|
||||
|
||||
// 判断位数
|
||||
if (dateTimeStamp.toString().length !== 13) dateTimeStamp = dateTimeStamp * 1000;
|
||||
var minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示
|
||||
var hour = minute * 60;
|
||||
var day = hour * 24;
|
||||
var now = new Date().getTime(); //获取当前时间毫秒
|
||||
var diffValue = now - dateTimeStamp; //时间差
|
||||
if (diffValue < 0) return "刚刚";
|
||||
|
||||
var minC = diffValue / minute; //计算时间差的分,时,天,周,月
|
||||
var hourC = diffValue / hour;
|
||||
var dayC = diffValue / day;
|
||||
|
||||
let result = "";
|
||||
if (dayC >= 7) {
|
||||
var datetime = new Date(dateTimeStamp);
|
||||
var Nyear = datetime.getFullYear();
|
||||
var Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
|
||||
var Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
|
||||
var Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
|
||||
var Nmin = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
|
||||
|
||||
if (type == 1) result = Nyear + "-" + Nmonth + "-" + Ndate;
|
||||
if (type == 2) {
|
||||
result = `${Nmonth}月${Ndate}日 ${Nhour}:${Nmin}`;
|
||||
if (new Date().getFullYear() !== Nyear) result = `${Nyear}年${result}`;
|
||||
}
|
||||
} else if (dayC >= 1) result = parseInt(dayC) + "天前";
|
||||
else if (hourC >= 1 && hourC <= 24) result = parseInt(hourC) + "小时前";
|
||||
else if (minC >= 1 && minC <= 60) result = parseInt(minC) + "分钟前";
|
||||
else result = "刚刚";
|
||||
|
||||
return result;
|
||||
};
|
||||
119
js/section-index.js
Normal file
119
js/section-index.js
Normal file
@@ -0,0 +1,119 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch } = Vue;
|
||||
import { itemForum } from "../component/item-forum/item-forum.js";
|
||||
|
||||
const appSectionIndex = createApp({
|
||||
setup() {
|
||||
let signInAlreadyState = ref(false);
|
||||
onMounted(() => {
|
||||
getSectionList();
|
||||
|
||||
init();
|
||||
handpick();
|
||||
getTags();
|
||||
getList();
|
||||
});
|
||||
|
||||
let sectionList = ref([]);
|
||||
let section = ref("Lz9aimSLXeim");
|
||||
|
||||
const getSectionList = () => {
|
||||
ajaxget("/v2/api/forum/getSectionList").then((res) => {
|
||||
if (res.code != 200) return;
|
||||
const data = res.data || [];
|
||||
|
||||
let obj = {};
|
||||
|
||||
data.forEach((element) => (obj[element.cid] = element));
|
||||
|
||||
sectionList.value = insertLineBetweenCategories(data, "cid");
|
||||
});
|
||||
};
|
||||
|
||||
// 将版块按 cid 分格开
|
||||
const insertLineBetweenCategories = (arr) => {
|
||||
if (!arr.length) return [];
|
||||
|
||||
const sortedArr = [...arr].sort((a, b) => {
|
||||
if (a["cid"] < b["cid"]) return -1;
|
||||
if (a["cid"] > b["cid"]) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const result = [sortedArr[0]];
|
||||
let prevCategory = sortedArr[0]["cid"];
|
||||
|
||||
for (let i = 1; i < sortedArr.length; i++) {
|
||||
const current = sortedArr[i];
|
||||
const currentCategory = current["cid"];
|
||||
|
||||
if (currentCategory !== prevCategory) {
|
||||
result.push({
|
||||
key: "line",
|
||||
});
|
||||
prevCategory = currentCategory;
|
||||
}
|
||||
result.push(current);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
let info = ref({});
|
||||
|
||||
const init = () => {
|
||||
ajaxget(`/v2/api/forum/getSectionDetails?sectionid=${section.value}`).then((res) => {
|
||||
if (res.code != 200) return;
|
||||
const data = res.data || {};
|
||||
info.value = data;
|
||||
});
|
||||
};
|
||||
|
||||
let handpickList = ref([]);
|
||||
const handpick = () => {
|
||||
ajaxget(`/v2/api/forum/topicHandpicked?sectionid=${section.value}`).then((res) => {
|
||||
let data = res.data || [];
|
||||
handpickList.value = data;
|
||||
});
|
||||
};
|
||||
|
||||
let tagsList = ref([]);
|
||||
const getTags = () => {
|
||||
ajaxget(`/v2/api/forum/sectionTags?sectionid=${section.value}`).then((res) => {
|
||||
if (res.code != 200) return;
|
||||
const data = res.data || {};
|
||||
tagsList.value = data;
|
||||
});
|
||||
};
|
||||
|
||||
let loading = false;
|
||||
let page = ref(1);
|
||||
let count = ref(0);
|
||||
let list = ref([]);
|
||||
const getList = () => {
|
||||
if (loading || page.value == 0) return;
|
||||
loading = true;
|
||||
ajaxget(`/v2/api/forum/topicLists?type=thread&page=${page.value || 1}§ionid=${section.value}`)
|
||||
.then((res) => {
|
||||
if (res.code != 200) return;
|
||||
let data = res.data;
|
||||
list.value = list.value.concat(data.data);
|
||||
page.value = data.count > data.limit * data.page ? page.value + 1 : 0;
|
||||
count.value = data.count;
|
||||
loading = false;
|
||||
console.log(list.value[0]);
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
|
||||
err = err.data;
|
||||
if (err.code == 401) openLoginBtnState();
|
||||
loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
return { signInAlreadyState, sectionList, section, info, handpickList, tagsList, list };
|
||||
},
|
||||
});
|
||||
appSectionIndex.component("item-forum", itemForum);
|
||||
appSectionIndex.mount("#sectionIndex");
|
||||
@@ -1,12 +0,0 @@
|
||||
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch } = Vue;
|
||||
import { itemForum } from "../component/item-forum/item-forum.js";
|
||||
|
||||
const appSectionIndex = createApp({
|
||||
setup() {
|
||||
let signInAlreadyState = ref(false);
|
||||
|
||||
return { signInAlreadyState };
|
||||
},
|
||||
});
|
||||
appSectionIndex.component("item-forum", itemForum);
|
||||
appSectionIndex.mount("#sectionIndex");
|
||||
Reference in New Issue
Block a user