const forumBaseURL = "https://api.gter.net"; axios.defaults.withCredentials = true; axios.defaults.emulateJSON = true; const withVer = (p) => `${p}?v=${window.__ASSET_VERSION__}`; const getScriptParameter = (paramName) => { const currentScript = document.currentScript; if (currentScript && currentScript.src) { const url = new URL(currentScript.src, window.location.origin); return url.searchParams.get(paramName); } return null; }; // 判断是否已经创建了v参数 const vParam = getScriptParameter("v"); // 导出ajax函数 const ajax = (url, data) => { axios.defaults.withCredentials = true; axios.defaults.emulateJSON = true; url = url.indexOf("https://") > -1 ? url : forumBaseURL + url; if (data) data["v"] = vParam || "v2"; return new Promise(function (resolve, reject) { if (location.hostname == "127.0.0.1") axios.defaults.headers.common["Authorization"] = "n1pstcsmw6m6bcx49z705xhvduqviw29"; 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) { if (data) data["v"] = vParam || "v2"; 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; const paramSymbol = url.includes("?") ? "&" : "?"; url = `${url}${paramSymbol}v=${vParam || "v2"}`; return new Promise(function (resolve, reject) { if (location.hostname == "127.0.0.1") axios.defaults.headers.common["Authorization"] = "n1pstcsmw6m6bcx49z705xhvduqviw29"; 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) => { if (error?.status == 401) go_ajax_Login(); 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]; let finalPathname = ""; if (basePath.startsWith("/")) { finalPathname = basePath; } else { const oldPathSegments = window.location.pathname.split("/").filter(Boolean); const newPathSegments = oldPathSegments.slice(0, -1); // 移除原最后一段 if (basePath) { newPathSegments.push(basePath); // 添加新最后一段 } finalPathname = "/" + newPathSegments.join("/"); } // 拼接完整URL const newSearch = window.location.search; const newUrl = window.location.origin + finalPathname + newSearch; // 管理历史栈 + 修改URL 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 = () => { if (typeof ajax_login === "function") ajax_login(); else window.open("https://passport.gter.net/?referer=" + escape(location.href), "_self"); };