diff --git a/.vscode/settings.json b/.vscode/settings.json index 6f3a291..f673a71 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "liveServer.settings.port": 5501 + "liveServer.settings.port": 5502 } \ No newline at end of file diff --git a/best.html b/best.html new file mode 100644 index 0000000..47848a9 --- /dev/null +++ b/best.html @@ -0,0 +1,489 @@ + + + + + + + + 精华主题 - 寄托天下 -- 寄托天下 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+
+
+
+ + +
+
历史搜索
+
+
+
+ +
+ +
+ +
+ +
+ + +
+ + + + +
+
+
+ + + +
+ +
精华帖
+
+ +
+
{{ item }}
+
+ +
+
+
+
+
+
+
+ +
+
+
+ {{ tabList[tabValue] }} +
+ 共 +
{{ count }}
+ 条 + +
+
+
{{ currentSortText }}
+ +
+ +
+
+
按综合排序
+
按最新发布排序
+
+
+
+
+ +
+ + + +
+ +
- 暂无内容 -
+
+ +
+ + + +
{{ item }}
+ + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/component/helper-pop/helper-pop.js b/component/helper-pop/helper-pop.js new file mode 100644 index 0000000..3292e3f --- /dev/null +++ b/component/helper-pop/helper-pop.js @@ -0,0 +1,30 @@ +// my-component.js +// 引入全局 Vue 对象(因在 HTML 中通过 script 引入,Vue 已挂载到 window) +const { defineComponent, ref, inject, defineAsyncComponent, onMounted } = Vue; + +// 定义组件(直接使用模板) +export const helperPop = defineComponent({ + name: "item-bottom", + props: {}, + + setup(props) { + let isMobile = ref(false); + + let state = ref(false); + + onMounted(() => { + isMobile.value = window.isMobile; + }); + + const open = () => (state.value = true); + const closeGroup = () => (state.value = false); + + const holdback = () => {}; + + return { state, isMobile, holdback, closeGroup, open }; + }, + + components: {}, + + template: `
长按识别二维码
`, +}); diff --git a/component/helper-pop/helper-pop.txt b/component/helper-pop/helper-pop.txt new file mode 100644 index 0000000..32de937 --- /dev/null +++ b/component/helper-pop/helper-pop.txt @@ -0,0 +1,18 @@ +
+
+ + +
+
+ + + + + +
+ 长按识别二维码 +
+ + +
+
\ No newline at end of file diff --git a/component/huddle-box/huddle-box.js b/component/huddle-box/huddle-box.js new file mode 100644 index 0000000..1dbefb3 --- /dev/null +++ b/component/huddle-box/huddle-box.js @@ -0,0 +1,30 @@ +// my-component.js +// 引入全局 Vue 对象(因在 HTML 中通过 script 引入,Vue 已挂载到 window) +const { defineComponent, ref, inject, defineAsyncComponent, onMounted } = Vue; + +// 定义组件(直接使用模板) +export const huddleBox = defineComponent({ + name: "item-bottom", + props: {}, + + setup(props) { + let isMobile = ref(false); + + let state = ref(false); + + onMounted(() => { + isMobile.value = window.isMobile; + }); + + const open = () => (state.value = true); + const closeGroup = () => (state.value = false); + + const holdback = () => {}; + + return { state, isMobile, holdback, closeGroup, open }; + }, + + components: {}, + + template: `
抱团 / 信息共享 / 互助申学
添加寄托葱哥进群
`, +}); diff --git a/component/huddle-box/huddle-box.txt b/component/huddle-box/huddle-box.txt new file mode 100644 index 0000000..544722a --- /dev/null +++ b/component/huddle-box/huddle-box.txt @@ -0,0 +1,19 @@ +
+
+ + + + +
抱团 / 信息共享 / 互助申学
+
+
+ +
+
+ + 添加寄托葱哥进群 + +
+
+
+
\ No newline at end of file diff --git a/component/item-mj/item-mj.js b/component/item-mj/item-mj.js index 99d0363..ad71746 100644 --- a/component/item-mj/item-mj.js +++ b/component/item-mj/item-mj.js @@ -5,7 +5,7 @@ const { defineComponent, ref, defineAsyncComponent } = Vue; // const { itemBottom } = await import(withVer("../item-bottom/item-bottom.js")); // const { itemHead } = await import(withVer("../item-head/item-head.js")); const itemHead = defineAsyncComponent(() => import(withVer("../item-head/item-head.js")).then((m) => m.itemHead)); -const itemBottom = defineAsyncComponent(() => import(withVer("../item-bottom/item-bottom.js")).then((m) => m.itemHead)); +const itemBottom = defineAsyncComponent(() => import(withVer("../item-bottom/item-bottom.js")).then((m) => m.itemBottom)); // 定义组件(直接使用模板) export const itemMj = defineComponent({ diff --git a/css/public.css b/css/public.css index e192590..fd64180 100644 --- a/css/public.css +++ b/css/public.css @@ -57,7 +57,6 @@ body { border-radius: 10px; padding: 18px 20px 0; display: block; - overflow: hidden; } .item-box .item-head { margin-bottom: 14px; @@ -2184,3 +2183,342 @@ td { padding: 0 5px; } } +.huddle-box { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.70588235); + display: flex; + align-items: flex-end; + justify-content: center; + overflow: hidden; + animation: slidebj 0.5s forwards; + z-index: 10002; +} +.huddle-box .box { + width: 100vw; + height: 719px; + border-radius: 20px 20px 0 0; + box-shadow: 0 0 15px rgba(0, 0, 0, 0.10196078); + animation: slideUp 0.5s forwards; + background: linear-gradient(0.0796881deg, #c1a75a 0%, #15a3dc 100%); + position: relative; + flex-direction: column; + align-items: center; + padding-top: 32px; + z-index: 1; +} +.huddle-box .box .code { + width: 100vw; +} +.huddle-box .box .bj { + width: 100vw; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + z-index: -1; +} +.huddle-box .box .bj-bottom { + width: 126px; + height: 134px; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); +} +.huddle-box .box .top { + width: 199px; + height: 36px; + margin-bottom: 13px; +} +.huddle-box .box .title { + width: 311px; + height: 86px; + margin-bottom: 4px; +} +.huddle-box .box .text { + font-family: "PingFangSC-Regular", "PingFang SC", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 20px; + color: #ffffff; + text-align: center; + line-height: 30px; + margin-bottom: 25px; +} +.huddle-box .box .case { + width: 360px; + height: 400px; + background: linear-gradient(180deg, #f2f2f2 0%, #ebebeb 100%); + border-radius: 15px; + flex-direction: column; + align-items: center; + padding-top: 50px; + margin: 0 auto; +} +.huddle-box .box .case .QRcode { + width: 240px; + height: 240px; + background-color: #ffffff; + border-color: #f2f2f2; + border-radius: 10px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.18431373); + margin-bottom: 26px; +} +.huddle-box .box .case .QRcode .img { + width: 218px; + height: 218px; +} +.huddle-box .box .case .hint .img { + width: 32px; + height: 32px; +} +.huddle-box .box .case .hint .img.img-left { + transform: rotate(180deg); +} +.huddle-box .box .case .hint .hint-text { + font-size: 18px; + color: #000000; + text-align: center; + line-height: 28px; + margin: 0 15px; +} +@media screen and (max-width: 600px) { + .huddle-box .box { + width: 100vw; + height: calc(719 / 600 * 100vw); + padding-top: calc(32 / 600 * 100vw); + box-shadow: 0 0 calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.10196078); + animation-name: slideUp; + } + .huddle-box .box .code { + width: 100vw; + } + .huddle-box .box .bj-bottom { + width: calc(126 / 600 * 100vw); + height: calc(134 / 600 * 100vw); + } + .huddle-box .box .top { + width: calc(199 / 600 * 100vw); + height: calc(36 / 600 * 100vw); + margin-bottom: calc(13 / 600 * 100vw); + } + .huddle-box .box .title { + width: calc(311 / 600 * 100vw); + height: calc(86 / 600 * 100vw); + margin-bottom: calc(4 / 600 * 100vw); + } + .huddle-box .box .text { + font-size: calc(20 / 600 * 100vw); + line-height: calc(30 / 600 * 100vw); + margin-bottom: calc(25 / 600 * 100vw); + } + .huddle-box .box .case { + width: calc(360 / 600 * 100vw); + height: calc(400 / 600 * 100vw); + padding-top: calc(50 / 600 * 100vw); + border-radius: calc(15 / 600 * 100vw); + } + .huddle-box .box .case .QRcode { + width: calc(240 / 600 * 100vw); + height: calc(240 / 600 * 100vw); + margin-bottom: calc(26 / 600 * 100vw); + border-radius: calc(10 / 600 * 100vw); + box-shadow: 0 0 calc(5 / 600 * 100vw) rgba(0, 0, 0, 0.18431373); + } + .huddle-box .box .case .QRcode .img { + width: calc(218 / 600 * 100vw); + height: calc(218 / 600 * 100vw); + } + .huddle-box .box .case .hint .img { + width: calc(32 / 600 * 100vw); + height: calc(32 / 600 * 100vw); + } + .huddle-box .box .case .hint .hint-text { + font-size: calc(18 / 600 * 100vw); + line-height: calc(28 / 600 * 100vw); + margin: 0 calc(15 / 600 * 100vw); + } +} +@keyframes slidebj { + 0% { + background-color: rgba(0, 0, 0, 0); + } + 100% { + background-color: rgba(0, 0, 0, 0.71764706); + } +} +.helper-pop { + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.71764706); + position: fixed; + top: 0; + left: 0; + z-index: 1004; + align-items: flex-end; + box-sizing: border-box; + animation: slidebj 0.5s forwards; + display: flex; + justify-content: center; + overflow: hidden; +} +.helper-pop .helper-box { + animation: slideUp 0.5s forwards; + box-sizing: border-box; + flex-direction: column; + width: 100vw; + background: linear-gradient(179.80708565deg, #c1cefa 0%, #e2edfb 28%, #ffffff 60%); + border: none; + border-radius: 20px; + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.10196078); + position: relative; + padding-top: 59px; + display: flex; + align-items: center; +} +.helper-pop .helper-box .cross-grey { + width: 16px; + height: 16px; + position: absolute; + top: 13px; + right: 13px; + padding: 7px; + cursor: pointer; +} +.helper-pop .helper-box .helper-text { + box-sizing: border-box; + height: 103px; + margin: 0 auto 24px; +} +.helper-pop .helper-box .helper-box-box { + box-sizing: border-box; + width: 280px; + background: linear-gradient(139.427577deg, #6589f2 0%, #74b1f0 100%); + border: none; + border-radius: 20px; + box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.17647059); + flex-direction: column; + align-items: center; + padding: 20px 0; + z-index: 1; + margin-bottom: 80px; + display: flex; +} +.helper-pop .helper-box .helper-box-box .helper-box-text { + box-sizing: border-box; + font-size: 16px; + color: #ffffff; + text-align: center; + line-height: 28px; + margin-top: 20px; +} +.helper-pop .helper-box .helper-QRcode-box { + box-sizing: border-box; + width: 240px; + height: 240px; + background-color: #ffffff; + border-radius: 6px; + position: relative; + display: flex; + justify-content: center; + align-items: center; +} +.helper-pop .helper-box .helper-QRcode-box .helper-QRcode-box-icon { + width: 24px; + height: 24px; + position: absolute; +} +.helper-pop .helper-box .helper-QRcode-box .left-top { + top: 0; + left: 0; + transform: rotate(-90deg); +} +.helper-pop .helper-box .helper-QRcode-box .left-bottom { + bottom: 0; + left: 0; + transform: rotate(180deg); +} +.helper-pop .helper-box .helper-QRcode-box .right-top { + right: 0; + top: 0; +} +.helper-pop .helper-box .helper-QRcode-box .right-bottom { + right: 0; + bottom: 0; + transform: rotate(90deg); +} +.helper-pop .helper-box .helper-QRcode-box .helper-QRcode-img { + width: 220px; + height: 220px; + box-sizing: border-box; +} +.helper-pop .helper-box .helper-bottom { + position: absolute; + bottom: 0; + left: 0; + width: 100vw; + height: 151px; +} +@media screen and (max-width: 600px) { + .helper-pop .helper-box { + width: 100vw; + padding-top: calc(59 / 600 * 100vw); + border-radius: calc(20 / 600 * 100vw); + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + box-shadow: 0px 0px calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.10196078); + } + .helper-pop .helper-box .cross-grey { + width: calc(16 / 600 * 100vw); + height: calc(16 / 600 * 100vw); + top: calc(13 / 600 * 100vw); + right: calc(13 / 600 * 100vw); + padding: calc(7 / 600 * 100vw); + } + .helper-pop .helper-box .helper-text { + height: calc(103 / 600 * 100vw); + margin: 0 auto calc(24 / 600 * 100vw); + } + .helper-pop .helper-box .helper-box-box { + width: calc(280 / 600 * 100vw); + border-radius: calc(20 / 600 * 100vw); + box-shadow: 0px 0px calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.17647059); + padding: calc(20 / 600 * 100vw) 0; + margin-bottom: calc(80 / 600 * 100vw); + } + .helper-pop .helper-box .helper-box-box .helper-box-text { + font-size: calc(16 / 600 * 100vw); + line-height: calc(28 / 600 * 100vw); + margin-top: calc(20 / 600 * 100vw); + } + .helper-pop .helper-box .helper-QRcode-box { + width: calc(240 / 600 * 100vw); + height: calc(240 / 600 * 100vw); + border-radius: calc(6 / 600 * 100vw); + } + .helper-pop .helper-box .helper-QRcode-box .helper-QRcode-box-icon { + width: calc(24 / 600 * 100vw); + height: calc(24 / 600 * 100vw); + } + .helper-pop .helper-box .helper-QRcode-box .helper-QRcode-img { + width: calc(220 / 600 * 100vw); + height: calc(220 / 600 * 100vw); + } + .helper-pop .helper-box .helper-bottom { + height: calc(151 / 600 * 100vw); + } +} +@keyframes slideUp { + 0% { + top: 100%; + } + 100% { + top: 0; + } +} diff --git a/css/public.less b/css/public.less index 8da3d62..eb464a0 100644 --- a/css/public.less +++ b/css/public.less @@ -2629,3 +2629,399 @@ td { padding: 0 5px; } } + +.huddle-box { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.705882352941177); + display: flex; + align-items: flex-end; + justify-content: center; + overflow: hidden; + animation: slidebj 0.5s forwards; + z-index: 10002; + + .box { + width: 100vw; + height: 719px; + border-radius: 20px 20px 0 0; + box-shadow: 0 0 15px rgba(0, 0, 0, 0.101960784313725); + animation: slideUp 0.5s forwards; + background: linear-gradient(0.0796881deg, #c1a75a 0%, #15a3dc 100%); + position: relative; + flex-direction: column; + align-items: center; + padding-top: 32px; + z-index: 1; + + .code { + width: 100vw; + } + + .bj { + width: 100vw; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + z-index: -1; + } + + .bj-bottom { + width: 126px; + height: 134px; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + } + + .top { + width: 199px; + height: 36px; + margin-bottom: 13px; + } + + .title { + width: 311px; + height: 86px; + margin-bottom: 4px; + } + + .text { + font-family: "PingFangSC-Regular", "PingFang SC", sans-serif; + font-weight: 400; + font-style: normal; + font-size: 20px; + color: #ffffff; + text-align: center; + line-height: 30px; + margin-bottom: 25px; + } + + .case { + width: 360px; + height: 400px; + background: linear-gradient(180deg, rgba(242, 242, 242, 1) 0%, rgba(235, 235, 235, 1) 100%); + border-radius: 15px; + flex-direction: column; + align-items: center; + padding-top: 50px; + margin: 0 auto; + + .QRcode { + width: 240px; + height: 240px; + background-color: rgba(255, 255, 255, 1); + border-color: rgba(242, 242, 242, 1); + border-radius: 10px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.184313725490196); + margin-bottom: 26px; + + .img { + width: 218px; + height: 218px; + } + } + + .hint { + .img { + width: 32px; + height: 32px; + + &.img-left { + transform: rotate(180deg); + } + } + + .hint-text { + font-size: 18px; + color: #000000; + text-align: center; + line-height: 28px; + margin: 0 15px; + } + } + } + } + + @media screen and (max-width: 600px) { + .box { + width: 100vw; + height: calc(719 / 600 * 100vw); + padding-top: calc(32 / 600 * 100vw); + // border-radius: calc(30 / 600 * 100vw) calc(30 / 600 * 100vw) 0 0; + box-shadow: 0 0 calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.101960784313725); + animation-name: slideUp; + + .code { + width: 100vw; + } + + .bj-bottom { + width: calc(126 / 600 * 100vw); + height: calc(134 / 600 * 100vw); + } + + .top { + width: calc(199 / 600 * 100vw); + height: calc(36 / 600 * 100vw); + margin-bottom: calc(13 / 600 * 100vw); + } + + .title { + width: calc(311 / 600 * 100vw); + height: calc(86 / 600 * 100vw); + margin-bottom: calc(4 / 600 * 100vw); + } + + .text { + font-size: calc(20 / 600 * 100vw); + line-height: calc(30 / 600 * 100vw); + margin-bottom: calc(25 / 600 * 100vw); + } + + .case { + width: calc(360 / 600 * 100vw); + height: calc(400 / 600 * 100vw); + padding-top: calc(50 / 600 * 100vw); + border-radius: calc(15 / 600 * 100vw); + + .QRcode { + width: calc(240 / 600 * 100vw); + height: calc(240 / 600 * 100vw); + margin-bottom: calc(26 / 600 * 100vw); + border-radius: calc(10 / 600 * 100vw); + box-shadow: 0 0 calc(5 / 600 * 100vw) rgba(0, 0, 0, 0.184313725490196); + + .img { + width: calc(218 / 600 * 100vw); + height: calc(218 / 600 * 100vw); + } + } + + .hint { + .img { + width: calc(32 / 600 * 100vw); + height: calc(32 / 600 * 100vw); + } + + .hint-text { + font-size: calc(18 / 600 * 100vw); + line-height: calc(28 / 600 * 100vw); + margin: 0 calc(15 / 600 * 100vw); + } + } + } + } + } +} + +@keyframes slidebj { + 0% { + background-color: rgba(0, 0, 0, 0); + } + + 100% { + background-color: rgba(0, 0, 0, 0.717647058823529); + } +} + +.helper-pop { + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.717647058823529); + position: fixed; + top: 0; + left: 0; + z-index: 1004; + align-items: flex-end; + box-sizing: border-box; + animation: slidebj 0.5s forwards; + display: flex; + justify-content: center; + overflow: hidden; + + .helper-box { + animation: slideUp 0.5s forwards; + box-sizing: border-box; + flex-direction: column; + width: 100vw; + background: linear-gradient(179.807085646467deg, rgba(193, 206, 250, 1) 0%, rgba(226, 237, 251, 1) 28%, rgba(255, 255, 255, 1) 60%); + border: none; + border-radius: 20px; + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.101960784313725); + position: relative; + padding-top: 59px; + display: flex; + align-items: center; + + .cross-grey { + width: 16px; + height: 16px; + position: absolute; + top: 13px; + right: 13px; + padding: 7px; + cursor: pointer; + } + + .helper-text { + box-sizing: border-box; + height: 103px; + margin: 0 auto 24px; + } + + .helper-box-box { + box-sizing: border-box; + width: 280px; + background: linear-gradient(139.427576997557deg, rgba(101, 137, 242, 1) 0%, rgba(116, 177, 240, 1) 100%); + border: none; + border-radius: 20px; + box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.176470588235294); + flex-direction: column; + align-items: center; + padding: 20px 0; + z-index: 1; + margin-bottom: 80px; + display: flex; + + .helper-box-text { + box-sizing: border-box; + font-size: 16px; + color: #ffffff; + text-align: center; + line-height: 28px; + margin-top: 20px; + } + } + + .helper-QRcode-box { + box-sizing: border-box; + width: 240px; + height: 240px; + background-color: rgba(255, 255, 255, 1); + border-radius: 6px; + position: relative; + display: flex; + justify-content: center; + align-items: center; + + .helper-QRcode-box-icon { + width: 24px; + height: 24px; + position: absolute; + } + + .left-top { + top: 0; + left: 0; + transform: rotate(-90deg); + } + + .left-bottom { + bottom: 0; + left: 0; + transform: rotate(180deg); + } + + .right-top { + right: 0; + top: 0; + } + + .right-bottom { + right: 0; + bottom: 0; + transform: rotate(90deg); + } + + .helper-QRcode-img { + width: 220px; + height: 220px; + box-sizing: border-box; + } + } + + .helper-bottom { + position: absolute; + bottom: 0; + left: 0; + width: 100vw; + height: 151px; + } + } + + @media screen and (max-width: 600px) { + .helper-box { + width: 100vw; + padding-top: calc(59 / 600 * 100vw); + border-radius: calc(20 / 600 * 100vw); + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + box-shadow: 0px 0px calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.101960784313725); + + .cross-grey { + width: calc(16 / 600 * 100vw); + height: calc(16 / 600 * 100vw); + top: calc(13 / 600 * 100vw); + right: calc(13 / 600 * 100vw); + padding: calc(7 / 600 * 100vw); + } + + .helper-text { + height: calc(103 / 600 * 100vw); + margin: 0 auto calc(24 / 600 * 100vw); + } + + .helper-box-box { + width: calc(280 / 600 * 100vw); + border-radius: calc(20 / 600 * 100vw); + box-shadow: 0px 0px calc(15 / 600 * 100vw) rgba(0, 0, 0, 0.176470588235294); + padding: calc(20 / 600 * 100vw) 0; + margin-bottom: calc(80 / 600 * 100vw); + + .helper-box-text { + font-size: calc(16 / 600 * 100vw); + line-height: calc(28 / 600 * 100vw); + margin-top: calc(20 / 600 * 100vw); + } + } + + .helper-QRcode-box { + width: calc(240 / 600 * 100vw); + height: calc(240 / 600 * 100vw); + border-radius: calc(6 / 600 * 100vw); + + .helper-QRcode-box-icon { + width: calc(24 / 600 * 100vw); + height: calc(24 / 600 * 100vw); + } + + .helper-QRcode-img { + width: calc(220 / 600 * 100vw); + height: calc(220 / 600 * 100vw); + } + } + + .helper-bottom { + height: calc(151 / 600 * 100vw); + } + } + } +} + +@keyframes slideUp { + 0% { + top: 100%; + } + + 100% { + top: 0; + } +} \ No newline at end of file diff --git a/css/search-tag.css b/css/search-tag.css index 3693483..38ef21c 100644 --- a/css/search-tag.css +++ b/css/search-tag.css @@ -7,7 +7,6 @@ } #search-tag .label-title .icon { width: 25px; - height: 20px; margin-right: 12px; } #search-tag .label-title .text { @@ -65,6 +64,63 @@ color: #000000; margin: 0 10px; } +#search-tag .quantity .sort-area { + margin-left: auto; + position: relative; + z-index: 1; +} +#search-tag .quantity .sort-area .sort-head { + cursor: pointer; +} +#search-tag .quantity .sort-area .sort-head .text { + font-size: 14px; + color: #555555; + line-height: 26px; + margin-right: 6px; +} +#search-tag .quantity .sort-area .sort-head .icon { + width: 8px; + height: 5px; + transform: rotate(0deg); + transition: transform 0.3s ease-in-out; +} +#search-tag .quantity .sort-area .sort-head .icon.rotate { + transform: rotate(180deg); +} +#search-tag .quantity .sort-area .sort-mask { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; +} +#search-tag .quantity .sort-area .sort-box { + position: absolute; + top: 28px; + right: 0; + width: 140px; + padding: 0 10px; + background-color: #ffffff; + border-radius: 8px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.16862745); +} +#search-tag .quantity .sort-area .sort-box .item { + font-size: 16px; + color: #555555; + text-align: center; + height: 60px; + line-height: 60px; + cursor: pointer; +} +#search-tag .quantity .sort-area .sort-box .item.pitch { + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + color: #d35110; +} +#search-tag .quantity .sort-area .sort-box .item:not(:last-child) { + border-bottom: 1px dotted #d7d7d7; +} #search-tag .matter { align-items: flex-start; } @@ -131,3 +187,31 @@ right: calc((100% - 1200px) / 2); bottom: 10px; } +#search-tag .matter .sidebar-box .recommend-and-essence { + width: 291px; + height: 64px; + background-color: #ffffff; + border: 1px solid #e9eef2; + border-radius: 10px; + padding: 0 10px; + justify-content: space-between; + margin-bottom: 12px; +} +#search-tag .matter .sidebar-box .recommend-and-essence .item { + width: 130px; + height: 40px; + background-color: #f6f6f6; + border: 1px solid #f2f2f2; + border-radius: 65px; + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + font-size: 16px; + color: #000000; + cursor: pointer; +} +#search-tag .matter .sidebar-box .recommend-and-essence .item .icon { + width: 20px; + height: 24px; + margin-right: 8px; +} diff --git a/css/search-tag.less b/css/search-tag.less index 7152da8..0f4d96a 100644 --- a/css/search-tag.less +++ b/css/search-tag.less @@ -7,7 +7,7 @@ .icon { width: 25px; - height: 20px; + // height: 20px; margin-right: 12px; } @@ -74,6 +74,74 @@ color: #000000; margin: 0 10px; } + + .sort-area { + margin-left: auto; + position: relative; + z-index: 1; + + .sort-head { + cursor: pointer; + + .text { + font-size: 14px; + color: #555555; + line-height: 26px; + margin-right: 6px; + } + + .icon { + width: 8px; + height: 5px; + + transform: rotate(0deg); + transition: transform 0.3s ease-in-out; + + &.rotate { + transform: rotate(180deg); + } + } + } + + .sort-mask { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + } + + .sort-box { + position: absolute; + top: 28px; + right: 0; + width: 140px; + padding: 0 10px; + background-color: rgba(255, 255, 255, 1); + border-radius: 8px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.168627450980392); + + .item { + font-size: 16px; + color: #555555; + text-align: center; + height: 60px; + line-height: 60px; + cursor: pointer; + + &.pitch { + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + color: #d35110; + } + + &:not(:last-child) { + border-bottom: 1px dotted #d7d7d7; + } + } + } + } } .matter { @@ -154,6 +222,37 @@ right: calc((100% - 1200px) / 2); bottom: 10px; } + + .recommend-and-essence { + width: 291px; + height: 64px; + background-color: rgba(255, 255, 255, 1); + border: 1px solid rgba(233, 238, 242, 1); + border-radius: 10px; + padding: 0 10px; + justify-content: space-between; + margin-bottom: 12px; + + .item { + width: 130px; + height: 40px; + background-color: rgba(246, 246, 246, 1); + border: 1px solid rgba(242, 242, 242, 1); + border-radius: 65px; + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + font-size: 16px; + color: #000000; + cursor: pointer; + + .icon { + width: 20px; + height: 24px; + margin-right: 8px; + } + } + } } } } diff --git a/css/search.css b/css/search.css index 2e77054..33a621f 100644 --- a/css/search.css +++ b/css/search.css @@ -15,6 +15,7 @@ border: none; outline: none; height: 100%; + font-size: 16px; } #search .search-box .search-icon { width: 20px; @@ -126,3 +127,46 @@ width: 291px; position: sticky; } +#search .matter .sidebar-box .recommend-and-essence { + width: 291px; + height: 64px; + background-color: #ffffff; + border: 1px solid #e9eef2; + border-radius: 10px; + padding: 0 10px; + justify-content: space-between; + margin-bottom: 12px; +} +#search .matter .sidebar-box .recommend-and-essence .item { + width: 130px; + height: 40px; + background-color: #f6f6f6; + border: 1px solid #f2f2f2; + border-radius: 65px; + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + font-size: 16px; + color: #000000; + cursor: pointer; +} +#search .matter .sidebar-box .recommend-and-essence .item .icon { + width: 20px; + height: 24px; + margin-right: 8px; +} +#search .search-no .earth-icon { + width: 239px; + height: 180px; + margin: 0 auto; +} +#search .search-no .input-box { + width: 903px; + height: 60px; + background-color: #ffffff; + border: 1px solid #e9eef2; + border-radius: 6px; +} +#search .search-no .input-box .input { + font-size: 16px; +} diff --git a/css/search.less b/css/search.less index 3fae62f..c5e2583 100644 --- a/css/search.less +++ b/css/search.less @@ -15,6 +15,7 @@ border: none; outline: none; height: 100%; + font-size: 16px; } .search-icon { @@ -161,6 +162,58 @@ // left: calc((100% - 1200px) / 2 + 909px); // bottom: 10px; // } + + .recommend-and-essence { + width: 291px; + height: 64px; + background-color: rgba(255, 255, 255, 1); + border: 1px solid rgba(233, 238, 242, 1); + border-radius: 10px; + padding: 0 10px; + justify-content: space-between; + margin-bottom: 12px; + + .item { + width: 130px; + height: 40px; + background-color: rgba(246, 246, 246, 1); + border: 1px solid rgba(242, 242, 242, 1); + border-radius: 65px; + font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; + font-weight: 650; + font-style: normal; + font-size: 16px; + color: #000000; + cursor: pointer; + + .icon { + width: 20px; + height: 24px; + margin-right: 8px; + } + } + } + } + } + + .search-no { + .earth-icon { + width: 239px; + height: 180px; + margin: 0 auto; + } + + .input-box { + width: 903px; + height: 60px; + background-color: rgba(255, 255, 255, 1); + border: 1px solid rgba(233, 238, 242, 1); + border-radius: 6px; + + .input { + + font-size: 16px; + } } } } diff --git a/css/section.css b/css/section.css index 8f3595c..c3763c6 100644 --- a/css/section.css +++ b/css/section.css @@ -399,4 +399,30 @@ #sectionIndex .matter .sidebar { display: none; } + #sectionIndex .matter .matter-content .details-box .content-box .selectives-box .list { + padding-right: 0; + } + #sectionIndex .matter .matter-content .details-box .content-box .selectives-box .list .item { + width: 100%; + } + #sectionIndex .matter .matter-content .details-box .content-box .selectives-box .list .item .text { + flex: 1; + } + #sectionIndex .matter .matter-content .info-box .right .link .item { + width: 50%; + } + #sectionIndex .matter .matter-content .info-box .right .link .item:not(:last-child) { + margin: 0; + } +} +@media screen and (max-width: 500px) { + #sectionIndex .matter .matter-content .info-box { + padding-top: 15px; + padding-left: 15px; + } + #sectionIndex .matter .matter-content .info-box .img-box { + width: 70px; + height: 70px; + margin-right: 15px; + } } diff --git a/css/section.less b/css/section.less index e31eda9..e40f25e 100644 --- a/css/section.less +++ b/css/section.less @@ -83,6 +83,8 @@ } .matter-content { + min-width: 0; + .info-box { width: 100%; background: -webkit-linear-gradient(270.539085289936deg, rgba(255, 255, 255, 1) 2%, rgba(235, 248, 249, 1) 98%); @@ -234,6 +236,7 @@ margin-right: 12px; position: sticky; z-index: 1; + min-width: 0; .selectives-box { width: 100%; @@ -473,4 +476,38 @@ #sectionIndex .matter .sidebar { display: none; } + + #sectionIndex .matter .matter-content { + .details-box .content-box .selectives-box .list { + padding-right: 0; + + .item { + width: 100%; + + .text { + flex: 1; + } + } + } + .info-box .right .link .item { + width: 50%; + + &:not(:last-child) { + margin: 0; + } + } + } +} + +@media screen and (max-width: 500px) { + #sectionIndex .matter .matter-content .info-box { + padding-top: 15px; + padding-left: 15px; + + .img-box { + width: 70px; + height: 70px; + margin-right: 15px; + } + } } diff --git a/img/apply-for-name.png b/img/apply-for-name.png new file mode 100644 index 0000000..2051910 Binary files /dev/null and b/img/apply-for-name.png differ diff --git a/img/cross-grey.png b/img/cross-grey.png new file mode 100644 index 0000000..c3e2e52 Binary files /dev/null and b/img/cross-grey.png differ diff --git a/img/earth-icon.png b/img/earth-icon.png new file mode 100644 index 0000000..68d7375 Binary files /dev/null and b/img/earth-icon.png differ diff --git a/img/essence-head-icon.png b/img/essence-head-icon.png new file mode 100644 index 0000000..3cb7f48 Binary files /dev/null and b/img/essence-head-icon.png differ diff --git a/img/group-arrows.png b/img/group-arrows.png new file mode 100644 index 0000000..4b0b445 Binary files /dev/null and b/img/group-arrows.png differ diff --git a/img/group-bj.svg b/img/group-bj.svg new file mode 100644 index 0000000..c62fb7a --- /dev/null +++ b/img/group-bj.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/img/group-bottom.png b/img/group-bottom.png new file mode 100644 index 0000000..fd55089 Binary files /dev/null and b/img/group-bottom.png differ diff --git a/img/group-title.png b/img/group-title.png new file mode 100644 index 0000000..12f15c7 Binary files /dev/null and b/img/group-title.png differ diff --git a/img/group-top.png b/img/group-top.png new file mode 100644 index 0000000..b306246 Binary files /dev/null and b/img/group-top.png differ diff --git a/img/helper-bottom-blue.svg b/img/helper-bottom-blue.svg new file mode 100644 index 0000000..1b40266 --- /dev/null +++ b/img/helper-bottom-blue.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/img/helper-bottom-yellow.svg b/img/helper-bottom-yellow.svg new file mode 100644 index 0000000..1e8a509 --- /dev/null +++ b/img/helper-bottom-yellow.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/img/recommend-head-icon.png b/img/recommend-head-icon.png new file mode 100644 index 0000000..6d2f8bf Binary files /dev/null and b/img/recommend-head-icon.png differ diff --git a/img/triangle-black.svg b/img/triangle-black.svg new file mode 100644 index 0000000..c061932 --- /dev/null +++ b/img/triangle-black.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/img/yellow-border.svg b/img/yellow-border.svg new file mode 100644 index 0000000..efc4bda --- /dev/null +++ b/img/yellow-border.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/js/save.js b/js/save.js index 3bf8ed5..c54d559 100644 --- a/js/save.js +++ b/js/save.js @@ -40,7 +40,11 @@ const watchList = { // 监听 bi.txt,同步到 bi.js "../component/bi/bi.txt": "../component/bi/bi.js", - + + "../component/huddle-box/huddle-box.txt": "../component/huddle-box/huddle-box.js", + + "../component/helper-pop/helper-pop.txt": "../component/helper-pop/helper-pop.js", + // 可添加更多文件(格式:'txt路径': 'js路径') // './component/other/other.txt': './component/other/other.js', }; diff --git a/js/search.js b/js/search.js index 180be59..e363ba7 100644 --- a/js/search.js +++ b/js/search.js @@ -1,307 +1,295 @@ const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue; -import { itemForum } from "../component/item-forum/item-forum.js"; -import { itemOffer } from "../component/item-offer/item-offer.js"; -import { itemSummary } from "../component/item-summary/item-summary.js"; -import { itemVote } from "../component/item-vote/item-vote.js"; -import { itemMj } from "../component/item-mj/item-mj.js"; -import { itemTenement } from "../component/item-tenement/item-tenement.js"; -import { itemProject } from "../component/item-project/item-project.js"; -import { headTop } from "../component/head-top/head-top.js"; -import { hotTag } from "../component/hot-tag/hot-tag.js"; -import { hotSearch } from "../component/hot-search/hot-search.js"; -import { slideshowBox } from "../component/slideshow-box/slideshow-box.js"; -import { latestList } from "../component/latest-list/latest-list.js"; -import { loadBox } from "../component/load-box/load-box.js"; +(async function () { + const { itemForum } = await import(withVer("../component/item-forum/item-forum.js")); + const { itemOffer } = await import(withVer("../component/item-offer/item-offer.js")); + const { itemSummary } = await import(withVer("../component/item-summary/item-summary.js")); + const { itemVote } = await import(withVer("../component/item-vote/item-vote.js")); + const { itemMj } = await import(withVer("../component/item-mj/item-mj.js")); + const { itemTenement } = await import(withVer("../component/item-tenement/item-tenement.js")); + const { itemProject } = await import(withVer("../component/item-project/item-project.js")); + const { headTop } = await import(withVer("../component/head-top/head-top.js")); + const { hotTag } = await import(withVer("../component/hot-tag/hot-tag.js")); + const { hotSearch } = await import(withVer("../component/hot-search/hot-search.js")); + const { slideshowBox } = await import(withVer("../component/slideshow-box/slideshow-box.js")); + const { latestList } = await import(withVer("../component/latest-list/latest-list.js")); + const { loadBox } = await import(withVer("../component/load-box/load-box.js")); -const appSearch = createApp({ - setup() { - let kwValue = ref(null); - let typeValue = ref(null); - let kw = ref(""); - onMounted(() => { - const params = getUrlParams(); - console.log("params", params); - // 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; - const tab = typeValue.value.innerText; - if (tab) tabValue.value = tab; - if (params.page) page.value = params.page; - else page.value = 1; + const appSearch = createApp({ + setup() { + let kwValue = ref(null); + let typeValue = ref(null); + let kw = ref(""); + onMounted(() => { + console.log('onMounted'); + const params = getUrlParams(); - if (kw.value) getList(); - else page.value = null; + kw.value = kwValue.value.innerText; + const tab = typeValue.value.innerText; + if (tab) tabValue.value = tab; + if (params.page) page.value = params.page; + else page.value = 1; - getUserInfoWin(); - - window.addEventListener("scroll", handleScroll); - }); - - let isLogin = ref(false); - let realname = ref(0); // 是否已经实名 - let userInfoWin = ref({}); - - 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; - permissions.value = user?.authority || []; - }; - 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); - - const cutTab = (type) => { - if (tabValue.value == type) return; - page.value = 1; - list.value = []; - count.value = 0; - tabValue.value = type; - pagination.value = []; - - updateUrlParams({ type: type == "all" ? null : type }); - - getList(); - }; - - let tabList = ref({ - all: "全部", - thread: "论坛", - offer: "Offer", - offer_summary: "总结", - interviewexperience: "面经", - vote: "投票", - }); - - let tabValue = ref("all"); - - let uniqid = ""; - const init = () => { - ajaxGet(`https://offer.gter.net/miniprogramApi/offer/search`).then((res) => { - if (res.code != 200) { - creationAlertBox("error", res.message); - page.value = 0; - return; + console.log("kw.value", kw.value); + if (kw.value) getList(); + else { + page.value = null; + isEmptySearch.value = true; } - console.log("res", res); - }); - }; - let loading = ref(false); - let page = ref(0); - let maxPage = ref(0); - let count = ref(0); - let list = ref([]); - let pagination = ref([]); - const getList = () => { - if (loading.value || page.value == null) return; - loading.value = true; - const limit = 20; - window.scrollTo(0, 0); - updateUrlParams({ page: page.value }); - ajaxGet(`/v2/api/forum/topicLists?type=${tabValue.value == "all" ? "" : tabValue.value}&page=${page.value}&limit=${limit}&keyword=${kw.value}`) - .then((res) => { + getUserInfoWin(); + + window.addEventListener("scroll", handleScroll); + + const preLoader = document.getElementById("pre-loader"); + if (preLoader) preLoader.style.display = "none"; + }); + + let isLogin = ref(false); + let realname = ref(0); // 是否已经实名 + let userInfoWin = ref({}); + + 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; + permissions.value = user?.authority || []; + }; + 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); + + const cutTab = (type) => { + if (tabValue.value == type) return; + page.value = 1; + list.value = []; + count.value = 0; + tabValue.value = type; + pagination.value = []; + + updateUrlParams({ type: type == "all" ? null : type }); + + getList(); + }; + + let tabList = ref({ + all: "全部", + thread: "论坛", + offer: "Offer", + offer_summary: "总结", + interviewexperience: "面经", + vote: "投票", + xg: "港校项目", + }); + + let tabValue = ref("all"); + + let uniqid = ""; + const init = () => { + ajaxGet(`https://offer.gter.net/miniprogramApi/offer/search`).then((res) => { if (res.code != 200) { creationAlertBox("error", res.message); + page.value = 0; return; } - - let data = res.data; - data.data.unshift({ - id: 20, - program_en: "Master of Laws in Arbitration and Dispute Resolution", - program_zh: "法学硕士(仲裁及争议解决学)", - program_abbr: "LLMARBDR", - program_code: "P41", - award_en: "Master of Laws in Arbitration and Dispute Resolution", - award_zh: "法学硕士(仲裁及争议解决学)", - subject_area_id: 9, - subject_area_name: "Law", - primary_university: "City University of Hong Kong", - primary_university_id: 3, - status: "ACTIVE", - intake_year: 2026, - disciplineid: 9, - distinctive: "毕业生可参与:当事人、辩护人、专家、仲裁员和调解员", - rank: "42", - department: "法律学院", - admissionsproject: "1", - departmentid: 26, - schoolalias: "城大", - schoolname: "香港城市大学", - tags: ["有奖学金", "论文课程", "26fall 提前批", "Top 50", "专业资格认证"], - schoolenname: "City University of Hong Kong", - intake_month: 9, - schoolid: 311, - tuition_fee: null, - uniqid: "tf1yFYMER8-1bY1t5oLbKaNc2FVhOWM0", - type: "programs", - schoollogo: "https://oss.x-php.com/school/J6BSwE-VfCFkCb1SBaR7ec6NYmTA4pRcOalNHJRfNzUxNg~~", - }); - - list.value = data.data; - if (list.value.length == 0) page.value = null; - - count.value = data.count; - loading.value = false; - maxPage.value = Math.ceil(count.value / limit); - pagination.value = calculatePagination(page.value, maxPage.value); - - let url = `/search/${kw.value}`; - - const hostname = location.hostname; - const localHostReg = /^(localhost|127\.0\.0\.1|\[::1\])$/; - if (localHostReg.test(hostname)) url = `/search.html`; - - updateUrlLastPath(url); - removeQueryQ(); - }) - .catch((err) => { - err = err.data; - if (err.code == 401) goLogin(); - loading.value = false; }); - }; + }; - const calculatePagination = (currentPage, totalPages, visibleCount = 3) => { - // 处理特殊情况:总页数小于等于1时,无需显示分页 - if (totalPages <= 1) { - return []; - } + let loading = ref(false); + let page = ref(0); + let maxPage = ref(0); + let count = ref(0); + let total = ref(0); + let list = ref([]); + let pagination = ref([]); + const getList = () => { + if (loading.value || page.value == null) return; + loading.value = true; + isEmptySearch.value = false; + const limit = 20; + window.scrollTo(0, 0); + // updateUrlParams({ page: page.value }); - const pages = []; - // 始终显示第一页 - pages.push(1); + let postHead = null; - // 计算中间需要显示的页码范围 - let startPage = Math.max(2, currentPage - Math.floor(visibleCount / 2)); - let endPage = Math.min(totalPages - 1, startPage + visibleCount - 1); + if (tabValue.value == "xg") { + postHead = ajax(`https://api.gter.net/v1/program/getList`, { + page: page.value, + keyword: kw.value, + }); + } else postHead = ajaxGet(`/v2/api/forum/topicLists?type=${tabValue.value == "all" ? "" : tabValue.value}&page=${page.value}&limit=${limit}&keyword=${kw.value}`); - // 调整起始页码,确保显示足够数量的页码 - startPage = Math.max(2, endPage - visibleCount + 1); + let historySearchList = JSON.parse(localStorage.getItem("history-search")) || []; + historySearchList.unshift(kw.value); + historySearchList = [...new Set(historySearchList)]; + if (historySearchList.length > 10) historySearchList = historySearchList.splice(0, 10); + localStorage.setItem("history-search", JSON.stringify(historySearchList)); - // 前面的省略号:如果第一页和起始页之间有间隔 - if (startPage > 2) { - pages.push("..."); - } + postHead + .then((res) => { + if (res.code != 200) { + creationAlertBox("error", res.message); + return; + } - // 添加中间的页码 - for (let i = startPage; i <= endPage; i++) { - pages.push(i); - } + let data = res.data; + list.value = data.data; + if (list.value.length == 0) page.value = null; - // 后面的省略号:如果最后一页和结束页之间有间隔 - if (endPage < totalPages - 1) { - pages.push("..."); - } + total.value = data.total || data.count; + count.value = data.count; + loading.value = false; + maxPage.value = Math.ceil(count.value / limit); + pagination.value = calculatePagination(page.value, maxPage.value); + // updateUrlLastPath(`/search/${kw.value}`); + removeQueryQ(); + }) + .catch((err) => { + err = err?.data; + if (err?.code == 401) goLogin(); + loading.value = false; + }); + }; - // 始终显示最后一页(如果总页数大于1) - if (totalPages > 1) { - pages.push(totalPages); - } + const calculatePagination = (currentPage, totalPages, visibleCount = 3) => { + // 处理特殊情况:总页数小于等于1时,无需显示分页 + if (totalPages <= 1) { + return []; + } - return pages; - }; + const pages = []; + // 始终显示第一页 + pages.push(1); - const cutPage = (value) => { - if (value == "...") return; - if (value == page.value) return; - page.value = value; - list.value = []; - getList(); - }; + // 计算中间需要显示的页码范围 + let startPage = Math.max(2, currentPage - Math.floor(visibleCount / 2)); + let endPage = Math.min(totalPages - 1, startPage + visibleCount - 1); - const prevPage = () => { - page.value -= 1; - list.value = []; - pagination.value = []; - getList(); - }; + // 调整起始页码,确保显示足够数量的页码 + startPage = Math.max(2, endPage - visibleCount + 1); - const nextPage = () => { - page.value += 1; - list.value = []; - pagination.value = []; - getList(); - }; + // 前面的省略号:如果第一页和起始页之间有间隔 + if (startPage > 2) { + pages.push("..."); + } - const startSearch = () => { - if (kw.value == "") { - creationAlertBox("error", "请输入搜索关键词"); - return; - } + // 添加中间的页码 + for (let i = startPage; i <= endPage; i++) { + pages.push(i); + } - page.value = 1; - list.value = []; - count.value = 0; - pagination.value = []; - getList(); - }; + // 后面的省略号:如果最后一页和结束页之间有间隔 + if (endPage < totalPages - 1) { + pages.push("..."); + } - const sidebarFixed = ref(false); - const matterFixed = ref(false); - const matterBottom = ref(false); + // 始终显示最后一页(如果总页数大于1) + if (totalPages > 1) { + pages.push(totalPages); + } - const handleScroll = () => { - matterHeight.value = -(matterContentRef.value.offsetHeight - window.innerHeight); - sidebarHeight.value = -(sidebarRef.value.offsetHeight - window.innerHeight); - if (matterHeight.value > 0) matterHeight.value = 12; - if (sidebarHeight.value > 0) sidebarHeight.value = 12; - }; + return pages; + }; - const matterRef = ref(null); - const sidebarRef = ref(null); - const matterContentRef = ref(null); + const cutPage = (value) => { + if (value == "...") return; + if (value == page.value) return; + page.value = value; + list.value = []; + getList(); + }; - let sidebarHeight = ref(0); - let matterHeight = ref(0); + const prevPage = () => { + page.value -= 1; + list.value = []; + pagination.value = []; + getList(); + }; - return { 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("itemOffer", itemOffer); -appSearch.component("itemSummary", itemSummary); -appSearch.component("itemVote", itemVote); -appSearch.component("itemMj", itemMj); -appSearch.component("itemTenement", itemTenement); -appSearch.component("itemProject", itemProject); -appSearch.component("head-top", headTop); -appSearch.component("hot-tag", hotTag); -appSearch.component("hot-search", hotSearch); -appSearch.component("slideshow-box", slideshowBox); -appSearch.component("latest-list", latestList); -appSearch.component("load-box", loadBox); -appSearch.mount("#search"); + const nextPage = () => { + page.value += 1; + list.value = []; + pagination.value = []; + getList(); + }; + + const startSearch = () => { + if (kw.value == "") { + creationAlertBox("error", "请输入搜索关键词"); + return; + } + + page.value = 1; + list.value = []; + count.value = 0; + pagination.value = []; + getList(); + }; + + const sidebarFixed = ref(false); + const matterFixed = ref(false); + const matterBottom = ref(false); + + const handleScroll = () => { + matterHeight.value = -(matterContentRef.value.offsetHeight - window.innerHeight); + sidebarHeight.value = -(sidebarRef.value.offsetHeight - window.innerHeight); + if (matterHeight.value > 0) matterHeight.value = 12; + if (sidebarHeight.value > 0) sidebarHeight.value = 12; + }; + + const matterRef = ref(null); + const sidebarRef = ref(null); + const matterContentRef = ref(null); + + let sidebarHeight = ref(0); + let matterHeight = ref(0); + + 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 }; + }, + }); + appSearch.component("item-forum", itemForum); + appSearch.component("itemOffer", itemOffer); + appSearch.component("itemSummary", itemSummary); + appSearch.component("itemVote", itemVote); + appSearch.component("itemMj", itemMj); + appSearch.component("itemTenement", itemTenement); + appSearch.component("itemProject", itemProject); + appSearch.component("head-top", headTop); + appSearch.component("hot-tag", hotTag); + appSearch.component("hot-search", hotSearch); + appSearch.component("slideshow-box", slideshowBox); + appSearch.component("latest-list", latestList); + appSearch.component("load-box", loadBox); + appSearch.mount("#search"); +})(); diff --git a/js/sectionV2.js b/js/sectionV2.js new file mode 100644 index 0000000..88c6565 --- /dev/null +++ b/js/sectionV2.js @@ -0,0 +1,333 @@ +const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue; +(async function () { + const { itemForum } = await import(withVer("../component/item-forum/item-forum.js")); + const { itemOffer } = await import(withVer("../component/item-offer/item-offer.js")); + const { itemSummary } = await import(withVer("../component/item-summary/item-summary.js")); + const { itemVote } = await import(withVer("../component/item-vote/item-vote.js")); + const { itemMj } = await import(withVer("../component/item-mj/item-mj.js")); + const { itemTenement } = await import(withVer("../component/item-tenement/item-tenement.js")); + const { itemProject } = await import(withVer("../component/item-project/item-project.js")); + const { latestList } = await import(withVer("../component/latest-list/latest-list.js")); + const { headTop } = await import(withVer("../component/head-top/head-top.js")); + const { loadBox } = await import(withVer("../component/load-box/load-box.js")); + const { huddleBox } = await import(withVer("../component/huddle-box/huddle-box.js")); + const { helperPop } = await import(withVer("../component/helper-pop/helper-pop.js")); + + const appSectionIndex = createApp({ + setup() { + let uniValue = ref(null); + + let isMobile = ref(false); + + onMounted(() => { + isMobile.value = window.isMobile; + + const urlObj = new URL(location.href); + const pathParts = urlObj.pathname.split("/").filter((part) => part); + const id = pathParts.pop(); + + section.value = uniValue.value.innerText; + + init(); + getSectionList(); + handpick(); + getTags(); + getList(); + getTopicLatest(); + window.addEventListener("scroll", handleScroll); + + // const preLoader = document.getElementById("pre-loader"); + // if (preLoader) preLoader.style.display = "none"; + + document.querySelectorAll(".vuehide").forEach((item) => { + item.style.display = "none"; + }); + }); + + const detailsRef = ref(null); + const matterRef = ref(null); + const sidebarRef = ref(null); + + const contentRef = ref(null); + let sidebarHeight = ref(0); + let matterHeight = ref(0); + + const sidebarFixed = ref(false); + const handleScroll = () => { + const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; + const scrollHeight = document.documentElement.scrollHeight; + const clientHeight = window.innerHeight; + + // 列表下 滑动到底部 获取新数据 + if (scrollTop + clientHeight >= scrollHeight - 200) getList(); + + // 侧边栏滚动固定 + // if (scrollTop >= detailsRef.value.offsetTop + sidebarRef.value.offsetHeight - clientHeight) sidebarFixed.value = true; + // else sidebarFixed.value = false; + + matterHeight.value = -(contentRef.value.offsetHeight - window.innerHeight); + sidebarHeight.value = -(sidebarRef.value.offsetHeight - window.innerHeight); + + if (matterHeight.value > 0) matterHeight.value = 12; + if (sidebarHeight.value > 0) sidebarHeight.value = 12; + }; + + let sectionList = ref([]); + let section = ref(""); + + const getSectionList = () => { + ajaxGet("/v2/api/forum/getSectionList").then((res) => { + if (res.code != 200) return; + const data = res.data || []; + + let obj = {}; + + data.forEach((element) => (obj[element.cid] = element)); + const list = insertLineBetweenCategories(data, "cid"); + sectionList.value = list; + // if (!section.value) { + // const uniqid = list[0].uniqid; + // section.value = uniqid; + // updateUrlParams({ section: uniqid }); + // init(); + // } + }); + }; + + // 将版块按 cid 分格开 + const insertLineBetweenCategories = (arr) => { + if (!arr.length) return []; + + const sortedArr = [...arr].sort((a, b) => { + if (a["cid"] < b["cid"]) return -1; + if (a["cid"] > b["cid"]) return 1; + return 0; + }); + + const result = [sortedArr[0]]; + let prevCategory = sortedArr[0]["cid"]; + + for (let i = 1; i < sortedArr.length; i++) { + const current = sortedArr[i]; + const currentCategory = current["cid"]; + + if (currentCategory !== prevCategory) { + result.push({ + key: "line", + }); + prevCategory = currentCategory; + } + result.push(current); + } + + return result; + }; + + let info = ref({}); + + const init = () => { + ajaxGet(`/v2/api/forum/getSectionDetails?sectionid=${section.value}`).then((res) => { + if (res.code != 200) return; + const data = res.data || {}; + info.value = data; + // 滚动到顶部 + window.scrollTo({ top: 0, behavior: "smooth" }); + }); + }; + + let handpickList = ref([]); + const handpick = () => { + ajaxGet(`/v2/api/forum/topicHandpicked?sectionid=${section.value}`).then((res) => { + let data = res.data || []; + handpickList.value = data; + }); + }; + + let tagsList = ref([]); + const getTags = () => { + ajaxGet(`/v2/api/forum/sectionTags?sectionid=${section.value}`).then((res) => { + if (res.code != 200) return; + const data = res.data || {}; + tagsList.value = data; + }); + }; + + let loading = ref(false); + let page = ref(1); + let count = ref(0); + let list = ref([]); + const getList = () => { + if (loading.value || page.value == 0) return; + loading.value = true; + ajaxGet(`/v2/api/forum/topicLists?page=${page.value || 1}§ionid=${section.value}`) + .then((res) => { + if (res.code != 200) return; + let data = res.data; + list.value = list.value.concat(data.data); + page.value = data.count > data.limit * data.page ? page.value + 1 : 0; + count.value = data.count; + loading.value = false; + }) + .catch((err) => { + err = err.data; + if (err.code == 401) openLoginBtnState(); + loading.value = false; + }); + }; + + onMounted(() => getUserInfoWin()); + + let isLogin = ref(false); + let realname = ref(0); // 是否已经实名 + let userInfoWin = 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); + + const changeSection = (uniqid) => { + section.value = uniqid; + handpickList.value = []; + info.value = {}; + tagsList.value = []; + + count.value = 0; + page.value = 1; + list.value = []; + + init(); + handpick(); + getTags(); + getList(); + updateUrlLastPath(`/section/${uniqid}`); + }; + + let offer = ref([]); // 面经列表 + let vote = ref([]); // 面经列表 + let interviewexperience = ref([]); // 面经列表 + const getTopicLatest = () => { + ajaxGet(`/v2/api/forum/getTopicLatest?limit=4`).then((res) => { + const data = res.data || []; + + data.vote.forEach((item) => { + if (!item.title) { + item.title = item.content; + item.content = ""; + } + }); + + offer.value = data.offer; + vote.value = data.vote; + interviewexperience.value = data.interviewexperience; + }); + }; + + let linkXg = ref([ + { + name: "申港超强资料包", + url: "https://u.gter.net/ad/1043?x=gter", + }, + { + name: "港校项目库", + url: "http://program.gter.net/", + }, + { + name: "26fall香港申请群", + img: "/img/cong-ge.png", + hint: "微信扫码添加", + type: "cong", + }, + { + name: "寄托香港租房", + url: "https://fang.gter.net/", + }, + ]); // 链接列表 + + let linkOther = ref([ + { + name: "26fall申请群", + img: "/img/cong-ge.png", + title: "26fall申请群", + hint: "微信扫码添加", + type: "cong", + }, + { + name: "申请求助", + img: "/img/university-manager.png", + title: "申请遇疑问可联系", + hint: "寄托院校君", + type: "university", + }, + ]); // 链接列表 + + const handleCheckAttest = (e) => { + if (!isLogin.value) { + goLogin(); + e.preventDefault(); // 阻止默认跳转(即使 href 为链接,也强制拦截) + return; + } + if (realname.value === 0 && userInfoWin.value?.uin > 0) { + openAttest(); + e.preventDefault(); // 阻止默认跳转(即使 href 为链接,也强制拦截) + } + }; + + let huddleBoxRef = ref(null); + let helperPopRef = ref(null); + const linkClick = (type) => { + if (!isMobile.value) return; + if (type == "cong") huddleBoxRef.value.open(); + if (type == "university") helperPopRef.value.open(); + }; + + return { helperPopRef, huddleBoxRef, linkClick, handleCheckAttest, sidebarHeight, matterHeight, page, sidebarFixed, detailsRef, contentRef, matterRef, sidebarRef, loading, linkOther, linkXg, uniValue, offer, vote, interviewexperience, changeSection, sectionList, section, info, handpickList, tagsList, list, count }; + }, + }); + appSectionIndex.component("item-forum", itemForum); + appSectionIndex.component("item-offer", itemOffer); + appSectionIndex.component("item-summary", itemSummary); + appSectionIndex.component("item-vote", itemVote); + appSectionIndex.component("item-mj", itemMj); + appSectionIndex.component("item-tenement", itemTenement); + appSectionIndex.component("item-project", itemProject); + appSectionIndex.component("latest-list", latestList); + appSectionIndex.component("head-top", headTop); + appSectionIndex.component("load-box", loadBox); + appSectionIndex.component("huddle-box", huddleBox); + appSectionIndex.component("helper-pop", helperPop); + + appSectionIndex.mount("#sectionIndex"); +})(); diff --git a/searchV2.html b/searchV2.html new file mode 100644 index 0000000..9ada716 --- /dev/null +++ b/searchV2.html @@ -0,0 +1,474 @@ + + + + + + + + 搜索结果 - 澳门大学 - 寄托天下 -- 寄托天下 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+
+
+
+ + +
+
历史搜索
+
+
+
+ +
+ +
+ +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sectionV2.html b/sectionV2.html index f1ea38a..bca17da 100644 --- a/sectionV2.html +++ b/sectionV2.html @@ -200,7 +200,7 @@
{{ item.name }}
-
+
{{ item.name }}
@@ -338,14 +338,14 @@
@@ -459,6 +459,9 @@ + + + @@ -468,7 +471,7 @@ - +