Files
PC-Light-Forum/js/public.js
DESKTOP-RQ919RC\Pc c9e229a5cd fix(bi): 添加投币数量必须大于0的校验
feat(item-bottom): 实现二维码弹窗自适应右侧边界
添加判断逻辑使二维码弹窗在靠近右侧边界时向左弹出

refactor(public.js): 优化ajax请求配置和登录跳转逻辑
统一设置axios默认配置,提取登录跳转函数

style(public.css): 调整QRcode-box.right的定位
修复二维码弹窗靠近右侧时的显示问题

fix(details.js): 修复粗体标记正则匹配多行内容
使用[\s\S]*?匹配可能的多行内容

refactor(index.js): 优化列表加载和滚动逻辑
移除模拟数据,添加加载状态,调整滚动加载阈值

chore: 更新html模板中的唯一标识和广告类名
2025-11-19 19:27:43 +08:00

403 lines
15 KiB
JavaScript
Raw 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 forumBaseURL = "https://api.gter.net";
axios.defaults.withCredentials = true;
axios.defaults.emulateJSON = true;
// 导出ajax函数
const ajax = (url, data) => {
axios.defaults.withCredentials = true;
axios.defaults.emulateJSON = true;
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) {
// 需要登录
go_ajax_Login();
reject();
}
resolve(data);
})
.catch((err) => {
reject();
if (err.response?.status == 401) go_ajax_Login();
});
});
};
const ajaxdelete = (url, data) => {
axios.defaults.withCredentials = true;
axios.defaults.emulateJSON = true;
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
return new Promise(function (resolve, reject) {
axios
.delete(url, {
emulateJSON: true,
withCredentials: true,
data,
})
.then(function (res) {
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
if (data.code == 401) {
// 需要登录
go_ajax_Login();
reject();
}
resolve(data);
})
.catch((err) => {
reject();
if (err.response?.status == 401) go_ajax_Login();
});
});
};
// 导出ajaxGet函数
const ajaxGet = (url) => {
axios.defaults.withCredentials = true;
axios.defaults.emulateJSON = true;
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) {
// 需要登录
go_ajax_Login();
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;
};
const managerHide = (token, state, type = "offer") => {
return new Promise((resolve, reject) => {
const obj = {
offer: "Offer",
offer_summary: "总结",
interviewexperience: "面经",
thread: "帖子",
question: "帖子",
vote: "投票",
};
const isConfirmed = confirm(`确定要${state == 0 ? "隐藏" : "显示"}${obj[type]}吗?`);
if (isConfirmed) {
ajax(`/v2/api/forum/setTopicHide`, {
token,
hidden: Number(state !== 1),
}).then((res) => {
const data = res.data;
creationAlertBox("success", res.message || "");
resolve(data.hidden);
});
}
});
};
// 推荐
const managerRecommend = (token, state) => {
return new Promise((resolve, reject) => {
const post = () => {
ajax(`/v2/api/forum/setTopicRecommend`, {
token,
recommend: state == 1 ? 0 : 1,
}).then((res) => {
const data = res.data;
creationAlertBox("success", res.message || "");
resolve(data.recommend);
});
};
if (state == 1) {
const isConfirmed = confirm(`确定要取消推荐吗?`);
if (isConfirmed) post();
else resolve(state);
} else post();
});
};
// 精华
const managerEssence = (token, state) => {
return new Promise((resolve, reject) => {
const post = () => {
ajax(`/v2/api/forum/setTopicBest`, {
token,
best: state == 1 ? 0 : 1,
}).then((res) => {
const data = res.data;
creationAlertBox("success", res.message || "");
resolve(data.best);
});
};
if (state == 1) {
const isConfirmed = confirm(`确定要取消精华吗?`);
if (isConfirmed) post();
else resolve(state);
} else post();
});
};
// 删除
const managerDelete = (token) => {
return new Promise((resolve, reject) => {
const post = () => {
ajaxdelete(`/v2/api/forum/deleteTopic`, {
token,
}).then((res) => {
creationAlertBox("success", res.message || "");
resolve();
});
};
const isConfirmed = confirm(`确定要删除吗?`);
if (!isConfirmed) reject();
else post();
});
};
const getUrlParams = () => {
const params = {};
const queryString = window.location.search.slice(1);
if (queryString) {
queryString.split("&").forEach((pair) => {
const [key, value] = pair.split("=");
params[decodeURIComponent(key)] = decodeURIComponent(value || "");
});
}
return params;
};
const updateUrlParams = (params, replace = false) => {
// 解析当前URL
const url = new URL(window.location.href);
const searchParams = url.searchParams;
// 遍历参数对象更新URL参数
Object.entries(params).forEach(([key, value]) => {
if (value === null || value === undefined) {
// 删除参数
searchParams.delete(key);
} else {
// 添加或修改参数
searchParams.set(key, value);
}
});
// 生成新的URL保留协议、域名、路径等只修改参数
const newUrl = url.origin + url.pathname + (searchParams.toString() ? `?${searchParams.toString()}` : "");
// 修改URL不刷新页面
if (replace) {
history.replaceState(null, "", newUrl);
} else {
history.pushState(null, "", newUrl);
}
};
// 跳转 url
const redirectToExternalWebsite = (url, target = "_blank") => {
const link = document.createElement("a");
link.href = url;
link.target = target;
link.click();
};
// 点击ta的主页
const goHomePage = (token) => {
if (!token) return;
redirectToExternalWebsite(`/u/${token}`);
};
// 点击发送信息
const goSendMessage = (token) => {
if (typeof messagePrivateItem == "function") {
messagePrivateItem({ token });
return;
}
goHomePage(token);
};
const lang = {
money: { 1: "3000以下", 2: "3000-4000", 3: "4000-5000", 4: "5000-6500", 5: "6500-8000", 6: "8000-10000", 7: "10000-20000", 8: "20000-30000", 9: "30000-40000", 10: "40000-50000", 11: "50000以上" },
leaseterm: { 1: "长租", 2: "短租" },
intermediary: { 1: "中介", 2: "非中介", 3: "房东", 4: "有房招室友", 5: "其他", 6: "求房源" },
property: { 1: "唐楼", 2: "洋楼", 3: "酒店式公寓", 4: "村屋", 5: "其他", 6: "学生公寓", 7: "house", 8: "屋苑", 9: "酒店" },
elevator: { 1: "有电梯", 2: "无电梯", "-1": "不限" },
sunshinearea: { 1: "阳台", 2: "天台", "-1": "无" },
floor: { 1: "低层", 2: "中层", 3: "高层", 4: "地下", 5: "不要一楼", 6: "不要顶层" },
tenementtype: { 1: "合租", 2: "整租", 1.5: "独卫套房", 1.1: "房间", 1.2: "床位", 1.3: "客厅", 1.4: "其他", 2.1: "studio", 2.2: "一房", 2.3: "两房", 2.4: "三房", 2.5: "四房以上" },
gender: { 1: "女性", 2: "男性", 3: "男女皆可" },
location: { 1: "港岛", 2: "九龙", 3: "新界", 1.1: "上环/中环/金钟", 1.2: "湾仔/铜锣湾", 1.3: "天后/炮台山", 1.4: "北角/则鱼涌", 1.5: "太古/西湾河", 1.6: "筲箕湾/柴湾", 1.7: "西营盘/坚尼地城/石塘咀", 1.8: "薄扶林", 1.9: "赤柱/香港仔", 1.11: "半山/山顶", 1.12: "南区", 2.1: "九龙站/奥运/南昌", 2.2: "尖沙咀/佐敦", 2.3: "长沙湾/深水埗/荔枝角", 2.4: "美孚/荔景", 2.5: "红磡/黄埔", 2.6: "土瓜湾/何文田", 2.7: "九龙城/启德", 2.8: "石夹尾/九龙塘", 2.9: "乐富/黄大仙", 2.11: "钻石山/彩虹", 2.12: "牛头角/九龙湾/观塘", 2.13: "蓝田/油塘", 2.14: "调景岭", 2.15: "油麻地/旺角/太子", 3.1: "葵芳/葵兴", 3.2: "荃湾", 3.3: "将军澳/坑口/宝琳", 3.4: "大埔仔/西贡", 3.5: "康城", 3.6: "大围/沙田", 3.7: "马鞍山", 3.8: "大埔/火炭/太和", 3.9: "粉岭/上水", 3.11: "赤泥坪/大埔尾/樟树滩", 3.12: "元朗/天水围/屯门", 3.13: "青衣", 3.14: "东涌/马湾/愉景湾", 3.15: "长洲" },
apartmentschool: [
{ id: 1, name: "港大", sid: 309 },
{ id: 2, name: "城大", sid: 311 },
{ id: 3, name: "理工", sid: 312 },
{ id: 4, name: "浸会", sid: 313 },
{ id: 5, name: "中大", sid: 308 },
{ id: 6, name: "教大", sid: 453 },
{ id: 7, name: "科大", sid: 310 },
{ id: 8, name: "岭大", sid: 314 },
{ id: 9, name: "都大", sid: 315 },
],
rentalduration: { 1: "1个月", 2: "2个月", 3: "3个月", 4: "4个月", 5: "5个月", 6: "6个月", 7: "7个月", 8: "8个月", 9: "9个月", 10: "10个月", 11: "11个月", 12: "1年", 13: "1年1个月", 14: "1年2个月", 15: "1年3个月", 16: "1年4个月", 17: "1年5个月", 18: "1年6个月", 24: "2年", 36: "3年" },
};
let copyForumUid = (text) => {
if (navigator.clipboard)
copyForumUid = () => {
navigator.clipboard.writeText(text);
creationAlertBox("success", "复制成功");
};
else {
copyForumUid = () => {
var tempInput = document.createElement("input");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
creationAlertBox("success", "复制成功");
};
}
copyForumUid();
};
const updateUrlLastPath = (newLastPath, isReplace = false) => {
const raw = typeof newLastPath === "string" ? newLastPath : String(newLastPath);
const basePath = raw.split("?")[0];
const newPathname = basePath.startsWith("/") ? basePath : "/" + basePath;
const newSearch = window.location.search;
const newUrl = window.location.origin + newPathname + newSearch;
if (isReplace) history.replaceState(null, document.title, newUrl);
else history.pushState(null, document.title, newUrl);
};
const removeQueryQ = (isReplace = false) => {
const params = new URLSearchParams(window.location.search);
if (!params.has("q")) return;
params.delete("q");
const qs = params.toString();
const newUrl = window.location.origin + window.location.pathname + (qs ? "?" + qs : "") + window.location.hash;
if (isReplace) history.replaceState(null, document.title, newUrl);
else history.pushState(null, document.title, newUrl);
};
// 跳转登录
const go_ajax_Login = () => {
console.log("go_ajax_Login");
if (typeof ajax_login === "function") ajax_login();
else window.open("https://passport.gter.net/?referer=" + escape(location.href), "_self");
};