fix(component): 修复组件名称错误和props类型定义

refactor(component): 重构组件模板结构,移除重复代码

feat(component): 添加可选props支持外部数据传入

style(css): 优化样式布局和响应式设计

fix(js): 修复URL路径处理逻辑和滚动加载问题

feat(search): 新增搜索页推荐内容和空状态处理

chore: 添加新图标资源文件
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-12-22 19:01:00 +08:00
parent acf03efaf0
commit 43556292d2
26 changed files with 783 additions and 225 deletions

View File

@@ -4,7 +4,7 @@ const { defineComponent, ref, inject, defineAsyncComponent, onMounted } = Vue;
// 定义组件(直接使用模板) // 定义组件(直接使用模板)
export const helperPop = defineComponent({ export const helperPop = defineComponent({
name: "item-bottom", name: "helper-pop",
props: {}, props: {},
setup(props) { setup(props) {

View File

@@ -1,20 +1,41 @@
// my-component.js // my-component.js
// 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window // 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window
const { defineComponent, ref, onMounted } = Vue; const { defineComponent, ref, onMounted, watch } = Vue;
// 定义组件(直接使用模板) // 定义组件(直接使用模板)
export const hotSearch = defineComponent({ export const hotSearch = defineComponent({
name: "hot-search", name: "hot-search",
props: {}, props: {
isnorequestdata: {
type: Boolean,
},
searchlist: {
type: Array,
},
},
setup(props) { setup(props) {
let valueUrl = ref(""); let valueUrl = ref("");
onMounted(() => { onMounted(() => {
init(); if (!props.isnorequestdata) init();
const valueA = document.querySelector(".valueA"); const valueA = document.querySelector(".valueA");
valueUrl.value = valueA.innerText; valueUrl.value = valueA.innerText;
}); });
const list = ref([]);
watch(
() => props.searchlist,
(newVal) => {
if (newVal) list.value = newVal;
},
{
deep: true, // 核心:开启深度监听(监听对象/数组内部属性变化)
immediate: true, // 可选:组件挂载时立即执行一次回调(根据需求决定)
}
);
const init = () => { const init = () => {
ajaxGet("/v2/api/forum/getHotSearchWords?limit=20").then((res) => { ajaxGet("/v2/api/forum/getHotSearchWords?limit=20").then((res) => {
const data = res.data; const data = res.data;
@@ -22,12 +43,10 @@ export const hotSearch = defineComponent({
}); });
}; };
const list = ref([]);
return { valueUrl, list }; return { valueUrl, list };
}, },
components: {}, components: {},
template: `<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag-title"> <img class="icon" :src="valueUrl + '/img/triangle-violet.svg'" /> 热门搜索 </div> <div class="list flexflex"> <a class="item" v-for="item in list" :href="'/search/' + item.keyword" target="_blank">{{ item.keyword }}</a> </div></div>`, template: `<div class="hot-tag" v-if="list?.length > 0"> <div class="hot-tag-title"> <img class="icon" :src="valueUrl + '/img/triangle-violet.svg'" /> 热门搜索 </div> <div class="list flexflex"> <a class="item" v-for="item in list" :href="'/search/' + item.keyword" target="_blank">{{ item.keyword }}</a> </div></div>`,
}); });

View File

@@ -1,4 +1,4 @@
<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag" v-if="list?.length > 0">
<div class="hot-tag-title"> <div class="hot-tag-title">
<img class="icon" :src="valueUrl + '/img/triangle-violet.svg'" /> <img class="icon" :src="valueUrl + '/img/triangle-violet.svg'" />
热门搜索 热门搜索

View File

@@ -1,16 +1,23 @@
// my-component.js // my-component.js
// 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window // 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window
const { defineComponent, ref, onMounted } = Vue; const { defineComponent, ref, onMounted, emit, watch } = Vue;
// 定义组件(直接使用模板) // 定义组件(直接使用模板)
export const hotTag = defineComponent({ export const hotTag = defineComponent({
name: "hot-tag", name: "hot-tag",
props: {}, props: {
isnorequestdata: {
type: Boolean,
},
taglist: {
type: Array,
},
},
setup(props) { setup(props) {
let valueUrl = ref(""); let valueUrl = ref("");
onMounted(() => { onMounted(() => {
init(); if (!props.isnorequestdata) init();
const valueA = document.querySelector(".valueA"); const valueA = document.querySelector(".valueA");
valueUrl.value = valueA.innerText; valueUrl.value = valueA.innerText;
}); });
@@ -24,10 +31,22 @@ export const hotTag = defineComponent({
const list = ref([]); const list = ref([]);
watch(
() => props.taglist,
(newVal) => {
if (newVal) list.value = newVal;
},
{
deep: true, // 核心:开启深度监听(监听对象/数组内部属性变化)
immediate: true, // 可选:组件挂载时立即执行一次回调(根据需求决定)
}
);
return { valueUrl, list }; return { valueUrl, list };
}, },
components: {}, components: {},
template: `<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag-title"> <img class="icon" :src="valueUrl + '/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="valueUrl + '/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,4 +1,4 @@
<div class="hot-tag" v-if="list.length > 0"> <div class="hot-tag" v-if="list?.length > 0">
<div class="hot-tag-title"> <div class="hot-tag-title">
<img class="icon" :src="valueUrl + '/img/triangle-orange.svg'" /> <img class="icon" :src="valueUrl + '/img/triangle-orange.svg'" />
热门标签 热门标签

View File

@@ -4,7 +4,7 @@ const { defineComponent, ref, inject, defineAsyncComponent, onMounted } = Vue;
// 定义组件(直接使用模板) // 定义组件(直接使用模板)
export const huddleBox = defineComponent({ export const huddleBox = defineComponent({
name: "item-bottom", name: "huddle-box",
props: {}, props: {},
setup(props) { setup(props) {

View File

@@ -17,25 +17,25 @@ export const itemBottom = defineComponent({
setup(props) { setup(props) {
let valueUrl = ref(""); let valueUrl = ref("");
let isMobile = ref(false) let isMobile = ref(false);
onMounted(() => { onMounted(() => {
const valueA = document.querySelector(".valueA"); const valueA = document.querySelector(".valueA");
valueUrl.value = valueA.innerText; valueUrl.value = valueA.innerText;
isMobile.value = window.isMobile isMobile.value = window.isMobile;
}); });
let item = ref({ ...props.itemdata }); let item = ref({ ...props.itemdata });
let isLogin = inject("isLogin"); let isLogin = inject("isLogin");
let userInfoWin = inject("userInfoWin"); let userInfoWin = inject("userInfoWin");
let realname = inject("realname"); let realname = inject("realname", null);
let goLogin = inject("goLogin"); let goLogin = inject("goLogin");
let openAttest = inject("openAttest"); let openAttest = inject("openAttest");
let isLikeGif = ref(false); let isLikeGif = ref(false);
let cancelOperate = inject("cancelOperate"); let cancelOperate = inject("cancelOperate", () => {});
const likeClick = () => { const likeClick = () => {
if (realname.value == 0 && userInfoWin.value?.uin > 0) { if (realname.value == 0 && userInfoWin.value?.uin > 0) {
@@ -50,7 +50,7 @@ export const itemBottom = defineComponent({
const token = item.value.token || ""; const token = item.value.token || "";
if (["offer", "offer_summary", "interviewexperience"].includes(itemvalue["type"]) && item.value["is_like"]) { if (["offer", "offer_summary", "interviewexperience"].includes(item.value["type"]) && item.value["is_like"]) {
creationAlertBox("error", "不可取消点赞"); creationAlertBox("error", "不可取消点赞");
return; return;
} }
@@ -154,5 +154,5 @@ export const itemBottom = defineComponent({
like, like,
}, },
template: `<a class="comment flexacenter" v-if="item?.commentreviews && !Array.isArray(item?.commentreviews)" :href="item.url" target="_blank"> <img class="icon" :src="item?.commentreviews?.avatar" /> <div class="text one-line-display">{{ item?.commentreviews?.content || "[图]" }}</div></a><template v-if="item.comment_list?.length != 0"> <a class="comment flexacenter" style="margin-bottom: 15px" v-for="(item, index) in item.comment_list" :key="index" :href="item.url" target="_blank"> <img class="icon" :src="item.avatar" /> <div class="text one-line-display">{{ item.content || "[图]" }}</div> </a></template><div class="bottom flexacenter"> <div class="bottom-item like flexacenter" @click="likeClick()" v-if="item?.type != 'tenement'"> <img v-if="item.is_like" class="icon" :src="valueUrl + '/img/like-red-icon.png'" /> <img v-else class="icon" :src="valueUrl + '/img/like-icon.png'" /> <div class="text">{{ item.likes || "赞" }}</div> </div> <div class="bottom-item flexacenter" @click="collectClick()"> <img v-if="item.is_collect" class="icon" :src="valueUrl + '/img/collect-golden.svg'" /> <img v-else class="icon" :src="valueUrl + '/img/collect-gray.png'" /> <div class="text">{{ item.collections || "收藏" }}</div> </div> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <img class="icon" :src="valueUrl + '/img/discuss-icon.png'" /> <div class="text">{{ item.comments || "讨论" }}</div> </a> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <img class="icon" :src="valueUrl + '/img/bi-copper-icon.png'" /> <div class="text">{{ item.coins || "投币" }}</div> </a> <!-- 鼠标移入事件 --> <div class="bottom-item share flexacenter" @mouseenter="share" @click="isMobile ? copyLinkClick() : ''"> <img class="icon" :src="valueUrl + '/img/share-gray.png'" style="width: 19px; height: 19px;" /> <div class="text">{{ item.shares || '转发'}}</div> <div class="share-box flexcenter" ref="shareBoxRef"> <div class="share-item flexcenter" @click="copyLinkClick()"> <img class="share-icon" :src="valueUrl + '/img/copy-black-icon.png'" /> <div class="text">复制链接</div> </div> <!-- 鼠标移入 加载二维码 --> <div class="share-item wenxin flexcenter" @mouseenter="showQRcode"> <img class="share-icon" :src="valueUrl + '/img/weixin-icon.png'" /> <div class="text">微信转发</div> <div class="QRcode-box flexcenter" :class="{'right': isright}"> <img v-if="QRcode" class="QRcode" :src="QRcode" /> <div v-else class="QRcode flexcenter"> <img class="load" :src="valueUrl + '/img/load-icon.svg'" /> </div> <div class="text">微信扫码</div> </div> </div> </div> </div></div><like v-if="isLikeGif"></like>`, template: `<div> <a class="comment flexacenter" v-if="item?.commentreviews && !Array.isArray(item?.commentreviews)" :href="item.url" target="_blank"> <img class="icon" :src="item?.commentreviews?.avatar" /> <div class="text one-line-display">{{ item?.commentreviews?.content || "[图]" }}</div> </a> <template v-if="item.comment_list?.length != 0"> <a class="comment flexacenter" style="margin-bottom: 15px" v-for="(item, index) in item.comment_list" :key="index" :href="item.url" target="_blank"> <img class="icon" :src="item.avatar" /> <div class="text one-line-display">{{ item.content || "[图]" }}</div> </a> </template> <div class="bottom flexacenter"> <div class="bottom-item like flexacenter" @click="likeClick()" v-if="item?.type != 'tenement'"> <img v-if="item.is_like" class="icon" :src="valueUrl + '/img/like-red-icon.png'" /> <img v-else class="icon" :src="valueUrl + '/img/like-icon.png'" /> <div class="text">{{ item.likes || "赞" }}</div> </div> <div class="bottom-item flexacenter" @click="collectClick()"> <img v-if="item.is_collect" class="icon" :src="valueUrl + '/img/collect-golden.svg'" /> <img v-else class="icon" :src="valueUrl + '/img/collect-gray.png'" /> <div class="text">{{ item.collections || "收藏" }}</div> </div> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <img class="icon" :src="valueUrl + '/img/discuss-icon.png'" /> <div class="text">{{ item.comments || "讨论" }}</div> </a> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <img class="icon" :src="valueUrl + '/img/bi-copper-icon.png'" /> <div class="text">{{ item.coins || "投币" }}</div> </a> <!-- 鼠标移入事件 --> <div class="bottom-item share flexacenter" @mouseenter="share" @click="isMobile ? copyLinkClick() : ''"> <img class="icon" :src="valueUrl + '/img/share-gray.png'" style="width: 19px; height: 19px;" /> <div class="text">{{ item.shares || '转发'}}</div> <div class="share-box flexcenter" ref="shareBoxRef"> <div class="share-item flexcenter" @click="copyLinkClick()"> <img class="share-icon" :src="valueUrl + '/img/copy-black-icon.png'" /> <div class="text">复制链接</div> </div> <!-- 鼠标移入 加载二维码 --> <div class="share-item wenxin flexcenter" @mouseenter="showQRcode"> <img class="share-icon" :src="valueUrl + '/img/weixin-icon.png'" /> <div class="text">微信转发</div> <div class="QRcode-box flexcenter" :class="{'right': isright}"> <img v-if="QRcode" class="QRcode" :src="QRcode" /> <div v-else class="QRcode flexcenter"> <img class="load" :src="valueUrl + '/img/load-icon.svg'" /> </div> <div class="text">微信扫码</div> </div> </div> </div> </div> </div> <like v-if="isLikeGif"></like></div>`,
}); });

View File

@@ -1,60 +1,62 @@
<a class="comment flexacenter" v-if="item?.commentreviews && !Array.isArray(item?.commentreviews)" :href="item.url" target="_blank"> <div>
<img class="icon" :src="item?.commentreviews?.avatar" /> <a class="comment flexacenter" v-if="item?.commentreviews && !Array.isArray(item?.commentreviews)" :href="item.url" target="_blank">
<div class="text one-line-display">{{ item?.commentreviews?.content || "[图]" }}</div> <img class="icon" :src="item?.commentreviews?.avatar" />
</a> <div class="text one-line-display">{{ item?.commentreviews?.content || "[图]" }}</div>
<template v-if="item.comment_list?.length != 0">
<a class="comment flexacenter" style="margin-bottom: 15px" v-for="(item, index) in item.comment_list" :key="index" :href="item.url" target="_blank">
<img class="icon" :src="item.avatar" />
<div class="text one-line-display">{{ item.content || "[图]" }}</div>
</a> </a>
</template> <template v-if="item.comment_list?.length != 0">
<div class="bottom flexacenter"> <a class="comment flexacenter" style="margin-bottom: 15px" v-for="(item, index) in item.comment_list" :key="index" :href="item.url" target="_blank">
<div class="bottom-item like flexacenter" @click="likeClick()" v-if="item?.type != 'tenement'"> <img class="icon" :src="item.avatar" />
<img v-if="item.is_like" class="icon" :src="valueUrl + '/img/like-red-icon.png'" /> <div class="text one-line-display">{{ item.content || "[图]" }}</div>
<img v-else class="icon" :src="valueUrl + '/img/like-icon.png'" /> </a>
<div class="text">{{ item.likes || "赞" }}</div> </template>
</div> <div class="bottom flexacenter">
<div class="bottom-item like flexacenter" @click="likeClick()" v-if="item?.type != 'tenement'">
<img v-if="item.is_like" class="icon" :src="valueUrl + '/img/like-red-icon.png'" />
<img v-else class="icon" :src="valueUrl + '/img/like-icon.png'" />
<div class="text">{{ item.likes || "赞" }}</div>
</div>
<div class="bottom-item flexacenter" @click="collectClick()"> <div class="bottom-item flexacenter" @click="collectClick()">
<img v-if="item.is_collect" class="icon" :src="valueUrl + '/img/collect-golden.svg'" /> <img v-if="item.is_collect" class="icon" :src="valueUrl + '/img/collect-golden.svg'" />
<img v-else class="icon" :src="valueUrl + '/img/collect-gray.png'" /> <img v-else class="icon" :src="valueUrl + '/img/collect-gray.png'" />
<div class="text">{{ item.collections || "收藏" }}</div> <div class="text">{{ item.collections || "收藏" }}</div>
</div> </div>
<a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank">
<img class="icon" :src="valueUrl + '/img/discuss-icon.png'" /> <img class="icon" :src="valueUrl + '/img/discuss-icon.png'" />
<div class="text">{{ item.comments || "讨论" }}</div> <div class="text">{{ item.comments || "讨论" }}</div>
</a> </a>
<a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank"> <a class="bottom-item flexacenter" v-if="item?.type != 'tenement'" :href="'/details/' + item.uniqid" target="_blank">
<img class="icon" :src="valueUrl + '/img/bi-copper-icon.png'" /> <img class="icon" :src="valueUrl + '/img/bi-copper-icon.png'" />
<div class="text">{{ item.coins || "投币" }}</div> <div class="text">{{ item.coins || "投币" }}</div>
</a> </a>
<!-- 鼠标移入事件 --> <!-- 鼠标移入事件 -->
<div class="bottom-item share flexacenter" @mouseenter="share" @click="isMobile ? copyLinkClick() : ''"> <div class="bottom-item share flexacenter" @mouseenter="share" @click="isMobile ? copyLinkClick() : ''">
<img class="icon" :src="valueUrl + '/img/share-gray.png'" style="width: 19px; height: 19px;" /> <img class="icon" :src="valueUrl + '/img/share-gray.png'" style="width: 19px; height: 19px;" />
<div class="text">{{ item.shares || '转发'}}</div> <div class="text">{{ item.shares || '转发'}}</div>
<div class="share-box flexcenter" ref="shareBoxRef"> <div class="share-box flexcenter" ref="shareBoxRef">
<div class="share-item flexcenter" @click="copyLinkClick()"> <div class="share-item flexcenter" @click="copyLinkClick()">
<img class="share-icon" :src="valueUrl + '/img/copy-black-icon.png'" /> <img class="share-icon" :src="valueUrl + '/img/copy-black-icon.png'" />
<div class="text">复制链接</div> <div class="text">复制链接</div>
</div> </div>
<!-- 鼠标移入 加载二维码 --> <!-- 鼠标移入 加载二维码 -->
<div class="share-item wenxin flexcenter" @mouseenter="showQRcode"> <div class="share-item wenxin flexcenter" @mouseenter="showQRcode">
<img class="share-icon" :src="valueUrl + '/img/weixin-icon.png'" /> <img class="share-icon" :src="valueUrl + '/img/weixin-icon.png'" />
<div class="text">微信转发</div> <div class="text">微信转发</div>
<div class="QRcode-box flexcenter" :class="{'right': isright}"> <div class="QRcode-box flexcenter" :class="{'right': isright}">
<img v-if="QRcode" class="QRcode" :src="QRcode" /> <img v-if="QRcode" class="QRcode" :src="QRcode" />
<div v-else class="QRcode flexcenter"> <div v-else class="QRcode flexcenter">
<img class="load" :src="valueUrl + '/img/load-icon.svg'" /> <img class="load" :src="valueUrl + '/img/load-icon.svg'" />
</div>
<div class="text">微信扫码</div>
</div> </div>
<div class="text">微信扫码</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<like v-if="isLikeGif"></like> <like v-if="isLikeGif"></like>
</div>

View File

@@ -167,5 +167,5 @@ export const itemHead = defineComponent({
report, report,
}, },
template: `<div class="item-head flexacenter" ref="itemHead"> <div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uniqid)"> <img class="avatar" :src="item?.user?.avatar || item.avatar" /> <div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div> <img class="group" v-if="item.user?.groupimage" :src="item.user?.groupimage" /> </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="valueUrl + '/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="valueUrl + '/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="valueUrl + '/img/u1829.svg'"></image> </div> </div> </template> </div> <div class="view flexacenter"> <img class="icon" :src="valueUrl + '/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="valueUrl + '/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"> <a class="item icon" v-if="item.recommend == 1 && item.best != 1" target="_blank" href="/recommend"> <img style="height: 25px;" :src="valueUrl + '/img/recommend-icon.png'" /> </a> <a class="item icon" v-if="item.best == 1" target="_blank" href="/best"> <img style="height: 25px;" v-if="item.best == 1" :src="valueUrl + '/img/essence-icon.png'" /> </a> <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> <div class="item-head flexacenter" ref="itemHead"> <div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uniqid)"> <img class="avatar" :src="item?.user?.avatar || item.avatar" /> <div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div> <img class="group" v-if="item.user?.groupimage" :src="item.user?.groupimage" /> </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="valueUrl + '/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="valueUrl + '/img/u1829.svg'" /> </div> <div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表 <img v-if="item.anonymous != 0" class="isPublicityIcon" :src="valueUrl + '/img/u1829.svg'" /> </div> </div> </template> </div> <div class="view flexacenter"> <img class="icon" :src="valueUrl + '/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="valueUrl + '/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"> <a class="item icon" v-if="item.recommend == 1 && item.best != 1" target="_blank" href="/recommend"> <img style="height: 25px;" :src="valueUrl + '/img/recommend-icon.png'" /> </a> <a class="item icon" v-if="item.best == 1" target="_blank" href="/best"> <img style="height: 25px;" v-if="item.best == 1" :src="valueUrl + '/img/essence-icon.png'" /> </a> <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></div>`,
}); });

View File

@@ -1,75 +1,77 @@
<div class="item-head flexacenter" ref="itemHead"> <div>
<div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uniqid)"> <div class="item-head flexacenter" ref="itemHead">
<img class="avatar" :src="item?.user?.avatar || item.avatar" /> <div class="user-box flexacenter" @click="goPersonalHomepage(item?.user?.uniqid)">
<div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div> <img class="avatar" :src="item?.user?.avatar || item.avatar" />
<img class="group" v-if="item.user?.groupimage" :src="item.user?.groupimage" /> <div class="name">{{ item?.user?.nickname || item.nickname || "匿名用户" }}</div>
</div> <img class="group" v-if="item.user?.groupimage" :src="item.user?.groupimage" />
<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="valueUrl + '/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> </div>
<!-- 是否 公开发表 --> <div class="time">{{ timestamp }}</div>
<template v-if="anonymousState"> <div class="flex1"></div>
<div class="mask" @click.stop="cutAnonymous"></div>
<div class="isPublicityBox"> <div class="circlePen flexcenter" @click="openedit(item.type)" v-if="page == 'edit' && (item.type == 'offer' || item.type == 'offer_summary')">
<div class="isPublicity-item" :class="{'green': item.anonymous == 0}" @click.stop="cutAnonymousState(0)">公开发表 <img class="icon" :src="valueUrl + '/img/pen-icon.png'" />
<img v-if="item.anonymous == 0" class="isPublicityIcon" :src="valueUrl + '/img/u1829.svg'"></image> </div>
</div>
<div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表 <div class="flexacenter" style="position: relative;">
<img v-if="item.anonymous != 0" class="isPublicityIcon" :src="valueUrl + '/img/u1829.svg'"></image> <div class="anonymous-box flexcenter" @click.stop="cutAnonymous" v-if="page == 'edit' && (item.type == 'vote' || item.type == 'interviewexperience')">
</div> <span v-if="item.anonymous == 0">公开</span>
<span v-else>匿名</span>
</div> </div>
</template>
</div>
<!-- 是否 公开发表 -->
<div class="view flexacenter"> <template v-if="anonymousState">
<img class="icon" :src="valueUrl + '/img/eye-icon.svg'" /> <div class="mask" @click.stop="cutAnonymous"></div>
<div class="text">{{ item.views }}</div> <div class="isPublicityBox">
</div> <div class="isPublicity-item" :class="{'green': item.anonymous == 0}" @click.stop="cutAnonymousState(0)">公开发表
<img v-if="item.anonymous == 0" class="isPublicityIcon" :src="valueUrl + '/img/u1829.svg'" />
<div v-if="item.type != 'tenement'" class="btn flexcenter" @click.stop="cutShow"> </div>
<img class="icon" :src="valueUrl + '/img/dot-dot-dot-gray.png'" /> <div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表
</div> <img v-if="item.anonymous != 0" class="isPublicityIcon" :src="valueUrl + '/img/u1829.svg'" />
</div>
<div v-if="show"> </div>
<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>
</div>
<template v-if="item.type == 'thread' && item.ismyself">
<div class="item" @click.stop="edit">编辑</div> <div class="view flexacenter">
<div class="item" @click.stop="deleteItem">删除</div> <img class="icon" :src="valueUrl + '/img/eye-icon.svg'" />
</template> <div class="text">{{ item.views }}</div>
<div class="item" v-if="page == 'edit' && item.type == 'vote'" @click.stop="deleteItem">删除</div> </div>
<div v-if="item.type != 'tenement'" class="btn flexcenter" @click.stop="cutShow">
<img class="icon" :src="valueUrl + '/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> </div>
</div>
<div class="label flexflex" v-if="sectionn?.length || tags?.length || item.recommend == 1 || item.best == 1"> <div class="label flexflex" v-if="sectionn?.length || tags?.length || item.recommend == 1 || item.best == 1">
<a class="item icon" v-if="item.recommend == 1 && item.best != 1" target="_blank" href="/recommend"> <a class="item icon" v-if="item.recommend == 1 && item.best != 1" target="_blank" href="/recommend">
<img style="height: 25px;" :src="valueUrl + '/img/recommend-icon.png'" /> <img style="height: 25px;" :src="valueUrl + '/img/recommend-icon.png'" />
</a> </a>
<a class="item icon" v-if="item.best == 1" target="_blank" href="/best"> <a class="item icon" v-if="item.best == 1" target="_blank" href="/best">
<img style="height: 25px;" v-if="item.best == 1" :src="valueUrl + '/img/essence-icon.png'" /> <img style="height: 25px;" v-if="item.best == 1" :src="valueUrl + '/img/essence-icon.png'" />
</a> </a>
<a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a> <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> <a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a>
</div> </div>
<report v-if="reportState" :itemdata="item"></report> <report v-if="reportState" :itemdata="item"></report>
</div>

View File

@@ -32,5 +32,5 @@ export const itemMj = defineComponent({
itemHead, itemHead,
}, },
template: `<div class="item-box item-mj"> <item-head :itemdata="item" :page="page"></item-head> <a class="school flexacenter" :href="item.url" target="_blank" v-if="item.data.schoolname"> <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>`, template: `<div class="item-box item-mj"> <item-head :itemdata="item" :page="page"></item-head> <a class="school flexacenter" :href="item.url" target="_blank" v-if="item.data.schoolname"> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" /> <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,7 +1,7 @@
<div class="item-box item-mj"> <div class="item-box item-mj">
<item-head :itemdata="item" :page="page"></item-head> <item-head :itemdata="item" :page="page"></item-head>
<a class="school flexacenter" :href="item.url" target="_blank" v-if="item.data.schoolname"> <a class="school flexacenter" :href="item.url" target="_blank" v-if="item.data.schoolname">
<img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" />
<div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div>
</a> </a>

View File

@@ -31,5 +31,5 @@ export const itemOffer = defineComponent({
itemHead, itemHead,
}, },
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>`, 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" /> <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,7 +1,7 @@
<div class="item-box item-offer"> <div class="item-box item-offer">
<item-head :itemdata="item" :page="page"></item-head> <item-head :itemdata="item" :page="page"></item-head>
<a class="school flexacenter" :href="item.url" target="_blank"> <a class="school flexacenter" :href="item.url" target="_blank">
<img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" mode="heightFix"></image> <img class="icon" v-if="item.data.schoollogo" :src="item.data.schoollogo" />
<div class="text flex1 one-line-display">{{ item.data.schoolname }}</div> <div class="text flex1 one-line-display">{{ item.data.schoolname }}</div>
</a> </a>

View File

@@ -36,5 +36,5 @@ export const itemSummary = defineComponent({
itemHead, itemHead,
}, },
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"> <template v-for="(it,i) in item.data.offerlist" :key="i"> <div class="item flexflex" v-if="i < 2"> <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> </template> <div v-if="item.data.offercount > 2" class="item more flexcenter"> <div class="item-content flexcenter"> <div class="">查看更多</div> <img class="icon" :src="valueUrl + '/img/arrows-circle-dark-blue.svg'" mode="heightFix"></image> </div> </div> </a> <item-bottom :itemdata="item" :page="page"></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-v2" :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"> <template v-for="(it,i) in item.data.offerlist" :key="i"> <div class="item flexflex" v-if="i < 2"> <div class="item-content flexflex"> <div class="school flexacenter"> <img class="icon" v-if="it.schoollogo" :src="it.schoollogo" /> <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> </template> <div v-if="item.data.offercount > 2" class="item more flexcenter"> <div class="item-content flexcenter"> <div class="">查看更多</div> <img class="icon" :src="valueUrl + '/img/arrows-circle-dark-blue.svg'" /> </div> </div> </a> <item-bottom :itemdata="item" :page="page"></item-bottom></div>`,
}); });

View File

@@ -1,7 +1,7 @@
<div class="item-box item-summary"> <div class="item-box item-summary">
<item-head :itemdata="item" :page="page"></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="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="message one-line-display-v2" :href="item.url" target="_blank" v-if="item.content">{{ item.content }}</a>
<a class="total flexacenter" :href="item.url" target="_blank"> <a class="total flexacenter" :href="item.url" target="_blank">
<div>共</div> <div>共</div>
<div class="num">{{ item.data.offercount }}</div> <div class="num">{{ item.data.offercount }}</div>
@@ -12,7 +12,7 @@
<div class="item flexflex" v-if="i < 2"> <div class="item flexflex" v-if="i < 2">
<div class="item-content flexflex"> <div class="item-content flexflex">
<div class="school flexacenter"> <div class="school flexacenter">
<img class="icon" v-if="it.schoollogo" :src="it.schoollogo" mode="heightFix"></image> <img class="icon" v-if="it.schoollogo" :src="it.schoollogo" />
<div class="name one-line-display flex1">{{ it.schoolname }}</div> <div class="name one-line-display flex1">{{ it.schoolname }}</div>
</div> </div>
<div class="major one-line-display" v-if="it.professional">{{ it.professional }}</div> <div class="major one-line-display" v-if="it.professional">{{ it.professional }}</div>
@@ -30,7 +30,7 @@
<div v-if="item.data.offercount > 2" class="item more flexcenter"> <div v-if="item.data.offercount > 2" class="item more flexcenter">
<div class="item-content flexcenter"> <div class="item-content flexcenter">
<div class="">查看更多</div> <div class="">查看更多</div>
<img class="icon" :src="valueUrl + '/img/arrows-circle-dark-blue.svg'" mode="heightFix"></image> <img class="icon" :src="valueUrl + '/img/arrows-circle-dark-blue.svg'" />
</div> </div>
</div> </div>
</a> </a>

View File

@@ -7,7 +7,7 @@ export const loadBox = defineComponent({
name: "load-box", name: "load-box",
props: { props: {
loading: { loading: {
type: String, type: Boolean,
default: "", default: "",
}, },
}, },

View File

@@ -42,6 +42,13 @@ body {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.one-line-display-v2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.two-line-display { .two-line-display {
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@@ -243,7 +250,6 @@ body {
color: #555555; color: #555555;
white-space: pre-wrap; white-space: pre-wrap;
margin-bottom: 15px; margin-bottom: 15px;
display: block;
} }
.item-box.item-forum .picture { .item-box.item-forum .picture {
overflow-x: auto; overflow-x: auto;
@@ -334,7 +340,7 @@ body {
font-size: 14px; font-size: 14px;
color: #555555; color: #555555;
margin-bottom: 20px; margin-bottom: 20px;
display: block; width: 100%;
} }
.item-box.item-summary .total { .item-box.item-summary .total {
font-size: 14px; font-size: 14px;
@@ -350,15 +356,18 @@ body {
.item-box.item-summary .list { .item-box.item-summary .list {
overflow: auto; overflow: auto;
margin-bottom: 16px; margin-bottom: 16px;
max-width: 100%;
} }
.item-box.item-summary .list .item-content { .item-box.item-summary .list .item-content {
width: 280px; width: 280px;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding: 10px; padding: 10px;
flex: 1;
} }
.item-box.item-summary .list .item { .item-box.item-summary .list .item {
width: 280px; width: 280px;
flex-shrink: 0;
height: 110px; height: 110px;
background-color: rgba(242, 242, 242, 0); background-color: rgba(242, 242, 242, 0);
border: 1px solid #ebebeb; border: 1px solid #ebebeb;
@@ -702,6 +711,7 @@ body {
background-color: #f6f6f6; background-color: #f6f6f6;
border-radius: 10px; border-radius: 10px;
padding: 0 10px; padding: 0 10px;
width: 100%;
} }
.item-box .comment .icon { .item-box .comment .icon {
width: 20px; width: 20px;
@@ -713,7 +723,7 @@ body {
font-size: 14px; font-size: 14px;
color: #7f7f7f; color: #7f7f7f;
flex: 1; flex: 1;
width: 10px; width: 0;
} }
.item-box .bottom { .item-box .bottom {
height: 55px; height: 55px;

View File

@@ -54,6 +54,14 @@ body {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.one-line-display-v2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.two-line-display { .two-line-display {
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@@ -289,7 +297,7 @@ body {
color: #555555; color: #555555;
white-space: pre-wrap; white-space: pre-wrap;
margin-bottom: 15px; margin-bottom: 15px;
display: block; // display: block;
} }
.picture { .picture {
@@ -404,7 +412,7 @@ body {
font-size: 14px; font-size: 14px;
color: #555555; color: #555555;
margin-bottom: 20px; margin-bottom: 20px;
display: block; width: 100%;
} }
.total { .total {
@@ -423,16 +431,18 @@ body {
.list { .list {
overflow: auto; overflow: auto;
margin-bottom: 16px; margin-bottom: 16px;
max-width: 100%;
.item-content { .item-content {
width: 280px; width: 280px;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding: 10px; padding: 10px;
flex: 1;
} }
.item { .item {
width: 280px; width: 280px;
flex-shrink: 0;
height: 110px; height: 110px;
background-color: rgba(242, 242, 242, 0); background-color: rgba(242, 242, 242, 0);
border: 1px solid rgba(235, 235, 235, 1); border: 1px solid rgba(235, 235, 235, 1);
@@ -852,6 +862,7 @@ body {
background-color: rgba(246, 246, 246, 1); background-color: rgba(246, 246, 246, 1);
border-radius: 10px; border-radius: 10px;
padding: 0 10px; padding: 0 10px;
width: 100%;
.icon { .icon {
width: 20px; width: 20px;
@@ -864,7 +875,7 @@ body {
font-size: 14px; font-size: 14px;
color: #7f7f7f; color: #7f7f7f;
flex: 1; flex: 1;
width: 10px; width: 0;
} }
} }
@@ -3024,4 +3035,4 @@ td {
100% { 100% {
top: 0; top: 0;
} }
} }

View File

@@ -1,6 +1,7 @@
#search { #search {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
min-width: 320px;
} }
#search .search-box { #search .search-box {
width: 460px; width: 460px;
@@ -70,6 +71,7 @@
align-items: flex-end; align-items: flex-end;
} }
#search .matter .matter-content { #search .matter .matter-content {
min-width: 0;
margin-right: 12px; margin-right: 12px;
position: sticky; position: sticky;
z-index: 1; z-index: 1;
@@ -158,15 +160,173 @@
#search .search-no .earth-icon { #search .search-no .earth-icon {
width: 239px; width: 239px;
height: 180px; height: 180px;
margin: 0 auto; margin: 0 auto 20px;
} }
#search .search-no .input-box { #search .search-no .input-box {
width: 903px; max-width: 903px;
width: 100%;
height: 60px; height: 60px;
background-color: #ffffff; background-color: #ffffff;
border: 1px solid #e9eef2; border: 1px solid #e9eef2;
border-radius: 6px; border-radius: 6px;
margin: 0 auto 30px;
padding-right: 10px;
} }
#search .search-no .input-box .input { #search .search-no .input-box .input {
font-size: 16px; font-size: 16px;
border: none;
outline: none;
height: 100%;
padding: 0 15px;
border-radius: 6px;
}
#search .search-no .input-box .btn {
width: 120px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: #d35110;
border-radius: 8px;
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #ffffff;
cursor: pointer;
}
#search .search-no .recommend-box {
max-width: 903px;
width: 100%;
gap: 10px;
margin: 0 auto;
}
#search .search-no .recommend-box .recommend-head {
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #000000;
margin-bottom: 15px;
}
#search .search-no .recommend-box .recommend-head .icon {
width: 10px;
height: 18px;
margin-right: 10px;
}
#search .search-no .recommend-box .hot-box {
width: 100%;
background-color: #ffffff;
border: 1px solid #e9eef2;
border-radius: 10px;
padding-top: 20px;
padding-bottom: 12px;
}
#search .search-no .recommend-box .hot-box .hot-list {
flex-wrap: wrap;
padding-left: 20px;
padding-right: 12px;
}
#search .search-no .recommend-box .hot-box .hot-list .item {
font-size: 14px;
color: #333333;
height: 32px;
line-height: 32px;
padding: 0 13px;
margin-bottom: 10px;
background-color: #f6f6f6;
border: 1px solid #f2f2f2;
border-radius: 16px;
margin-right: 8px;
cursor: pointer;
}
#search .search-no .recommend-box .hot-box .hot-list .item .icon {
width: 17px;
height: 20px;
margin-right: 5px;
}
#search .search-no .recommend-box .read-box {
width: 291px;
background-color: #ffffff;
border: 1px solid #e9eef2;
border-radius: 10px;
padding-top: 20px;
padding-bottom: 12px;
}
#search .search-no .recommend-box .read-box .read-list {
padding-left: 20px;
padding-right: 12px;
}
#search .search-no .recommend-box .read-box .read-list .item {
font-size: 14px;
color: #555555;
cursor: pointer;
}
#search .search-no .recommend-box .read-box .read-list .item:hover {
color: #000000;
}
#search .search-no .recommend-box .read-box .read-list .item:not(:last-of-type) {
margin-bottom: 12px;
}
#search .search-no .recommend-box .read-box .read-list .item .dot {
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #86d0b1;
border: 1px solid #239f6c;
margin-right: 10px;
}
@media screen and (max-width: 768px) {
#search {
padding: 0 10px;
}
#search .search-no .earth-icon {
width: 60%;
max-width: 220px;
height: auto;
margin-bottom: 10px;
}
#search .search-no .input-box {
width: 100%;
height: 48px;
margin-bottom: 20px;
}
#search .search-no .input-box .btn {
width: 80px;
height: 36px;
line-height: 36px;
font-size: 14px;
}
#search .search-no .recommend-box {
width: 100%;
flex-direction: column;
height: auto;
}
#search .search-no .recommend-box .hot-box,
#search .search-no .recommend-box .read-box {
width: 100%;
}
.main-new {
width: 100%;
flex-direction: column;
}
.main-new .wp {
width: 100%;
min-width: 100%;
margin-right: 0;
}
.main-new .rightright {
width: 100%;
}
.item-box {
padding: 15px 10px 0;
}
.side-box {
width: 100%;
}
.head-top .input-box {
width: 100%;
}
.head-top .input-box .placeholder {
width: 100%;
}
} }

View File

@@ -1,6 +1,7 @@
#search { #search {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
min-width: 320px;
.search-box { .search-box {
width: 460px; width: 460px;
@@ -80,6 +81,7 @@
} }
.matter-content { .matter-content {
min-width: 0;
margin-right: 12px; margin-right: 12px;
position: sticky; position: sticky;
z-index: 1; z-index: 1;
@@ -200,20 +202,196 @@
.earth-icon { .earth-icon {
width: 239px; width: 239px;
height: 180px; height: 180px;
margin: 0 auto; margin: 0 auto 20px;
} }
.input-box { .input-box {
width: 903px; max-width: 903px;
width: 100%;
// width: 903px;
height: 60px; height: 60px;
background-color: rgba(255, 255, 255, 1); background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(233, 238, 242, 1); border: 1px solid rgba(233, 238, 242, 1);
border-radius: 6px; border-radius: 6px;
margin: 0 auto 30px;
padding-right: 10px;
.input { .input {
font-size: 16px;
font-size: 16px; border: none;
outline: none;
height: 100%;
padding: 0 15px;
border-radius: 6px;
}
.btn {
width: 120px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: rgba(211, 81, 16, 1);
border-radius: 8px;
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #ffffff;
cursor: pointer;
}
}
.recommend-box {
max-width: 903px;
width: 100%;
gap: 10px;
margin: 0 auto;
.recommend-head {
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #000000;
margin-bottom: 15px;
.icon {
width: 10px;
height: 18px;
margin-right: 10px;
}
}
.hot-box {
// width: 291px;
width: 100%;
// height: 365px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(233, 238, 242, 1);
border-radius: 10px;
padding-top: 20px;
padding-bottom: 12px;
.hot-list {
flex-wrap: wrap;
padding-left: 20px;
padding-right: 12px;
.item {
font-size: 14px;
color: #333333;
height: 32px;
line-height: 32px;
padding: 0 13px;
margin-bottom: 10px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(242, 242, 242, 1);
border-radius: 16px;
margin-right: 8px;
cursor: pointer;
.icon {
width: 17px;
height: 20px;
margin-right: 5px;
}
}
}
}
.read-box {
width: 291px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(233, 238, 242, 1);
border-radius: 10px;
padding-top: 20px;
padding-bottom: 12px;
.read-list {
padding-left: 20px;
padding-right: 12px;
.item {
font-size: 14px;
color: #555555;
cursor: pointer;
&:hover {
color: #000000;
}
&:not(:last-of-type) {
margin-bottom: 12px;
}
.dot {
width: 6px;
height: 6px;
border-radius: 50%;
background-color: #86d0b1;
border: 1px solid #239f6c;
margin-right: 10px;
}
}
}
} }
} }
} }
} }
@media screen and (max-width: 768px) {
#search {
padding: 0 10px;
}
#search .search-no .earth-icon {
width: 60%;
max-width: 220px;
height: auto;
margin-bottom: 10px;
}
#search .search-no .input-box {
width: 100%;
height: 48px;
margin-bottom: 20px;
}
#search .search-no .input-box .btn {
width: 80px;
height: 36px;
line-height: 36px;
font-size: 14px;
}
#search .search-no .recommend-box {
width: 100%;
flex-direction: column;
height: auto;
}
#search .search-no .recommend-box .hot-box,
#search .search-no .recommend-box .read-box {
width: 100%;
// margin-bottom: 15px;
}
.main-new {
width: 100%;
flex-direction: column;
}
.main-new .wp {
width: 100%;
min-width: 100%;
margin-right: 0;
}
.main-new .rightright {
width: 100%;
}
.item-box {
padding: 15px 10px 0;
}
.side-box {
width: 100%;
}
.head-top .input-box {
width: 100%;
}
.head-top .input-box .placeholder {
width: 100%;
}
}

6
img/triangle-blue.svg Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="10px" height="18px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1122 -427 )">
<path d="M 9.67013888888889 8.208984375 C 9.8900462962963 8.431640625 10 8.6953125 10 9 C 10 9.3046875 9.8900462962963 9.568359375 9.67013888888889 9.791015625 L 1.89236111111111 17.666015625 C 1.6724537037037 17.888671875 1.41203703703704 18 1.11111111111111 18 C 0.810185185185185 18 0.549768518518518 17.888671875 0.329861111111111 17.666015625 C 0.109953703703704 17.443359375 0 17.1796875 0 16.875 L 0 1.125 C 0 0.820312499999997 0.109953703703704 0.556640624999997 0.329861111111111 0.333984375 C 0.549768518518518 0.111328124999999 0.810185185185185 0 1.11111111111111 0 C 1.41203703703704 0 1.6724537037037 0.111328124999999 1.89236111111111 0.333984375 L 9.67013888888889 8.208984375 Z " fill-rule="nonzero" fill="#13a3df" stroke="none" transform="matrix(1 0 0 1 1122 427 )" />
</g>
</svg>

6
img/triangle-yellow.svg Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="10px" height="18px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -816 -427 )">
<path d="M 9.67013888888889 8.208984375 C 9.8900462962963 8.431640625 10 8.6953125 10 9 C 10 9.3046875 9.8900462962963 9.568359375 9.67013888888889 9.791015625 L 1.89236111111111 17.666015625 C 1.6724537037037 17.888671875 1.41203703703704 18 1.11111111111111 18 C 0.810185185185185 18 0.549768518518518 17.888671875 0.329861111111111 17.666015625 C 0.109953703703704 17.443359375 0 17.1796875 0 16.875 L 0 1.125 C 0 0.820312499999997 0.109953703703704 0.556640624999997 0.329861111111111 0.333984375 C 0.549768518518518 0.111328124999999 0.810185185185185 0 1.11111111111111 0 C 1.41203703703704 0 1.6724537037037 0.111328124999999 1.89236111111111 0.333984375 L 9.67013888888889 8.208984375 Z " fill-rule="nonzero" fill="#f3974b" stroke="none" transform="matrix(1 0 0 1 816 427 )" />
</g>
</svg>

View File

@@ -401,11 +401,29 @@ let copyForumUid = (text) => {
const updateUrlLastPath = (newLastPath, isReplace = false) => { const updateUrlLastPath = (newLastPath, isReplace = false) => {
const raw = typeof newLastPath === "string" ? newLastPath : String(newLastPath); const raw = typeof newLastPath === "string" ? newLastPath : String(newLastPath);
const basePath = raw.split("?")[0]; const basePath = raw.split("?")[0];
const newPathname = basePath.startsWith("/") ? basePath : "/" + basePath;
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 newSearch = window.location.search;
const newUrl = window.location.origin + newPathname + newSearch; const newUrl = window.location.origin + finalPathname + newSearch;
if (isReplace) history.replaceState(null, document.title, newUrl);
else history.pushState(null, document.title, newUrl); // 管理历史栈 + 修改URL
if (isReplace) {
history.replaceState(null, document.title, newUrl);
} else {
history.pushState(null, document.title, newUrl);
}
}; };
const removeQueryQ = (isReplace = false) => { const removeQueryQ = (isReplace = false) => {

View File

@@ -20,28 +20,60 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
let typeValue = ref(null); let typeValue = ref(null);
let kw = ref(""); let kw = ref("");
onMounted(() => { onMounted(() => {
console.log('onMounted');
const params = getUrlParams(); const params = getUrlParams();
// kw.value = params.kw || "";
// const urlObj = new URL(location.href);
// const pathParts = urlObj.pathname.split("/").filter((part) => part);
// kw.value = decodeURIComponent(pathParts.pop());
kw.value = kwValue.value.innerText; kw.value = kwValue.value.innerText;
const tab = typeValue.value.innerText; const tab = typeValue.value.innerText;
if (tab) tabValue.value = tab; if (tab) tabValue.value = tab;
if (params.page) page.value = params.page; if (params.page) page.value = params.page;
else page.value = 1; else page.value = 1;
console.log("kw.value", kw.value); if (kw.value) {
if (kw.value) getList(); getList();
else { isNoSearch.value = false;
nextTick(() => {
const preLoader = document.getElementById("pre-loader");
if (preLoader) preLoader.style.display = "none";
});
} else {
page.value = null; page.value = null;
isEmptySearch.value = true; isEmptySearch.value = true;
getRecommendList();
} }
getUserInfoWin(); getUserInfoWin();
window.addEventListener("scroll", handleScroll); window.addEventListener("scroll", handleScroll);
const preLoader = document.getElementById("pre-loader"); getTagList();
if (preLoader) preLoader.style.display = "none"; getSearchList();
document.querySelectorAll(".vuehide").forEach((item) => (item.style.display = "none"));
window.addEventListener("popstate", () => {
const urlObj = new URL(location.href);
const pathParts = urlObj.pathname.split("/").filter((part) => part);
const keyword = pathParts[1] ? decodeURIComponent(pathParts[1]) : ""; // /search/keyword...
if (keyword) {
kw.value = keyword;
page.value = 1;
list.value = [];
getList(true);
} else {
kw.value = "";
page.value = null;
isNoSearch.value = true;
getRecommendList();
nextTick(() => {
document.querySelectorAll(".vuehide").forEach((item) => (item.style.display = "none"));
});
}
});
}); });
let isLogin = ref(false); let isLogin = ref(false);
@@ -50,6 +82,8 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
let permissions = ref([]); let permissions = ref([]);
let isme = ref(false);
const getUserInfoWin = () => { const getUserInfoWin = () => {
const checkUser = () => { const checkUser = () => {
const user = window.userInfoWin; const user = window.userInfoWin;
@@ -59,6 +93,8 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
userInfoWin.value = user; userInfoWin.value = user;
if (user?.uin > 0 || user?.uid > 0) isLogin.value = true; if (user?.uin > 0 || user?.uid > 0) isLogin.value = true;
permissions.value = user?.authority || []; permissions.value = user?.authority || [];
// if (user.uid == 500144) isme.value = true;
}; };
document.addEventListener("getUser", checkUser); document.addEventListener("getUser", checkUser);
}; };
@@ -101,6 +137,12 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
getList(); getList();
}; };
const fetchPageData = (pathname) => {
console.log("pathname", pathname);
const lastSegment = pathname.split("/").filter(Boolean).pop() || "index";
console.log("当前路径:", pathname, ",最后一段:", lastSegment);
};
let tabList = ref({ let tabList = ref({
all: "全部", all: "全部",
thread: "论坛", thread: "论坛",
@@ -131,13 +173,16 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
let total = ref(0); let total = ref(0);
let list = ref([]); let list = ref([]);
let pagination = ref([]); let pagination = ref([]);
const getList = () => { const getList = (isHistoryBack = false) => {
if (loading.value || page.value == null) return; if (loading.value || page.value == null) return;
isNoSearch.value = false;
loading.value = true; loading.value = true;
isEmptySearch.value = false; isEmptySearch.value = false;
const limit = 20; const limit = 20;
window.scrollTo(0, 0); window.scrollTo(0, 0);
// updateUrlParams({ page: page.value }); if (!isHistoryBack) updateUrlParams({ page: page.value });
let postHead = null; let postHead = null;
@@ -170,7 +215,8 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
loading.value = false; loading.value = false;
maxPage.value = Math.ceil(count.value / limit); maxPage.value = Math.ceil(count.value / limit);
pagination.value = calculatePagination(page.value, maxPage.value); pagination.value = calculatePagination(page.value, maxPage.value);
// updateUrlLastPath(`/search/${kw.value}`);
if (location.hostname != '127.0.0.1') updateUrlLastPath(`/search/${kw.value}`, true);
removeQueryQ(); removeQueryQ();
}) })
.catch((err) => { .catch((err) => {
@@ -242,7 +288,8 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
getList(); getList();
}; };
const startSearch = () => { const startSearch = (value) => {
if (value) kw.value = value;
if (kw.value == "") { if (kw.value == "") {
creationAlertBox("error", "请输入搜索关键词"); creationAlertBox("error", "请输入搜索关键词");
return; return;
@@ -260,8 +307,8 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
const matterBottom = ref(false); const matterBottom = ref(false);
const handleScroll = () => { const handleScroll = () => {
matterHeight.value = -(matterContentRef.value.offsetHeight - window.innerHeight); matterHeight.value = -(matterContentRef.value?.offsetHeight - window.innerHeight);
sidebarHeight.value = -(sidebarRef.value.offsetHeight - window.innerHeight); sidebarHeight.value = -(sidebarRef.value?.offsetHeight - window.innerHeight);
if (matterHeight.value > 0) matterHeight.value = 12; if (matterHeight.value > 0) matterHeight.value = 12;
if (sidebarHeight.value > 0) sidebarHeight.value = 12; if (sidebarHeight.value > 0) sidebarHeight.value = 12;
}; };
@@ -275,7 +322,37 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provi
let isEmptySearch = ref(false); let isEmptySearch = ref(false);
return { isEmptySearch, total, matterHeight, sidebarHeight, matterBottom, matterFixed, matterContentRef, sidebarFixed, matterRef, sidebarRef, loading, typeValue, kwValue, startSearch, kw, maxPage, prevPage, nextPage, tabValue, cutTab, tabList, count, list, page, pagination, cutPage }; let tagList = ref([]);
const getTagList = () => {
ajaxGet("/v2/api/forum/getHotTags?limit=20").then((res) => {
const data = res.data;
tagList.value = data || [];
});
};
let placeholder = ref("");
let searchList = ref([]);
const getSearchList = () => {
ajaxGet("/v2/api/forum/getHotSearchWords?limit=20").then((res) => {
const data = res.data || [];
searchList.value = data;
if (data.length) placeholder.value = data[Math.floor(Math.random() * data.length)].keyword || "";
});
};
let isNoSearch = ref(true);
let recommendList = ref([]);
// 推荐阅读
const getRecommendList = () => {
if (recommendList.value?.length != 0) return;
ajaxGet("/v2/api/forum/getRecommendRead").then((res) => {
const data = res.data || [];
recommendList.value = data || [];
});
};
return { placeholder, recommendList, isNoSearch, searchList, tagList, isme, isEmptySearch, total, matterHeight, sidebarHeight, matterBottom, matterFixed, matterContentRef, sidebarFixed, matterRef, sidebarRef, loading, typeValue, kwValue, startSearch, kw, maxPage, prevPage, nextPage, tabValue, cutTab, tabList, count, list, page, pagination, cutPage };
}, },
}); });
appSearch.component("item-forum", itemForum); appSearch.component("item-forum", itemForum);

View File

@@ -5,22 +5,23 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>搜索结果 - 澳门大学 - 寄托天下 -- 寄托天下</title> <title>搜索结果 - - 寄托天下 -- 寄托天下</title>
<link rel="stylesheet" href="https://framework.x-php.com/gter/forum/css/public.css?v=vDmK98808ObK" /> <link rel="stylesheet" href="/css/public.css?v=uj0T1euj8ufe" />
<link rel="stylesheet" href="/css/search.css" /> <link rel="stylesheet" href="/css/search.css?v=uj0T1euj8ufe" />
<!-- <link rel="stylesheet" href="https://f.gter.net/css/search.css" /> -->
<meta name="description" content="在寄托天下留学论坛上搜索澳门大学, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。"> <meta name="description" content="在寄托天下留学论坛上搜索, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。">
<meta name="keywords" content="澳门大学, 寄托天下, 留学论坛"> <meta name="keywords" content=", 寄托天下, 留学论坛">
<meta name="author" content=""> <meta name="author" content="">
<!-- Open Graph / Facebook --> <!-- Open Graph / Facebook -->
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:title" content="搜索结果 - 澳门大学 - 寄托天下"> <meta property="og:title" content="搜索结果 - - 寄托天下">
<meta property="og:description" content="在寄托天下留学论坛上搜索澳门大学, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。"> <meta property="og:description" content="在寄托天下留学论坛上搜索, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。">
<meta property="og:image" content=""> <meta property="og:image" content="">
<!-- Twitter --> <!-- Twitter -->
<meta property="twitter:card" content="summary_large_image"> <meta property="twitter:card" content="summary_large_image">
<meta property="twitter:title" content="搜索结果 - 澳门大学 - 寄托天下"> <meta property="twitter:title" content="搜索结果 - - 寄托天下">
<meta property="twitter:description" content="在寄托天下留学论坛上搜索澳门大学, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。"> <meta property="twitter:description" content="在寄托天下留学论坛上搜索, 分享留学经验, 咨询签证, 面试, 机经, offer, 奖学金, 名校专业等。">
<meta property="twitter:image" content=""> <meta property="twitter:image" content="">
<!-- 网站图标 --> <!-- 网站图标 -->
<link rel="icon" href="https://www.gter.net/favicon.ico" type="image/x-icon"> <link rel="icon" href="https://www.gter.net/favicon.ico" type="image/x-icon">
@@ -114,7 +115,7 @@
<div class="placeholder-box" style="transition: transform .3s ease"></div> <div class="placeholder-box" style="transition: transform .3s ease"></div>
</div> </div>
<input class="input flex1" type="text" maxlength="140" /> <img class="icon" onclick="searchEvent()" src="https://framework.x-php.com/gter/forum/img/search-icon.svg?v=vDmK98808ObK" /> <input class="input flex1" type="text" maxlength="140" /> <img class="icon" onclick="searchEvent()" src="https://framework.x-php.com/gter/forum/img/search-icon.svg?v=uj0T1euj8ufe" />
<div class="search-box-history"> <div class="search-box-history">
<div class="search-box-history-title">历史搜索</div> <div class="search-box-history-title">历史搜索</div>
<div class="search-box-history-list"></div> <div class="search-box-history-list"></div>
@@ -126,7 +127,7 @@
<div class="sign-in sign-in-no flexacenter"></div> <div class="sign-in sign-in-no flexacenter"></div>
<div class="head-more flexcenter" onclick="openHeadPop()"> <div class="head-more flexcenter" onclick="openHeadPop()">
<img class="more-icon" style="width: 18px;height: 15px;" src="https://framework.x-php.com/gter/forum/img/threeAcross.svg?v=vDmK98808ObK" /> <img class="more-icon" style="width: 18px;height: 15px;" src="https://framework.x-php.com/gter/forum/img/threeAcross.svg?v=uj0T1euj8ufe" />
</div> </div>
<div class="head-pop" style="display: none;"> <div class="head-pop" style="display: none;">
@@ -141,9 +142,9 @@
</div> </div>
<div class="tab-list"><a class="tab-item flexacenter" href="https://www.gter.net" target="_blank">寄托首页</a><a class="tab-item flexacenter pitch" href="https://f.gter.net" target="_blank">论坛</a><a class="tab-item flexacenter" href="https://app.gter.net/admissionOfficer" target="_blank">招生官</a><a class="tab-item flexacenter" href="https://bbs.gter.net/thread-2345065-1-1.html" target="_blank">加群</a><a class="tab-item flexacenter" href="https://offer.gter.net" target="_blank">Offer榜</a></div> <div class="tab-list"><a class="tab-item flexacenter" href="https://www.gter.net" target="_blank">寄托首页</a><a class="tab-item flexacenter pitch" href="https://f.gter.net" target="_blank">论坛</a><a class="tab-item flexacenter" href="https://app.gter.net/admissionOfficer" target="_blank">招生官</a><a class="tab-item flexacenter" href="https://bbs.gter.net/thread-2345065-1-1.html" target="_blank">加群</a><a class="tab-item flexacenter" href="https://offer.gter.net" target="_blank">Offer榜</a></div>
<a class="head-more-post flexcenter" href="/publish" target="" onclick="skipLoginUrl(event)"> <a class="head-more-post flexcenter" href="/publish" target="" onclick="skipLoginUrl(event)">
<div class="head-more-post-icon flexcenter"><img class="head-more-post-img" src="https://framework.x-php.com/gter/forum/img/addyellow.svg?v=vDmK98808ObK" /></div>发布帖子 <div class="head-more-post-icon flexcenter"><img class="head-more-post-img" src="https://framework.x-php.com/gter/forum/img/addyellow.svg?v=uj0T1euj8ufe" /></div>发布帖子
</a> </a>
<img class="cross-icon" onclick="crossHeadPop()" src="https://framework.x-php.com/gter/forum/img/cross.svg?v=vDmK98808ObK"> <img class="cross-icon" onclick="crossHeadPop()" src="https://framework.x-php.com/gter/forum/img/cross.svg?v=uj0T1euj8ufe">
</div> </div>
</div> </div>
</div> </div>
@@ -153,22 +154,61 @@
<div class="container" id="search"> <div class="container" id="search">
<div class="templateValue" ref="kwValue">澳门大学</div> <div class="templateValue" ref="kwValue"></div>
<div class="templateValue" ref="typeValue"></div> <div class="templateValue" ref="typeValue"></div>
<div v-if="isNoSearch" class="search-no" style="min-height: 50vh;">
<img class="earth-icon flexflex" src="/img/earth-icon.png">
<div class="input-box flexacenter">
<input class="input flex1 vuehide" placeholder="请输入关键词" v-model="kw" @keyup.enter="startSearch(kw ? '' : placeholder)">
<input v-cloak class="input flex1" :placeholder="placeholder" v-model="kw" @keyup.enter="startSearch(kw ? '' : placeholder)">
<div class="btn" @click="startSearch(kw ? '' : placeholder)">搜索</div>
</div>
<template v-if="!isNoSearch"> <div class="recommend-box flexflex" v-cloak>
<div class="search-no"> <div class="hot-box" v-if="searchList.length != 0">
<img class="earth-icon flexflex" src="/img/earth-icon.png"> <div class="recommend-head flexacenter">
<div class="input-box"> <img class="icon" src="/img/triangle-violet.svg">
<input class="flex1" placeholder="港中大 双学位"> 热门搜索
<div class="btn">搜索</div> </div>
<div class="hot-list flexflex">
<div class="item" v-for="item in searchList" @click="startSearch(item.keyword)">{{ item.keyword }}</div>
</div>
</div>
<div class="hot-box" v-if="tagList.length != 0">
<div class="recommend-head flexacenter">
<img class="icon" src="/img/triangle-yellow.svg">
热门标签
</div>
<div class="hot-list flexflex">
<a class="item flexacenter" href="/recommend" target="_blank">
<img class="icon" src="/img/recommend-head-icon.png">
编辑推荐
</a>
<a class="item flexacenter" href="/best" target="_blank">
<img class="icon" src="/img/essence-head-icon.png">
精华帖
</a>
<a class="item" v-for="item in tagList" :href="'/tag/' + item.tagname" target="_blank">{{ item.tagname }}</a>
</div>
</div>
<div class="read-box" v-if="recommendList.length != 0">
<div class="recommend-head flexacenter">
<img class="icon" src="/img/triangle-blue.svg">
推荐阅读
</div>
<div class="read-list">
<a class="item flexacenter" v-for="item in recommendList" target="_blank" :href="'/details/' + item.uniqid ">
<div class="dot"></div>
<div class="text flex1 one-line-display">{{ item.title }}</div>
</a>
</div>
</div> </div>
</div> </div>
</template> </div>
<template v-else> <template v-else>
<div class="search-box flexacenter"> <div class="search-box flexacenter">
<input class="search-input flex1" placeholder="请输入搜索关键词" v-model="kw" @keyup.enter="startSearch" /> <input class="search-input flex1" placeholder="请输入搜索关键词" v-model="kw" @keyup.enter="startSearch()" />
<img class="search-icon" src="https://framework.x-php.com/gter/forum/img/search-icon.svg?v=vDmK98808ObK" alt="" @click="startSearch" /> <img class="search-icon" src="https://framework.x-php.com/gter/forum/img/search-icon.svg?v=uj0T1euj8ufe" alt="" @click="startSearch()" />
</div> </div>
<template v-if="!isEmptySearch"> <template v-if="!isEmptySearch">
<div class="classify flexacenter"> <div class="classify flexacenter">
@@ -183,16 +223,16 @@
</div> </div>
</template> </template>
<div id="pre-loader"> <!-- <div id="pre-loader">
<div class="three-bounce" p-id="11"> <div class="three-bounce" p-id="11">
<div class="one" p-id="12"></div> <div class="one" p-id="12"></div>
<div class="two" p-id="13"></div> <div class="two" p-id="13"></div>
<div class="three" p-id="14"></div> <div class="three" p-id="14"></div>
</div>
</div> </div>
</div> -->
<div class="matter flexflex" ref="matterRef" v-cloak> <div class="matter flexflex" ref="matterRef" v-cloak>
<div class="matter-content flex1" ref="matterContentRef" :style="{'top': matterHeight + 'px'}"> <div class="matter-content flex1" ref="matterContentRef" :style="{'top': matterHeight + 'px'}">
<div class="list-box" v-if="list.length != 0"> <div class="list-box" v-if="list.length != 0">
<template v-for="(item,index) in list" :key="index"> <template v-for="(item,index) in list" :key="index">
<item-offer v-if=" item.type == 'offer'" :itemdata="item"></item-offer> <item-offer v-if=" item.type == 'offer'" :itemdata="item"></item-offer>
@@ -208,24 +248,34 @@
<load-box :loading="loading"></load-box> <load-box :loading="loading"></load-box>
<div v-if="list.length == 0 && page == null" class="empty flexcenter"> <div v-if="list.length == 0 && page == null" class="empty flexcenter">
<img class="empty-icon" src="https://framework.x-php.com/gter/forum/img/empty-icon.png?v=vDmK98808ObK" /> <img class="empty-icon" src="https://framework.x-php.com/gter/forum/img/empty-icon.png?v=uj0T1euj8ufe" />
<div class="empty-text">{{ kw ? '- 暂无内容 -' : '- 请输入搜索关键词 -' }}</div> <div class="empty-text">{{ kw ? '- 暂无内容 -' : '- 请输入搜索关键词 -' }}</div>
</div> </div>
<div class="pages-box flexcenter" v-if="pagination.length != 0"> <div class="pages-box flexcenter" v-if="pagination.length != 0">
<img v-if="page == 1" class="arrows" src="https://framework.x-php.com/gter/forum/img/arrows-gray-simple.svg?v=vDmK98808ObK" alt="" /> <img v-if="page == 1" class="arrows" src="https://framework.x-php.com/gter/forum/img/arrows-gray-simple.svg?v=uj0T1euj8ufe" alt="" />
<img @click="prevPage" v-else class="arrows rotate180" src="https://framework.x-php.com/gter/forum/img/arrows-gray-deep.svg?v=vDmK98808ObK" alt="" /> <img @click="prevPage" v-else class="arrows rotate180" src="https://framework.x-php.com/gter/forum/img/arrows-gray-deep.svg?v=uj0T1euj8ufe" alt="" />
<div class="item" :class="{'pitch': item == page }" v-for="(item, index) in pagination" @click="cutPage(item)">{{ item }}</div> <div class="item" :class="{'pitch': item == page }" v-for="(item, index) in pagination" @click="cutPage(item)">{{ item }}</div>
<img v-if="page == maxPage" class="arrows rotate180" src="https://framework.x-php.com/gter/forum/img/arrows-gray-simple.svg?v=vDmK98808ObK" alt="" /> <img v-if="page == maxPage" class="arrows rotate180" src="https://framework.x-php.com/gter/forum/img/arrows-gray-simple.svg?v=uj0T1euj8ufe" alt="" />
<img @click="nextPage" v-else v-else class="arrows" src="https://framework.x-php.com/gter/forum/img/arrows-gray-deep.svg?v=vDmK98808ObK" alt="" /> <img @click="nextPage" v-else v-else class="arrows" src="https://framework.x-php.com/gter/forum/img/arrows-gray-deep.svg?v=uj0T1euj8ufe" alt="" />
</div> </div>
</div> </div>
<div class="sidebar-box" ref="sidebarRef" :style="{'top': sidebarHeight + 'px'}"> <div class="sidebar-box" ref="sidebarRef" :style="{'top': sidebarHeight + 'px'}">
<hot-search></hot-search> <div class="recommend-and-essence flexacenter">
<hot-tag></hot-tag> <a class="item flexcenter" target="_blank" href="/recommend">
<img class="icon" src="/img/recommend-head-icon.png" />
<div class="text">编辑推荐</div>
</a>
<a class="item flexcenter" target="_blank" href="/best">
<img class="icon" src="/img/essence-head-icon.png" />
<div class="text">精华帖</div>
</a>
</div>
<hot-search :isNoRequestData="true" :searchlist="searchList"></hot-search>
<hot-tag :isNoRequestData="true" :taglist="tagList"></hot-tag>
<slideshow-box></slideshow-box> <slideshow-box></slideshow-box>
<latest-list></latest-list> <latest-list></latest-list>
</div> </div>
@@ -234,13 +284,13 @@
</div> </div>
<script src="https://framework.x-php.com/gter/forum/js/vue.global.js?v=vDmK98808ObK"></script> <script src="https://framework.x-php.com/gter/forum/js/vue.global.js?v=uj0T1euj8ufe"></script>
<script src="https://framework.x-php.com/gter/forum/js/axios.min.js?v=vDmK98808ObK"></script> <script src="https://framework.x-php.com/gter/forum/js/axios.min.js?v=uj0T1euj8ufe"></script>
<script src="https://framework.x-php.com/gter/forum/js/public.js?v=vDmK98808ObK"></script> <script src="https://framework.x-php.com/gter/forum/js/public.js?v=uj0T1euj8ufe"></script>
<!-- <script src="https://f.gter.net/js/public.js"></script> --> <!-- <script src="https://f.gter.net/js/public.js"></script> -->
<script type="module" src="/js/search.js?v=vDmK98808ObK"></script> <!-- <script type="module" src="https://framework.x-php.com/gter/forum/js/search.js?v=uj0T1euj8ufe"></script> -->
<!-- <script type="module" src="https://f.gter.net/js/search.js"></script> --> <script type="module" src="/js/search.js"></script>
<script src="https://app.gter.net/bottom?tpl=footer,popupnotification"></script> <script src="https://app.gter.net/bottom?tpl=footer,popupnotification"></script>
@@ -250,7 +300,7 @@
if (location.href.indexOf('details') != -1) { if (location.href.indexOf('details') != -1) {
const postList = document.querySelector('.head-top .post-list') const postList = document.querySelector('.head-top .post-list')
postList.innerHTML = `<a href="/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-thread.png?v=vDmK98808ObK" /> </a> <a href="https://offer.gter.net/post" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-offer.png?v=vDmK98808ObK" /> </a> <a href="https://offer.gter.net/post/summary" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-summary.png?v=vDmK98808ObK" /> </a> <a href="https://interviewexperience.gter.net/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-mj.png?v=vDmK98808ObK" /> </a> <a href="https://vote.gter.net/publish" target="_blank"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-vote.png?v=vDmK98808ObK" /> </a>` postList.innerHTML = `<a href="/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-thread.png?v=uj0T1euj8ufe" /> </a> <a href="https://offer.gter.net/post" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-offer.png?v=uj0T1euj8ufe" /> </a> <a href="https://offer.gter.net/post/summary" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-summary.png?v=uj0T1euj8ufe" /> </a> <a href="https://interviewexperience.gter.net/publish" target="_blank" style="margin-right: 10px"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-mj.png?v=uj0T1euj8ufe" /> </a> <a href="https://vote.gter.net/publish" target="_blank"> <img class="post-item" src="https://framework.x-php.com/gter/forum/img/post-vote.png?v=uj0T1euj8ufe" /> </a>`
console.log(postList); console.log(postList);
postList.style.display = 'flex' postList.style.display = 'flex'
} else if (location.href.indexOf('search') != -1) { } else if (location.href.indexOf('search') != -1) {
@@ -263,17 +313,17 @@
} else { } else {
const signIn = document.querySelector('.head-top .sign-in') const signIn = document.querySelector('.head-top .sign-in')
signIn.innerHTML = `<div class="sign-in-no-box" onclick="headSignIn()"> signIn.innerHTML = `<div class="sign-in-no-box" onclick="headSignIn()">
<img class="sign-in-bj" src="https://framework.x-php.com/gter/forum/img/sign-in-bj.svg?v=vDmK98808ObK" /><img class="coin-bj" src="https://framework.x-php.com/gter/forum/img/coin-bj.svg?v=vDmK98808ObK" /> <img class="sign-in-bj" src="https://framework.x-php.com/gter/forum/img/sign-in-bj.svg?v=uj0T1euj8ufe" /><img class="coin-bj" src="https://framework.x-php.com/gter/forum/img/coin-bj.svg?v=uj0T1euj8ufe" />
<img class="coin-icon" src="https://framework.x-php.com/gter/forum/img/coin-icon.png?v=vDmK98808ObK" /><span class="text flex1">签到领寄托币</span> <img class="coin-icon" src="https://framework.x-php.com/gter/forum/img/coin-icon.png?v=uj0T1euj8ufe" /><span class="text flex1">签到领寄托币</span>
<div class="sign-go flexcenter"> <div class="sign-go flexcenter">
<img class="sign-go-bj" src="https://framework.x-php.com/gter/forum/img/sign-go.svg?v=vDmK98808ObK" /> GO <img class="sign-go-bj" src="https://framework.x-php.com/gter/forum/img/sign-go.svg?v=uj0T1euj8ufe" /> GO
</div> </div>
<img class="petal1" src="https://framework.x-php.com/gter/forum/img/petal1.png?v=vDmK98808ObK" /> <img class="petal1" src="https://framework.x-php.com/gter/forum/img/petal1.png?v=uj0T1euj8ufe" />
<img class="petal2" src="https://framework.x-php.com/gter/forum/img/petal2.png?v=vDmK98808ObK" /> <img class="petal2" src="https://framework.x-php.com/gter/forum/img/petal2.png?v=uj0T1euj8ufe" />
<img class="petal3" src="https://framework.x-php.com/gter/forum/img/petal3.png?v=vDmK98808ObK" /> <img class="petal3" src="https://framework.x-php.com/gter/forum/img/petal3.png?v=uj0T1euj8ufe" />
</div> </div>
<div class="sign-in-already-box"> <div class="sign-in-already-box">
<img class="sign-icon" src="https://framework.x-php.com/gter/forum/img/sign-icon.png?v=vDmK98808ObK" /> <img class="sign-icon" src="https://framework.x-php.com/gter/forum/img/sign-icon.png?v=uj0T1euj8ufe" />
<span>已签到,明天再来</span> <span>已签到,明天再来</span>
</div>` </div>`
signIn.style.display = 'flex' signIn.style.display = 'flex'