feat: 添加新图片资源及更新组件样式与功能

style: 调整CSS样式及优化布局
refactor: 重构组件逻辑及API调用
fix: 修复路径引用及图片加载问题
docs: 更新注释及文档内容
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-11-05 19:10:43 +08:00
parent 07f4401f67
commit 3365e5ee0a
43 changed files with 782 additions and 365 deletions

View File

@@ -42,8 +42,10 @@ export const headTop = defineComponent({
redirectToExternalWebsite("/search/" + searchText);
};
return { state, signIn, input, defaultSearchText, goSearch };
let pitchState = ref(false);
return { pitchState, state, signIn, input, defaultSearchText, goSearch };
},
template: `<div class="head-top flexacenter"> <a href="/" class="flexacenter" target="_blank"> <img class="logo" src="https://oss.gter.net/logo" alt="" /> </a> <div class="flex1"></div> <div class="input-box flexacenter"> <input class="input flex1" type="text" :placeholder="'大家都在搜:' + defaultSearchText" @keyup.enter="goSearch" v-model="input" /> <img class="icon" src="/img/search-icon.svg" @click="goSearch" /> </div> <div class="sign-in sign-in-no flexacenter" v-if="state == 0" @click="signIn()" v-cloak> <img class="sign-in-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-in-bj.svg" /> <img class="coin-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/coin-bj.svg" /> <img class="coin-icon" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/coin-icon.png" /> <span class="text flex1">签到领寄托币</span> <div class="sign-go flexcenter"> <img class="sign-go-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-go.svg" /> GO </div> <img class="petal1" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal1.png" /> <img class="petal2" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal2.png" /> <img class="petal3" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal3.png" /> </div> <div class="sign-in sign-in-already flexcenter" v-else> <img class="sign-icon" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-icon.png" /> <span>已签到,明天再来</span> </div></div>`,
template: `<div class="head-top flexacenter"> <a href="/" class="flexacenter" target="_blank"> <img class="logo" src="https://oss.gter.net/logo" alt="" /> </a> <div class="flex1"></div> <div class="input-box flexacenter" :class="{'pitch': pitchState}"> <input class="input flex1" type="text" :placeholder="'大家都在搜:' + defaultSearchText" @keyup.enter="goSearch" v-model="input" @focus="pitchState = true" @blur="pitchState = false" /> <img class="icon" src="/img/search-icon.svg" @click="goSearch" /> </div> <div class="sign-in sign-in-no flexacenter" v-if="state == 0" @click="signIn()" v-cloak> <img class="sign-in-bj" src="/img/sign-in-bj.svg" /> <img class="coin-bj" src="/img/coin-bj.svg" /> <img class="coin-icon" src="/img/coin-icon.png" /> <span class="text flex1">签到领寄托币</span> <div class="sign-go flexcenter"> <img class="sign-go-bj" src="/img/sign-go.svg" /> GO </div> <img class="petal1" src="/img/petal1.png" /> <img class="petal2" src="/img/petal2.png" /> <img class="petal3" src="/img/petal3.png" /> </div> <div class="sign-in sign-in-already flexcenter" v-else> <img class="sign-icon" src="/img/sign-icon.png" /> <span>已签到,明天再来</span> </div></div>`,
});

View File

@@ -3,26 +3,26 @@
<img class="logo" src="https://oss.gter.net/logo" alt="" />
</a>
<div class="flex1"></div>
<div class="input-box flexacenter">
<input class="input flex1" type="text" :placeholder="'大家都在搜:' + defaultSearchText" @keyup.enter="goSearch" v-model="input" />
<div class="input-box flexacenter" :class="{'pitch': pitchState}">
<input class="input flex1" type="text" :placeholder="'大家都在搜:' + defaultSearchText" @keyup.enter="goSearch" v-model="input" @focus="pitchState = true" @blur="pitchState = false" />
<img class="icon" src="/img/search-icon.svg" @click="goSearch" />
</div>
<div class="sign-in sign-in-no flexacenter" v-if="state == 0" @click="signIn()" v-cloak>
<img class="sign-in-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-in-bj.svg" />
<img class="coin-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/coin-bj.svg" />
<img class="coin-icon" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/coin-icon.png" />
<img class="sign-in-bj" src="/img/sign-in-bj.svg" />
<img class="coin-bj" src="/img/coin-bj.svg" />
<img class="coin-icon" src="/img/coin-icon.png" />
<span class="text flex1">签到领寄托币</span>
<div class="sign-go flexcenter">
<img class="sign-go-bj" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-go.svg" />
<img class="sign-go-bj" src="/img/sign-go.svg" />
GO
</div>
<img class="petal1" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal1.png" />
<img class="petal2" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal2.png" />
<img class="petal3" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/petal3.png" />
<img class="petal1" src="/img/petal1.png" />
<img class="petal2" src="/img/petal2.png" />
<img class="petal3" src="/img/petal3.png" />
</div>
<div class="sign-in sign-in-already flexcenter" v-else>
<img class="sign-icon" src="//framework.x-php.com/gter/image/gter/forum/assets/forum/sign-icon.png" />
<img class="sign-icon" src="/img/sign-icon.png" />
<span>已签到,明天再来</span>
</div>
</div>

View File

@@ -25,5 +25,5 @@ export const hotTag = defineComponent({
components: {},
template: `<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag-title"> <img class="icon" src="./img/triangle-orange.svg" /> 热门标签 </div> <div class="list flexflex"> <a class="item" v-for="item in list" :href="'/tag/' + item.tagname" target="_blank">{{ item.tagname }}</a> </div></div>`,
template: `<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag-title"> <img class="icon" src="/img/triangle-orange.svg" /> 热门标签 </div> <div class="list flexflex"> <a class="item" v-for="item in list" :href="'/tag/' + item.tagname" target="_blank">{{ item.tagname }}</a> </div></div>`,
});

View File

@@ -1,6 +1,6 @@
<div class="hot-tag" v-if="list.length > 0">
<div class="hot-tag-title">
<img class="icon" src="./img/triangle-orange.svg" />
<img class="icon" src="/img/triangle-orange.svg" />
热门标签
</div>
<div class="list flexflex">

View File

@@ -78,7 +78,7 @@ export const itemBottom = defineComponent({
const token = item.value.token || "";
ajax(`https://api.gter.net/v2/api/forum/postTopicCollect`, {
ajax(`/v2/api/forum/postTopicCollect`, {
token,
})
.then((res) => {

View File

@@ -12,6 +12,10 @@ export const itemForum = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
@@ -29,5 +33,5 @@ export const itemForum = defineComponent({
itemHead,
},
template: `<div class="item-box item-forum"> <item-head :itemdata="item"></item-head> <a v-if="item.title" class="title" :href="'/details/' + item.uniqid" target="_blank">{{ item.title }}</a> <a class="message two-line-display" :href="'/details/' + item.uniqid" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-forum"> <item-head :itemdata="item" :page="page"></item-head> <a v-if="item.title" class="title" :href="'/details/' + item.uniqid" target="_blank">{{ item.title }}</a> <a class="message two-line-display" :href="'/details/' + item.uniqid" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,8 +1,8 @@
<div class="item-box item-forum">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<a v-if="item.title" class="title" :href="'/details/' + item.uniqid" target="_blank">{{ item.title }}</a>
<a class="message two-line-display" :href="'/details/' + item.uniqid" target="_blank">{{ item.content }}</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -1,6 +1,6 @@
// my-component.js
// 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window
const { defineComponent, ref, provide, onMounted } = Vue;
const { defineComponent, ref, provide, onMounted, inject } = Vue;
import { report } from "../report/report.js";
// 定义组件(直接使用模板)
@@ -11,6 +11,11 @@ export const itemHead = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
@@ -89,20 +94,24 @@ export const itemHead = defineComponent({
});
};
// let cancelOperate = inject("cancelOperate");
// let handleDelete = inject("handleDelete");
let itemHead = ref(null);
// 删除
const deleteItem = () => {
const target = item.value;
console.log("deleteItem");
console.log("deleteItem", target, target.token);
managerDelete(target.token)
.then(() => {
const targetNode = itemHead.value;
if (!targetNode) return;
// managerDelete(target.token)
// .then(() => {
// cancelOperate("like", token);
// })
// .finally(() => {
// cutShow();
// });
const parentItemBox = targetNode.parentElement;
if (parentItemBox?.classList.contains("item-box")) parentItemBox.style.display = "none";
})
.finally(() => {
cutShow();
});
};
// 编辑
@@ -116,12 +125,44 @@ export const itemHead = defineComponent({
redirectToExternalWebsite(`/space?uin=${uin}&uid=${uid}`);
};
return { edit, deleteItem, goPersonalHomepage, reportState, cutShow, show, item, timestamp, sectionn, tags, ismanager, report, hide, recommend, essence };
const openedit = (type) => {
let url = ``;
if (type == "offer") url = `https://offer.gter.net/post/modify?id=${item.value.token}`;
else if (type == "offer_summary") url = `https://offer.gter.net/post/summary`;
redirectToExternalWebsite(url);
};
const anonymousState = ref(false);
const cutAnonymous = () => {
anonymousState.value = !anonymousState.value;
};
const cutAnonymousState = (state) => {
console.log("state", state);
const target = item.value;
ajax("/v2/api/forum/postTopicAnonymousStatus", {
token: target.token,
anonymous: state,
})
.then((res) => {
console.log("res", res);
if (res.code != 200) return;
const data = res.data || {};
target.anonymous = data.anonymous || 0;
item.value = target;
creationAlertBox("success", res.message || "操作成功");
})
.finally(() => {
cutAnonymous();
});
};
return { itemHead, cutAnonymousState, cutAnonymous, anonymousState, openedit, edit, deleteItem, goPersonalHomepage, reportState, cutShow, show, item, timestamp, sectionn, tags, ismanager, report, hide, recommend, essence };
},
components: {
report,
},
template: `<div class="item-head flexacenter"> <div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uin, item?.user?.uid)"> <img class="avatar" :src="item?.user?.avatar || item.avatar" /> <div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div> <img class="group" v-if="info?.group?.image" :src="info?.group?.image" /> </div> <div class="time">{{ timestamp }}</div> <div class="flex1"></div> <div class="view flexacenter"> <img class="icon" src="/img/eye-icon.svg" /> <div class="text">{{ item.views }}</div> </div> <div v-if="item.type != 'tenement'" class="btn flexcenter" @click.stop="cutShow"> <img class="icon" src="/img/dot-dot-dot-gray.png" /> </div> <div v-if="show"> <div class="mask" @click.stop="cutShow"></div> <div class="operate"> <div class="item" @click.stop="report">举报</div> <template v-if="ismanager"> <div class="item" @click.stop="hide">{{ item.hidden == 0 ? "隐藏" : "显示" }}</div> <div class="item" @click.stop="recommend">{{ item.recommend == 1 ? "取消" : "" }}推荐</div> <div class="item" @click.stop="essence">{{ item.best == 1 ? "取消" : "" }}精华</div> </template> <template v-if="item.type == 'thread' && item.ismyself"> <div class="item" @click.stop="edit">编辑</div> <div class="item" @click.stop="deleteItem">删除</div> </template> </div> </div></div><div class="label flexflex" v-if="sectionn?.length || tags?.length || item.recommend == 1 || item.best == 1"> <img class="item icon" v-if="item.recommend == 1 && item.best != 1" src="/img/recommend-icon.png" /> <img class="item icon" v-if="item.best == 1" src="/img/essence-icon.png" /> <a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a> <a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a></div><report v-if="reportState" :itemdata="item"></report>`,
template: `<div class="item-head flexacenter" ref="itemHead"> <div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uin, item?.user?.uid)"> <img class="avatar" :src="item?.user?.avatar || item.avatar" /> <div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div> <img class="group" v-if="info?.group?.image" :src="info?.group?.image" /> </div> <div class="time">{{ timestamp }}</div> <div class="flex1"></div> <div class="circlePen flexcenter" @click="openedit(item.type)" v-if="page == 'edit' && (item.type == 'offer' || item.type == 'offer_summary')"> <img class="icon" src="/img/pen-icon.png" /> </div> <div class="flexacenter" style="position: relative;"> <div class="anonymous-box flexcenter" @click.stop="cutAnonymous" v-if="page == 'edit' && (item.type == 'vote' || item.type == 'interviewexperience')"> <span v-if="item.anonymous == 0">公开</span> <span v-else>匿名</span> </div> <!-- 是否 公开发表 --> <template v-if="anonymousState"> <div class="mask" @click.stop="cutAnonymous"></div> <div class="isPublicityBox"> <div class="isPublicity-item" :class="{'green': item.anonymous == 0}" @click.stop="cutAnonymousState(0)">公开发表 <img v-if="item.anonymous == 0" class="isPublicityIcon" src="/img/u1829.svg"></image> </div> <div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表 <img v-if="item.anonymous != 0" class="isPublicityIcon" src="/img/u1829.svg"></image> </div> </div> </template> </div> <div class="view flexacenter"> <img class="icon" src="/img/eye-icon.svg" /> <div class="text">{{ item.views }}</div> </div> <div v-if="item.type != 'tenement'" class="btn flexcenter" @click.stop="cutShow"> <img class="icon" src="/img/dot-dot-dot-gray.png" /> </div> <div v-if="show"> <div class="mask" @click.stop="cutShow"></div> <div class="operate"> <div class="item" @click.stop="report">举报</div> <template v-if="ismanager"> <div class="item" @click.stop="hide">{{ item.hidden == 0 ? "隐藏" : "显示" }}</div> <div class="item" @click.stop="recommend">{{ item.recommend == 1 ? "取消" : "" }}推荐</div> <div class="item" @click.stop="essence">{{ item.best == 1 ? "取消" : "" }}精华</div> </template> <template v-if="item.type == 'thread' && item.ismyself"> <div class="item" @click.stop="edit">编辑</div> <div class="item" @click.stop="deleteItem">删除</div> </template> <div class="item" v-if="page == 'edit' && item.type == 'vote'" @click.stop="deleteItem">删除</div> </div> </div></div><div class="label flexflex" v-if="sectionn?.length || tags?.length || item.recommend == 1 || item.best == 1"> <img class="item icon" v-if="item.recommend == 1 && item.best != 1" src="/img/recommend-icon.png" /> <img class="item icon" v-if="item.best == 1" src="/img/essence-icon.png" /> <a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a> <a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a></div><report v-if="reportState" :itemdata="item"></report>`,
});

View File

@@ -1,4 +1,4 @@
<div class="item-head flexacenter">
<div class="item-head flexacenter" ref="itemHead">
<div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uin, item?.user?.uid)">
<img class="avatar" :src="item?.user?.avatar || item.avatar" />
<div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div>
@@ -8,6 +8,31 @@
<div class="time">{{ timestamp }}</div>
<div class="flex1"></div>
<div class="circlePen flexcenter" @click="openedit(item.type)" v-if="page == 'edit' && (item.type == 'offer' || item.type == 'offer_summary')">
<img class="icon" src="/img/pen-icon.png" />
</div>
<div class="flexacenter" style="position: relative;">
<div class="anonymous-box flexcenter" @click.stop="cutAnonymous" v-if="page == 'edit' && (item.type == 'vote' || item.type == 'interviewexperience')">
<span v-if="item.anonymous == 0">公开</span>
<span v-else>匿名</span>
</div>
<!-- 是否 公开发表 -->
<template v-if="anonymousState">
<div class="mask" @click.stop="cutAnonymous"></div>
<div class="isPublicityBox">
<div class="isPublicity-item" :class="{'green': item.anonymous == 0}" @click.stop="cutAnonymousState(0)">公开发表
<img v-if="item.anonymous == 0" class="isPublicityIcon" src="/img/u1829.svg"></image>
</div>
<div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表
<img v-if="item.anonymous != 0" class="isPublicityIcon" src="/img/u1829.svg"></image>
</div>
</div>
</template>
</div>
<div class="view flexacenter">
<img class="icon" src="/img/eye-icon.svg" />
<div class="text">{{ item.views }}</div>
@@ -31,6 +56,7 @@
<div class="item" @click.stop="edit">编辑</div>
<div class="item" @click.stop="deleteItem">删除</div>
</template>
<div class="item" v-if="page == 'edit' && item.type == 'vote'" @click.stop="deleteItem">删除</div>
</div>
</div>
</div>

View File

@@ -12,6 +12,10 @@ export const itemMj = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
@@ -25,5 +29,5 @@ export const itemMj = defineComponent({
itemHead,
},
template: `<div class="item-box item-mj"> <item-head :itemdata="item"></item-head> <a class="school flexacenter" :href="item.url" target="_blank"> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> </a> <a class="major flexacenter" v-if="item.data.professional" :href="item.url" target="_blank"> <div class="key">{{ item.data.project ? '专业' : '项目/专业' }}</div> <div class="value flex1 one-line-display">{{ item.data.professional }}</div> </a> <a class="major flexacenter" v-if="item.data.project" :href="item.url" target="_blank"> <div class="key">项目</div> <div class="value flex1 one-line-display">{{ item.data.project }}</div> </a> <a class="major flexacenter" v-if="item.data.interviewtime" :href="item.url" target="_blank"> <div class="key">面试</div> <div class="value time flex1 one-line-display">{{ item.data.interviewtime }}</div> </a> <a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-mj"> <item-head :itemdata="item" :page="page"></item-head> <a class="school flexacenter" :href="item.url" target="_blank"> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> </a> <a class="major flexacenter" v-if="item.data.professional" :href="item.url" target="_blank"> <div class="key">{{ item.data.project ? '专业' : '项目/专业' }}</div> <div class="value flex1 one-line-display">{{ item.data.professional }}</div> </a> <a class="major flexacenter" v-if="item.data.project" :href="item.url" target="_blank"> <div class="key">项目</div> <div class="value flex1 one-line-display">{{ item.data.project }}</div> </a> <a class="major flexacenter" v-if="item.data.interviewtime" :href="item.url" target="_blank"> <div class="key">面试</div> <div class="value time flex1 one-line-display">{{ item.data.interviewtime }}</div> </a> <a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,5 +1,5 @@
<div class="item-box item-mj">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<a class="school flexacenter" :href="item.url" target="_blank">
<img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image>
<div class="text flex1 one-line-display">{{ item.data.schoolname }}</div>
@@ -22,5 +22,5 @@
<a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -12,64 +12,16 @@ export const itemOffer = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
let item = ref({ ...props.itemdata });
item.value["url"] = "/details/" + item.value.uniqid;
// let isLogin = ref(true);
// let realname = ref(1); // 是否已经实名
// let userInfoWin = ref({
// authority: ["comment.edit", "comment.delete", "offercollege.hide", "offersummary.hide", "mj.hide", "topic:manager", "topic:hide"],
// avatar: "https://nas.gter.net:9008/avatar/97K4EWIMLrsbGTWXslC2WFVSEKWOikN42jDKLNjtax7HL4xtfMOJSdU9oWFhY2E~/middle?random=1761733169",
// groupid: 3,
// nickname: "肖荣豪",
// realname: 1,
// token: "01346a38444d71aaadb3adad52b52c39",
// uid: 500144,
// uin: 4238049,
// });
// let permissions = ref([]);
// const getUserInfoWin = () => {
// const checkUser = () => {
// const user = window.userInfoWin;
// if (!user) return;
// document.removeEventListener("getUser", checkUser);
// realname.value = user.realname;
// userInfoWin.value = user;
// if (user?.uin > 0 || user?.uid > 0) isLogin.value = true;
// };
// document.addEventListener("getUser", checkUser);
// };
// const openAttest = () => {
// const handleAttestClose = () => {
// document.removeEventListener("closeAttest", handleAttestClose);
// realname.value = window.userInfoWin?.realname || 0;
// };
// // 启动认证流程时添加监听
// document.addEventListener("closeAttest", handleAttestClose);
// loadAttest(2);
// };
// // 跳转登录
// const goLogin = () => {
// if (typeof window === "undefined") return;
// if (window["userInfoWin"] && Object.keys(window["userInfoWin"]).length !== 0) {
// if (window["userInfoWin"]["uid"]) isLogin.value = true;
// else ajax_login();
// } else ajax_login();
// };
// provide("isLogin", isLogin);
// provide("userInfoWin", userInfoWin);
// provide("realname", realname);
// provide("openAttest", openAttest);
// provide("goLogin", goLogin);
return { item };
},
@@ -78,5 +30,5 @@ export const itemOffer = defineComponent({
itemHead,
},
template: `<div class="item-box item-offer"> <item-head :itemdata="item"></item-head> <a class="school flexacenter" :href="item.url" target="_blank"> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> </a> <a class="major flexacenter" v-if="item.data.professional" :href="item.url" target="_blank"> <div class="key">{{ item.data.project ? '专业' : '项目/专业' }}</div> <div class="value flex1 one-line-display">{{ item.data.professional }}</div> </a> <a class="major flexacenter" v-if="item.data.project" :href="item.url" target="_blank"> <div class="key">项目</div> <div class="value flex1 one-line-display">{{ item.data.project }}</div> </a> <a class="info flexacenter" :href="item.url" target="_blank"> {{ item.data.semester }} <div class="line"></div> {{ item.data.degree }} <div class="line"></div> <div class="results" :class="['r' + item.data.apply_results]">{{ item.data.apply_results_text }}</div> </a> <a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-offer"> <item-head :itemdata="item" :page="page"></item-head> <a class="school flexacenter" :href="item.url" target="_blank"> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> </a> <a class="major flexacenter" v-if="item.data.professional" :href="item.url" target="_blank"> <div class="key">{{ item.data.project ? '专业' : '项目/专业' }}</div> <div class="value flex1 one-line-display">{{ item.data.professional }}</div> </a> <a class="major flexacenter" v-if="item.data.project" :href="item.url" target="_blank"> <div class="key">项目</div> <div class="value flex1 one-line-display">{{ item.data.project }}</div> </a> <a class="info flexacenter" :href="item.url" target="_blank"> {{ item.data.semester }} <div class="line"></div> {{ item.data.degree }} <div class="line"></div> <div class="results" :class="['r' + item.data.apply_results]">{{ item.data.apply_results_text }}</div> </a> <a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,5 +1,5 @@
<div class="item-box item-offer">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<a class="school flexacenter" :href="item.url" target="_blank">
<img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image>
<div class="text flex1 one-line-display">{{ item.data.schoolname }}</div>
@@ -24,5 +24,5 @@
</a>
<a class="message" v-if="item.content" :href="item.url" target="_blank">{{ item.content }}</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -12,6 +12,10 @@ export const itemSummary = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
@@ -26,5 +30,5 @@ export const itemSummary = defineComponent({
itemHead,
},
template: `<div class="item-box item-summary"> <item-head :itemdata="item"></item-head> <a class="title" v-if="item.title" :href="item.url" target="_blank">{{ item.title }}</a> <a class="message one-line-display" :href="item.url" target="_blank" v-if="item.content">{{ item.content }}</a> <a class="total flexacenter" :href="item.url" target="_blank"> <div>共</div> <div class="num">{{ item.data.offercount }}</div> <div>个Offer</div> </a> <a class="list flexacenter" :href="item.url" target="_blank"> <div class="item flexflex" v-for="(it,i) in item.data.offerlist" :key="i"> <div class="item-content flexflex"> <div class="school flexacenter"> <img class="icon" v-if="it.schoollogo" :src="it.schoollogo" mode="heightFix"></image> <div class="name one-line-display flex1">{{ it.schoolname }}</div> </div> <div class="major one-line-display" v-if="it.professional">{{ it.professional }}</div> <div class="info flexacenter"> {{ it.semester || '25Fall' }} <div class="line"></div> {{ it.degree || 'MSc' }} <div class="line"></div> <div class="results" :class="['r' + it.apply_results]">{{ it.apply_results_text || 'Offer' }}</div> </div> </div> </div> <div v-if="item.data.offercount > 3" class="item more flexcenter"> <div class="item-content flexcenter"> <div class="">查看更多</div> <img class="icon" src="/img/arrows-circle-dark-blue.svg" mode="heightFix"></image> </div> </div> </a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-summary"> <item-head :itemdata="item" :page="page"></item-head> <a class="title" v-if="item.title" :href="item.url" target="_blank">{{ item.title }}</a> <a class="message one-line-display" :href="item.url" target="_blank" v-if="item.content">{{ item.content }}</a> <a class="total flexacenter" :href="item.url" target="_blank"> <div>共</div> <div class="num">{{ item.data.offercount }}</div> <div>个Offer</div> </a> <a class="list flexacenter" :href="item.url" target="_blank"> <div class="item flexflex" v-for="(it,i) in item.data.offerlist" :key="i"> <div class="item-content flexflex"> <div class="school flexacenter"> <img class="icon" v-if="it.schoollogo" :src="it.schoollogo" mode="heightFix"></image> <div class="name one-line-display flex1">{{ it.schoolname }}</div> </div> <div class="major one-line-display" v-if="it.professional">{{ it.professional }}</div> <div class="info flexacenter"> {{ it.semester || '25Fall' }} <div class="line"></div> {{ it.degree || 'MSc' }} <div class="line"></div> <div class="results" :class="['r' + it.apply_results]">{{ it.apply_results_text || 'Offer' }}</div> </div> </div> </div> <div v-if="item.data.offercount > 3" class="item more flexcenter"> <div class="item-content flexcenter"> <div class="">查看更多</div> <img class="icon" src="/img/arrows-circle-dark-blue.svg" mode="heightFix"></image> </div> </div> </a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,5 +1,5 @@
<div class="item-box item-summary">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<a class="title" v-if="item.title" :href="item.url" target="_blank">{{ item.title }}</a>
<a class="message one-line-display" :href="item.url" target="_blank" v-if="item.content">{{ item.content }}</a>
<a class="total flexacenter" :href="item.url" target="_blank">
@@ -32,5 +32,5 @@
</div>
</div>
</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -12,6 +12,10 @@ export const itemTenement = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
@@ -84,5 +88,5 @@ export const itemTenement = defineComponent({
itemHead,
},
template: `<div class="item-box item-tenement"> <item-head :itemdata="item"></item-head> <div class="label flexflex" v-if="sectionn?.length || tags?.length"> <img class="item icon" v-if="item.isintermediary == 1" style="width: 94px; cursor: auto;" src="/img/intermediary-icon.png" /> <img class="item icon" v-if="item.verified == 1" style="width: 94px; cursor: auto;" src="/img/attestation-icon.png" /> <div class="item blue" v-for="(item, index) in sectionn" :key="item" style="cursor: auto;">{{ item }}</div> <div class="item" v-for="(item, index) in tags" :key="item" style="cursor: auto;">{{ item }}</div> </div> <a class="title" :href="item.url" target="_blank">{{ item.subject }}</a> <a class="site-box flexacenter" :href="item.url" target="_blank"> <template v-if="item.intermediary == 6"> <div class="site-item flexacenter" v-for="(item, index) in item.location" :key="index"> <img class="site-icon" src="/img/orientation.png"> {{ item }} </div> </template> <div v-else class="site-item flexacenter"> <img class="site-icon" src="/img/orientation.png"> {{ item.location || '' }} </div> </a> <a class="price-section flexacenter" :href="item.url" target="_blank"> <div class="unit">HK$</div> <div class="price">{{ item.rent }}</div> <span class="text">/月</span> <div class="rentalduration">[ 租期{{ item.rentalduration }} ]</div> </a> <a class="picture flexacenter" :href="item.url" target="_blank" v-if="item.images?.length != 0"> <img class="picture-item" v-for="(item, index) in item.images" :key="index" :src="item" alt=""> </a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-tenement"> <item-head :itemdata="item" :page="page"></item-head> <div class="label flexflex" v-if="sectionn?.length || tags?.length"> <img class="item icon" v-if="item.isintermediary == 1" style="width: 94px; cursor: auto;" src="/img/intermediary-icon.png" /> <img class="item icon" v-if="item.verified == 1" style="width: 94px; cursor: auto;" src="/img/attestation-icon.png" /> <div class="item blue" v-for="(item, index) in sectionn" :key="item" style="cursor: auto;">{{ item }}</div> <div class="item" v-for="(item, index) in tags" :key="item" style="cursor: auto;">{{ item }}</div> </div> <a class="title" :href="item.url" target="_blank">{{ item.subject }}</a> <a class="site-box flexacenter" :href="item.url" target="_blank"> <template v-if="item.intermediary == 6"> <div class="site-item flexacenter" v-for="(item, index) in item.location" :key="index"> <img class="site-icon" src="/img/orientation.png"> {{ item }} </div> </template> <div v-else class="site-item flexacenter"> <img class="site-icon" src="/img/orientation.png"> {{ item.location || '' }} </div> </a> <a class="price-section flexacenter" :href="item.url" target="_blank"> <div class="unit">HK$</div> <div class="price">{{ item.rent }}</div> <span class="text">/月</span> <div class="rentalduration">[ 租期{{ item.rentalduration }} ]</div> </a> <a class="picture flexacenter" :href="item.url" target="_blank" v-if="item.images?.length != 0"> <img class="picture-item" v-for="(item, index) in item.images" :key="index" :src="item" alt=""> </a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,5 +1,5 @@
<div class="item-box item-tenement">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<div class="label flexflex" v-if="sectionn?.length || tags?.length">
<img class="item icon" v-if="item.isintermediary == 1" style="width: 94px; cursor: auto;" src="/img/intermediary-icon.png" />
<img class="item icon" v-if="item.verified == 1" style="width: 94px; cursor: auto;" src="/img/attestation-icon.png" />
@@ -33,5 +33,5 @@
<img class="picture-item" v-for="(item, index) in item.images" :key="index" :src="item" alt="">
</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -12,11 +12,62 @@ export const itemVote = defineComponent({
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
// 处理 截止时间
const handleDeadline = (dateTimeStamp = "") => {
if (typeof dateTimeStamp == "number") dateTimeStamp = dateTimeStamp ? dateTimeStamp * 1000 : null;
if (typeof dateTimeStamp == "string" && dateTimeStamp.match(/^\d{4}-\d{2}-\d{2}$/)) dateTimeStamp += " 23:59:59";
const timestamp = new Date(dateTimeStamp.replace(/-/g, "/")).getTime();
const now = Date.now();
const diffValue = timestamp - now;
if (diffValue < 0) return null;
const units = [
{
value: 24 * 60 * 60 * 1000,
unit: "天",
},
{
value: 60 * 60 * 1000,
unit: "小时",
},
{
value: 60 * 1000,
unit: "分钟",
},
{
value: 1000,
unit: "秒",
},
];
for (const { value, unit } of units) {
if (diffValue >= value) {
return {
num: Math.round(diffValue / value),
unit,
};
}
}
return {
num: 0,
unit: "秒",
};
};
let item = ref({ ...props.itemdata });
item.value['url'] = 'https://vote.gter.net/details/' + item.value.uniqid;
item.value["time"] = handleDeadline(item.value.data.deadline);
item.value["url"] = "/details/" + item.value.uniqid;
const option = item.value.data.option || [];
item.value["isvote"] = option.some((item) => item.selected == 1);
return { item };
},
@@ -25,5 +76,5 @@ export const itemVote = defineComponent({
itemHead,
},
template: `<div class="item-box item-vote"> <item-head :itemdata="item"></item-head> <a class="title" :href="item.url" target="_blank">{{ item.title }}</a> <a class="message one-line-display" v-if="item.content">{{ item.content }}</a> <a class="info flexacenter" target="_blank" :href="item.url"> <template v-if="item?.data.status == 1"> <div class="status">进行中</div> <div class="line"></div> <div class="num">{{ item?.time.num }}</div>{{ item.time.unit }}后结束 </template> <div v-else class="status end">已结束</div> <div class="line"></div> <div class="num">{{ item?.data?.votes }}</div>人参与 </a> <a class="list" :class="{ 'voted': !item.time || item.isvote }" target="_blank" :href="item.url"> <div class="list-item flexcenter " v-for="(item, index) in item?.data?.option" :key="index"> <div class="list-top flexacenter"> <img v-if="item.selected" class="list-tick" src="/img/vote-tick.svg"> <div v-else class="list-serial flexcenter">{{ index + 1 }}</div> <div class="list-text one-line-display flex1">{{ item.value }}</div> </div> <div class="list-bottom flexacenter"> <div class="list-length" :style="{ width: item.percentage + '%' }"></div>{{ item.count }} </div> </div> </a> <item-bottom :itemdata="item"></item-bottom></div>`,
template: `<div class="item-box item-vote"> <item-head :itemdata="item" :page="page"></item-head> <a class="title" :href="item.url" target="_blank">{{ item.title }}</a> <a class="message one-line-display" v-if="item.content">{{ item.content }}</a> <a class="info flexacenter" target="_blank" :href="item.url"> <template v-if="item?.data.status == 1"> <div class="status">进行中</div> <div class="line"></div> <div class="num">{{ item?.time.num }}</div>{{ item.time.unit }}后结束 </template> <div v-else class="status end">已结束</div> <div class="line"></div> <div class="num">{{ item?.data?.votes }}</div>人参与 </a> <a class="list" :class="{ 'voted': !item.time || item.isvote }" target="_blank" :href="item.url"> <div class="list-item flexcenter " v-for="(item, index) in item?.data?.option" :key="index"> <div class="list-top flexacenter"> <img v-if="item.selected" class="list-tick" src="/img/vote-tick.svg"> <div v-else class="list-serial flexcenter">{{ index + 1 }}</div> <div class="list-text one-line-display flex1">{{ item.value }}</div> </div> <div class="list-bottom flexacenter"> <div class="list-length" :style="{ width: item.percentage + '%' }"></div>{{ item.count }} </div> </div> </a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
});

View File

@@ -1,5 +1,5 @@
<div class="item-box item-vote">
<item-head :itemdata="item"></item-head>
<item-head :itemdata="item" :page="page"></item-head>
<a class="title" :href="item.url" target="_blank">{{ item.title }}</a>
<a class="message one-line-display" v-if="item.content">{{ item.content }}</a>
<a class="info flexacenter" target="_blank" :href="item.url">
@@ -25,5 +25,5 @@
</div>
</div>
</a>
<item-bottom :itemdata="item"></item-bottom>
<item-bottom :itemdata="item" :page="page"></item-bottom>
</div>

View File

@@ -113,5 +113,5 @@ export const latestList = defineComponent({
itemHead,
},
template: `<div class="posts-box box-newest " :class="['boxtype-' + boxtype]"> <div v-if="boxtype == 'newest'" class="box-newest-head flexacenter"> <img class="icon" src="/img/newest-icon.png" alt="" /> 最新 </div> <div v-else-if="boxtype == 'essence'" class="box-newest-head flexacenter"> <img class="icon" src="/img/essence.png" alt="" /> 精华阅读 </div> <div v-else class="slideshow-box"> <div class="tab-list flexacenter"> <div class="tab-item newest" :class="{'pitch': postsTab == 'newest'}" @click="tabPostsItem('newest')">最新</div> <div class="tab-item essence" :class="{'pitch': postsTab == 'essence'}" @click="tabPostsItem('essence')">精华</div> </div> </div> <div class="slideshow-content flexflex"> <!-- newest 最新 --> <div class="newest-side-box side-box"> <img class="bounding" src="/img/bounding-circle-green.svg" alt="" /> <div class="box"> <a v-for="(item, index) in latestList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank"> <div class="dot dot-green"></div> <div class="text one-line-display">{{ item.title }}</div> </a> </div> </div> <!-- essence 精选 --> <div class="essence-side-box side-box"> <img class="bounding" src="/img/bounding-circle-blue.svg" alt="" /> <div class="box"> <a v-for="(item, index) in topList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank"> <div class="dot"></div> <div class="text one-line-display">{{ item.title }}</div> </a> </div> </div> </div></div>`,
template: `<div class="posts-box box-newest " :class="['boxtype-' + boxtype]"> <div v-if="boxtype == 'newest'" class="box-newest-head flexacenter"> <img class="icon" src="/img/newest-icon.png" alt="" /> 最新 </div> <div v-else-if="boxtype == 'essence'" class="box-newest-head flexacenter"> <img class="icon" src="/img/essence.png" alt="" /> 精华阅读 </div> <div v-else class="slideshow-box"> <div class="tab-list flexacenter"> <div class="tab-item newest" :class="{'pitch': postsTab == 'newest'}" @click="tabPostsItem('newest')">最新</div> <div class="tab-item essence" :class="{'pitch': postsTab == 'essence'}" @click="tabPostsItem('essence')">精华</div> </div> </div> <div class="slideshow-content flexflex"> <!-- newest 最新 --> <div class="newest-side-box side-box"> <img class="bounding" src="/img/bounding-circle-green.svg" alt="" /> <div class="box"> <a v-for="(item, index) in latestList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank"> <div class="dot dot-green"></div> <div class="text one-line-display">{{ item.title || item.content }}</div> </a> </div> </div> <!-- essence 精选 --> <div class="essence-side-box side-box"> <img class="bounding" src="/img/bounding-circle-blue.svg" alt="" /> <div class="box"> <a v-for="(item, index) in topList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank"> <div class="dot"></div> <div class="text one-line-display">{{ item.title || item.content }}</div> </a> </div> </div> </div></div>`,
});

View File

@@ -20,7 +20,7 @@
<div class="box">
<a v-for="(item, index) in latestList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank">
<div class="dot dot-green"></div>
<div class="text one-line-display">{{ item.title }}</div>
<div class="text one-line-display">{{ item.title || item.content }}</div>
</a>
</div>
</div>
@@ -31,7 +31,7 @@
<div class="box">
<a v-for="(item, index) in topList" :key="index" class="item flexacenter vuehide" :href="'/details/' + item.uniqid" target="_blank">
<div class="dot"></div>
<div class="text one-line-display">{{ item.title }}</div>
<div class="text one-line-display">{{ item.title || item.content }}</div>
</a>
</div>
</div>

View File

@@ -0,0 +1,19 @@
// my-component.js
// 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window
const { defineComponent, ref, onMounted, onUnmounted } = Vue;
// 定义组件(直接使用模板)
export const loadBox = defineComponent({
name: "load-box",
props: {
loading: {
type: String,
default: "",
},
},
setup(props) {
return { };
},
template: `<div class="list-load-box flexcenter" :class="{'show': loading}"><img class="list-load-icon" src="/img/load-icon.svg" /><div class="list-load-text">加载中</div></div>`,
});

View File

@@ -209,6 +209,7 @@
border-radius: 10px;
padding-left: 95px;
padding-right: 40px;
padding-bottom: 50px;
}
#homepage-other .matter .matter-content .list-area .classify {
padding-top: 39px;
@@ -254,7 +255,6 @@
border: 1px solid #e9eef2;
border-radius: 10px;
flex-direction: column;
margin-bottom: 50px;
}
#homepage-other .matter .matter-content .list-area .empty .empty-icon {
width: 80px;

View File

@@ -243,6 +243,7 @@
border-radius: 10px;
padding-left: 95px;
padding-right: 40px;
padding-bottom: 50px;
.classify {
padding-top: 39px;
@@ -296,7 +297,7 @@
border: 1px solid rgba(233, 238, 242, 1);
border-radius: 10px;
flex-direction: column;
margin-bottom: 50px;
// margin-bottom: 50px;
.empty-icon {
width: 80px;

View File

@@ -15,7 +15,10 @@
#appIndex .header-content-box .header-content-left .adv-list .adv-item:not(:last-child) {
margin-right: 12px;
}
#appIndex .header-content-box .header-content-left .adv-list .adv-item .adv-img {
#appIndex .header-content-box .header-content-left .adv-list .adv-item a {
display: block;
}
#appIndex .header-content-box .header-content-left .adv-list .adv-item img {
width: 468px;
height: 60px;
border-radius: 10px;
@@ -283,13 +286,16 @@
height: 16px;
margin-right: 6px;
}
#appIndex .header-content-box .header-content-right .adv-broadside {
#appIndex .header-content-box .header-content-right .adv {
width: 240px;
height: 140px;
margin-bottom: 10px;
display: block;
}
#appIndex .header-content-box .header-content-right .adv-broadside .adv-broadside-img {
#appIndex .header-content-box .header-content-right .adv a {
display: block;
}
#appIndex .header-content-box .header-content-right .adv img {
width: 240px;
height: 140px;
border-radius: 10px;

View File

@@ -18,7 +18,10 @@
&:not(:last-child) {
margin-right: 12px;
}
.adv-img {
a {
display: block;
}
img {
width: 468px;
height: 60px;
border-radius: 10px;
@@ -340,12 +343,15 @@
}
}
.adv-broadside {
.adv {
width: 240px;
height: 140px;
margin-bottom: 10px;
display: block;
.adv-broadside-img {
a {
display: block;
}
img {
width: 240px;
height: 140px;
border-radius: 10px;

View File

@@ -86,6 +86,59 @@ body {
font-size: 13px;
color: #aaaaaa;
}
.item-box .item-head .anonymous-box {
background-color: #f2f2f2;
border-radius: 30px;
font-size: 14px;
color: #333;
height: 28px;
padding: 0 10px;
cursor: pointer;
margin-right: 15px;
}
.item-box .item-head .circlePen {
border-radius: 50%;
background-color: #f2f2f2;
margin-right: 10px;
width: 28px;
height: 28px;
cursor: pointer;
}
.item-box .item-head .circlePen .icon {
width: 20px;
height: 20px;
}
.item-box .item-head .isPublicityBox {
width: 120px;
background-color: #fff;
position: absolute;
top: 34px;
left: 0;
border-radius: 8px;
box-shadow: 0px 0px 9px rgba(0, 0, 0, 0.2);
z-index: 89;
}
.item-box .item-head .isPublicityBox .isPublicity-item {
height: 40px;
line-height: 40px;
text-align: center;
padding: 0 10px;
color: #555555;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
.item-box .item-head .isPublicityBox .isPublicity-item:first-child {
border-bottom: 1px dotted #e3e3e3;
}
.item-box .item-head .isPublicityBox .isPublicity-item.green {
color: #26d79f;
}
.item-box .item-head .isPublicityBox .isPublicity-item .isPublicityIcon {
width: 12px;
}
.item-box .item-head .view {
font-size: 12px;
color: #aaaaaa;
@@ -856,7 +909,7 @@ body {
.side-box .box {
width: 272px;
background-color: #ffffff;
border-radius: 8px;
border-radius: 0;
}
.side-box.thread-side-box .box .item {
padding-top: 16px;
@@ -1021,7 +1074,7 @@ body {
margin-right: 10px;
}
.side-box.newest-side-box .box .item .dot.dot-green {
background-image: url(https://app.gter.net/image/gter/forum/assets/forum/dot-green.svg);
background-image: url(/img/dot-green.svg);
background-repeat: no-repeat;
}
.side-box.newest-side-box .box .item .text {
@@ -1056,7 +1109,7 @@ body {
width: 6px;
height: 6px;
margin-right: 10px;
background-image: url(https://app.gter.net/image/gter/forum/assets/forum/dot-blue.svg);
background-image: url(/img/dot-blue.svg);
background-repeat: no-repeat;
}
.side-box.essence-side-box .box .item .text {
@@ -1382,6 +1435,10 @@ body {
padding: 0 15px;
justify-content: space-between;
margin-right: 20px;
transition: all 0.3s;
}
.head-top .input-box.pitch {
border-color: #000;
}
.head-top .input-box .input {
border: none;
@@ -1392,7 +1449,7 @@ body {
.head-top .input-box .icon {
width: 18px;
height: 18px;
margin-left: 15rpx;
margin-left: 15px;
cursor: pointer;
}
.head-top .sign-in {
@@ -1593,3 +1650,44 @@ td {
.templateValue {
display: none;
}
.list-load-box {
width: 100%;
height: 0;
background-color: #ffffff;
border: 0 solid #e9eef2;
border-radius: 10px;
flex-direction: column;
transition: all 0.3s ease-in-out;
overflow: hidden;
}
.list-load-box.show {
height: 100px;
border-width: 1px;
}
.list-load-box.show .list-load-icon {
width: 30px;
height: 30px;
}
.list-load-box.show .list-load-text {
font-size: 14px;
}
.list-load-box .list-load-icon {
width: 0;
height: 0;
animation: loadingRotate 1s linear infinite;
transition: all 0.3s ease-in-out;
}
.list-load-box .list-load-text {
color: #999999;
font-size: 0;
margin-top: 6px;
transition: all 0.3s ease-in-out;
}
@keyframes loadingRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@@ -102,6 +102,67 @@ body {
color: #aaaaaa;
}
.anonymous-box {
background-color: #f2f2f2;
border-radius: 30px;
font-size: 14px;
color: #333;
height: 28px;
padding: 0 10px;
cursor: pointer;
margin-right: 15px;
}
.circlePen {
border-radius: 50%;
background-color: #f2f2f2;
margin-right: 10px;
width: 28px;
height: 28px;
cursor: pointer;
.icon {
width: 20px;
height: 20px;
}
}
.isPublicityBox {
width: 120px;
background-color: #fff;
position: absolute;
top: 34px;
left: 0;
border-radius: 8px;
box-shadow: 0px 0px 9px rgba(0, 0, 0, 0.2);
z-index: 89;
.isPublicity-item {
height: 40px;
line-height: 40px;
text-align: center;
padding: 0 10px;
color: #555555;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
&:first-child {
border-bottom: 1px dotted #e3e3e3;
}
&.green {
color: #26d79f;
}
.isPublicityIcon {
width: 12px;
}
}
}
.view {
font-size: 12px;
color: #aaaaaa;
@@ -1021,7 +1082,7 @@ body {
.side-box .box {
width: 272px;
background-color: #ffffff;
border-radius: 8px;
border-radius: 0;
}
.side-box.thread-side-box .box .item {
@@ -1220,7 +1281,7 @@ body {
}
.side-box.newest-side-box .box .item .dot.dot-green {
background-image: url(https://app.gter.net/image/gter/forum/assets/forum/dot-green.svg);
background-image: url(/img/dot-green.svg);
background-repeat: no-repeat;
}
@@ -1263,7 +1324,7 @@ body {
width: 6px;
height: 6px;
margin-right: 10px;
background-image: url(https://app.gter.net/image/gter/forum/assets/forum/dot-blue.svg);
background-image: url(/img/dot-blue.svg);
background-repeat: no-repeat;
}
@@ -1650,6 +1711,11 @@ body {
padding: 0 15px;
justify-content: space-between;
margin-right: 20px;
transition: all 0.3s;
&.pitch {
border-color: #000;
}
.input {
border: none;
@@ -1661,7 +1727,7 @@ body {
.icon {
width: 18px;
height: 18px;
margin-left: 15rpx;
margin-left: 15px;
cursor: pointer;
}
}
@@ -1882,7 +1948,6 @@ td {
height: 8px;
}
.t_r {
-moz-border-radius: 0 8px 0 0;
-webkit-border-radius: 0 8px 0 0;
@@ -1892,3 +1957,52 @@ td {
.templateValue {
display: none;
}
.list-load-box {
width: 100%;
height: 0;
background-color: #ffffff;
border: 0 solid #e9eef2;
border-radius: 10px;
flex-direction: column;
transition: all 0.3s ease-in-out;
overflow: hidden;
&.show {
height: 100px;
border-width: 1px;
.list-load-icon {
width: 30px;
height: 30px;
}
.list-load-text {
font-size: 14px;
}
}
.list-load-icon {
width: 0;
height: 0;
animation: loadingRotate 1s linear infinite;
transition: all 0.3s ease-in-out;
}
.list-load-text {
color: #999999;
font-size: 0;
margin-top: 6px;
transition: all 0.3s ease-in-out;
}
}
@keyframes loadingRotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

11
img/coin-bj.svg Normal file

File diff suppressed because one or more lines are too long

BIN
img/coin-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

13
img/dot-blue.svg Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="6px" height="6px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="15" y1="71.06" x2="15" y2="77" id="LinearGradient670">
<stop id="Stop671" stop-color="#ccddf7" offset="0" />
<stop id="Stop672" stop-color="#3889ff" offset="1" />
</linearGradient>
</defs>
<g transform="matrix(1 0 0 1 -12 -71 )">
<path d="M 15 71 C 16.68 71 18 72.32 18 74 C 18 75.68 16.68 77 15 77 C 13.32 77 12 75.68 12 74 C 12 72.32 13.32 71 15 71 Z " fill-rule="nonzero" fill="url(#LinearGradient670)" stroke="none" />
<path d="M 15 71.5 C 16.4 71.5 17.5 72.6 17.5 74 C 17.5 75.4 16.4 76.5 15 76.5 C 13.6 76.5 12.5 75.4 12.5 74 C 12.5 72.6 13.6 71.5 15 71.5 Z " stroke-width="1" stroke="#797979" fill="none" />
</g>
</svg>

13
img/dot-green.svg Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="6px" height="6px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="1597" y1="6772.06" x2="1597" y2="6778" id="LinearGradient682">
<stop id="Stop683" stop-color="#d3f2d9" offset="0" />
<stop id="Stop684" stop-color="#72db86" offset="1" />
</linearGradient>
</defs>
<g transform="matrix(1 0 0 1 -1594 -6772 )">
<path d="M 1597 6772 C 1598.68 6772 1600 6773.32 1600 6775 C 1600 6776.68 1598.68 6778 1597 6778 C 1595.32 6778 1594 6776.68 1594 6775 C 1594 6773.32 1595.32 6772 1597 6772 Z " fill-rule="nonzero" fill="url(#LinearGradient682)" stroke="none" />
<path d="M 1597 6772.5 C 1598.4 6772.5 1599.5 6773.6 1599.5 6775 C 1599.5 6776.4 1598.4 6777.5 1597 6777.5 C 1595.6 6777.5 1594.5 6776.4 1594.5 6775 C 1594.5 6773.6 1595.6 6772.5 1597 6772.5 Z " stroke-width="1" stroke="#797979" fill="none" />
</g>
</svg>

1
img/load-icon.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1762325523447" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6416" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M896 463m-128 0a128 128 0 1 0 256 0 128 128 0 1 0-256 0Z" p-id="6417" fill="#999999"></path><path d="M432 96m-96 0a96 96 0 1 0 192 0 96 96 0 1 0-192 0Z" p-id="6418" fill="#999999"></path><path d="M80 512m-80 0a80 80 0 1 0 160 0 80 80 0 1 0-160 0Z" p-id="6419" fill="#999999"></path><path d="M352 832c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64zM853.8 885.8c-28.1 28.1-65 42.2-101.8 42.2s-73.7-14.1-101.8-42.2c-56.2-56.2-56.2-147.4 0-203.6 28.1-28.1 65-42.2 101.8-42.2s73.7 14.1 101.8 42.2c56.3 56.2 56.3 147.4 0 203.6zM829.9 258.4c-22.2 22.2-51.4 33.4-80.5 33.4-29.2 0-58.3-11.1-80.5-33.4-44.5-44.5-44.5-116.6 0-161C691.1 75.1 720.2 64 749.4 64c29.1 0 58.3 11.1 80.5 33.4 44.5 44.4 44.5 116.5 0 161zM246.4 294.5c-17.2 17.2-39.7 25.8-62.3 25.8-22.5 0-45.1-8.6-62.3-25.8-34.4-34.4-34.4-90.2 0-124.6 17.2-17.2 39.7-25.8 62.3-25.8 22.5 0 45.1 8.6 62.3 25.8 34.4 34.4 34.4 90.2 0 124.6zM218.8 794.9c-14.1 14-32.5 21.1-50.9 21.1s-36.8-7-50.8-21.1c-28.1-28.1-28.1-73.6 0-101.7 14-14 32.5-21.1 50.8-21.1 18.4 0 36.8 7 50.9 21.1 28.1 28.1 28.1 73.6 0 101.7z" p-id="6420" fill="#999999"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
img/petal1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

BIN
img/petal2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

BIN
img/petal3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

22
img/sign-go.svg Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="30px" height="30px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="171" y1="1" x2="171" y2="44" id="LinearGradient644">
<stop id="Stop645" stop-color="#fbfff4" offset="0" />
<stop id="Stop646" stop-color="#fbcdc4" offset="1" />
</linearGradient>
<filter x="156px" y="16px" width="30px" height="30px" filterUnits="userSpaceOnUse" id="filter647">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetInner" />
<feGaussianBlur stdDeviation="1" in="shadowOffsetInner" result="shadowGaussian" />
<feComposite in2="shadowGaussian" operator="atop" in="SourceAlpha" result="shadowComposite" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.349019607843137 0 " in="shadowComposite" />
</filter>
<g id="widget648">
<path d="M 171 18 C 178.28 18 184 23.72 184 31 C 184 38.28 178.28 44 171 44 C 163.72 44 158 38.28 158 31 C 158 23.72 163.72 18 171 18 Z " fill-rule="nonzero" fill="url(#LinearGradient644)" stroke="none" />
</g>
</defs>
<g transform="matrix(1 0 0 1 -156 -16 )">
<use xlink:href="#widget648" filter="url(#filter647)" />
<use xlink:href="#widget648" />
</g>
</svg>

BIN
img/sign-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

13
img/sign-in-bj.svg Normal file

File diff suppressed because one or more lines are too long

7
img/u1829.svg Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="8px" height="8px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1317 -4719 )">
<path d="M 1321 4720 C 1322.68 4720 1324 4721.32 1324 4723 C 1324 4724.68 1322.68 4726 1321 4726 C 1319.32 4726 1318 4724.68 1318 4723 C 1318 4721.32 1319.32 4720 1321 4720 Z " fill-rule="nonzero" fill="#fddf6d" stroke="none" />
<path d="M 1321 4720 C 1322.68 4720 1324 4721.32 1324 4723 C 1324 4724.68 1322.68 4726 1321 4726 C 1319.32 4726 1318 4724.68 1318 4723 C 1318 4721.32 1319.32 4720 1321 4720 Z " stroke-width="2" stroke="#aaaaaa" fill="none" />
</g>
</svg>

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -158,7 +159,10 @@
</template>
</div>
</div>
<div class="list-load-box flexcenter">
<img class="list-load-icon" src="./img/load-icon.svg" />
<div class="list-load-text">加载中</div>
</div>
<item-forum :itemdata="item" v-for="(item, index) in list" :key="index"></item-forum>
</div>
<div class="sidebar">
@@ -270,4 +274,5 @@
<script src="./js/scrolltext.js"></script>
<script type="module" src="./js/index.js"></script>
</body>
</html>

View File

@@ -112,7 +112,7 @@ const appIndex = createApp({
let ongoingbj = ref({}); // 话题数据
const getTalkingRecommend = () => {
ajaxget("/v2/api/forum/talkingRecommend").then((res) => {
ajaxGet("/v2/api/forum/talkingRecommend").then((res) => {
if (res.code != 200) return;
let data = res["data"] || [];
@@ -128,7 +128,7 @@ const appIndex = createApp({
let topicHandpickedList = ref([]); // 精选列表
const getTopicHandpicked = (uniqid) => {
ajaxget(`/v2/api/forum/topicHandpicked?limit=16`).then((res) => {
ajaxGet(`/v2/api/forum/topicHandpicked?limit=16`).then((res) => {
if (res.code != 200) return;
let data = res["data"] || [];
topicHandpickedList.value = data;
@@ -139,7 +139,7 @@ const appIndex = createApp({
let vote = ref([]); // 面经列表
let interviewexperience = ref([]); // 面经列表
const getTopicLatest = () => {
ajaxget(`/v2/api/forum/getTopicLatest?limit=4`).then((res) => {
ajaxGet(`/v2/api/forum/getTopicLatest?limit=4`).then((res) => {
const data = res.data || [];
data.vote.forEach((item) => {
@@ -238,7 +238,7 @@ const appIndex = createApp({
let sectionList = ref([]);
const getSectionList = () => {
ajaxget("/v2/api/forum/getSectionList").then((res) => {
ajaxGet("/v2/api/forum/getSectionList").then((res) => {
if (res.code != 200) return;
const data = res.data || [];
let obj = {};
@@ -267,7 +267,7 @@ const appIndex = createApp({
if (loading || page.value == 0) return;
loading = true;
// wx.showLoading();
ajaxget(`/v2/api/forum/topicLists?type=thread&page=${page.value || 1}`)
ajaxGet(`/v2/api/forum/topicLists?type=thread&page=${page.value || 1}`)
.then((res) => {
// wx.hideLoading();
if (res.code != 200) return;

View File

@@ -221,7 +221,7 @@ const managerHide = (token, state, type = "offer") => {
const isConfirmed = confirm(`确定要${state == 0 ? "隐藏" : "显示"}${obj[type]}吗?`);
if (isConfirmed) {
ajax(`https://api.gter.net/v2/api/forum/setTopicHide`, {
ajax(`/v2/api/forum/setTopicHide`, {
token,
hidden: Number(state !== 1),
}).then((res) => {