feat: 新增签到功能模块并优化详情页样式
- 添加签到功能相关HTML/CSS/JS文件 - 在详情页增加图片预览组件 - 调整详情页文本行高和标题样式 - 修复评论时间显示问题 - 优化本地开发环境授权处理
This commit is contained in:
99
component/preview-image/preview.js
Normal file
99
component/preview-image/preview.js
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
class PreviewImage extends HTMLElement {
|
||||||
|
static get observedAttributes() { return ["src", "alt"]; }
|
||||||
|
constructor(){
|
||||||
|
super();
|
||||||
|
this._src = this.getAttribute("src") || "";
|
||||||
|
this._alt = this.getAttribute("alt") || "";
|
||||||
|
this.attachShadow({ mode: "open" });
|
||||||
|
const root = document.createElement("div");
|
||||||
|
root.className = "root";
|
||||||
|
const img = document.createElement("img");
|
||||||
|
root.appendChild(img);
|
||||||
|
this.shadowRoot.append(style, root);
|
||||||
|
this._img = img;
|
||||||
|
this._render();
|
||||||
|
this._img.addEventListener("click", (e)=>{ e.stopPropagation(); this.init(this._src); });
|
||||||
|
// 保存一个全局实例(与 bi.js 风格一致,便于外部静态调用)
|
||||||
|
window.previewImageComponent = this;
|
||||||
|
}
|
||||||
|
attributeChangedCallback(name, oldVal, newVal){
|
||||||
|
if(name === "src") this._src = newVal || "";
|
||||||
|
if(name === "alt") this._alt = newVal || "";
|
||||||
|
this._render();
|
||||||
|
}
|
||||||
|
_render(){
|
||||||
|
if(this._img){ this._img.src = this._src; this._img.alt = this._alt; }
|
||||||
|
}
|
||||||
|
init(src){ PreviewImage.open(src || this._src); }
|
||||||
|
static open(src){
|
||||||
|
if(!src) return;
|
||||||
|
const mask = document.createElement("div");
|
||||||
|
const box = document.createElement("div");
|
||||||
|
const img = document.createElement("img");
|
||||||
|
|
||||||
|
mask.style.width = "100%";
|
||||||
|
mask.style.height = "100%";
|
||||||
|
mask.style.maxWidth = "none";
|
||||||
|
mask.style.maxHeight = "none";
|
||||||
|
mask.style.border = "none";
|
||||||
|
mask.style.position = "fixed";
|
||||||
|
mask.style.top = "0";
|
||||||
|
mask.style.left = "0";
|
||||||
|
mask.style.backgroundColor = "rgba(255, 255, 255, 0.8)";
|
||||||
|
mask.style.zIndex = "10002";
|
||||||
|
mask.style.display = "flex";
|
||||||
|
mask.style.alignItems = "center";
|
||||||
|
mask.style.justifyContent = "center";
|
||||||
|
|
||||||
|
// box.className = "detail-image flexcenter";
|
||||||
|
box.style.width = "80vw";
|
||||||
|
box.style.height = "80vh";
|
||||||
|
box.style.borderRadius = "8px";
|
||||||
|
box.style.backgroundColor = "rgba(17, 17, 17, 0.9)";
|
||||||
|
box.style.overflow = "hidden";
|
||||||
|
box.style.display = "flex";
|
||||||
|
box.style.alignItems = "center";
|
||||||
|
box.style.justifyContent = "center";
|
||||||
|
box.style.position = "relative";
|
||||||
|
|
||||||
|
// img.className = "detail-img";
|
||||||
|
img.style.maxWidth = "100%";
|
||||||
|
img.style.maxHeight = "100%";
|
||||||
|
img.src = src;
|
||||||
|
box.appendChild(img);
|
||||||
|
mask.appendChild(box);
|
||||||
|
let scale = 1, tx = 0, ty = 0, dragging = false, sx = 0, sy = 0;
|
||||||
|
const apply = () => { img.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`; img.style.cursor = dragging ? "grabbing" : "grab"; };
|
||||||
|
const onWheel = (ev) => { ev.preventDefault(); const step = 0.1; scale += (ev.deltaY > 0 ? -step : step); if (scale < 0.1) scale = 0.1; if (scale > 5) scale = 5; apply(); };
|
||||||
|
const onDown = (ev) => { ev.preventDefault(); dragging = true; sx = ev.clientX; sy = ev.clientY; apply(); };
|
||||||
|
const onMove = (ev) => { if (!dragging) return; const dx = ev.clientX - sx, dy = ev.clientY - sy; sx = ev.clientX; sy = ev.clientY; tx += dx; ty += dy; apply(); };
|
||||||
|
const onUp = () => { dragging = false; apply(); };
|
||||||
|
img.addEventListener("wheel", onWheel, { passive: false }); img.addEventListener("mousedown", onDown); document.addEventListener("mousemove", onMove); document.addEventListener("mouseup", onUp); img.addEventListener("click", (ev) => ev.stopPropagation());
|
||||||
|
const onKey = (ev) => { if (ev.key === "Escape") close(); };
|
||||||
|
const close = () => {
|
||||||
|
document.body.style.overflow = "auto";
|
||||||
|
img.removeEventListener("wheel", onWheel);
|
||||||
|
img.removeEventListener("mousedown", onDown);
|
||||||
|
document.removeEventListener("mousemove", onMove);
|
||||||
|
document.removeEventListener("mouseup", onUp);
|
||||||
|
document.removeEventListener("keydown", onKey);
|
||||||
|
mask.remove();
|
||||||
|
};
|
||||||
|
mask.addEventListener("click", (ev)=>{ if (ev.target === mask) close(); });
|
||||||
|
box.addEventListener("click", (ev)=>ev.stopPropagation());
|
||||||
|
const dl = document.createElement("button"); dl.textContent = "下载图片"; Object.assign(dl.style, { position: "absolute", right: "24px", bottom: "24px", zIndex: "10001", padding: "8px 14px", borderRadius: "6px", border: "none", cursor: "pointer", backgroundColor: "#50e3c2", color: "#000" });
|
||||||
|
dl.addEventListener("click", (ev) => { ev.stopPropagation(); const name = (src.split("/").pop() || "image").split("?")[0]; fetch(src).then((r) => r.blob()).then((blob) => { const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = name || "image"; document.body.appendChild(a); a.click(); a.remove(); setTimeout(()=>URL.revokeObjectURL(url),0); }).catch(() => { const a = document.createElement("a"); a.href = src; a.target = "_blank"; document.body.appendChild(a); a.click(); a.remove(); }); });
|
||||||
|
box.appendChild(dl);
|
||||||
|
document.body.appendChild(mask);
|
||||||
|
document.addEventListener("keydown", onKey);
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!customElements.get("preview-image")) customElements.define("preview-image", PreviewImage);
|
||||||
|
// 3. 暴露统一对象(可使用 previewImage.initComponent(url))
|
||||||
|
PreviewImage.initComponent = function(url){
|
||||||
|
if (window.previewImageComponent) { window.previewImageComponent.init(url); return true; }
|
||||||
|
PreviewImage.open(url); return true;
|
||||||
|
};
|
||||||
|
window.previewImage = PreviewImage;
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: #555555;
|
color: #555555;
|
||||||
line-height: 24px;
|
line-height: 26px;
|
||||||
margin-bottom: 66px;
|
margin-bottom: 66px;
|
||||||
}
|
}
|
||||||
#details .matter .matter-left .html a {
|
#details .matter .matter-left .html a {
|
||||||
@@ -177,6 +177,13 @@
|
|||||||
#details .matter .matter-left .html video {
|
#details .matter .matter-left .html video {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
#details .matter .matter-left .html h2 {
|
||||||
|
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
|
||||||
|
font-weight: 650;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
#details .matter .matter-left .last-time {
|
#details .matter .matter-left .last-time {
|
||||||
color: #aaaaaa;
|
color: #aaaaaa;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -1124,6 +1131,7 @@
|
|||||||
height: 80vh;
|
height: 80vh;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.detail-image-mask .detail-image .detail-img {
|
.detail-image-mask .detail-image .detail-img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|||||||
@@ -180,7 +180,7 @@
|
|||||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: #555555;
|
color: #555555;
|
||||||
line-height: 24px;
|
line-height: 26px;
|
||||||
margin-bottom: 66px;
|
margin-bottom: 66px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -204,6 +204,14 @@
|
|||||||
video {
|
video {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
|
||||||
|
font-weight: 650;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.last-time {
|
.last-time {
|
||||||
@@ -1316,6 +1324,7 @@
|
|||||||
height: 80vh;
|
height: 80vh;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-image-mask .detail-image .detail-img {
|
.detail-image-mask .detail-image .detail-img {
|
||||||
|
|||||||
112
css/signIn.css
Normal file
112
css/signIn.css
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: unset;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #eef2f5;
|
||||||
|
}
|
||||||
|
.flexflex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.flexcenter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.flexjcenter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.flexacenter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.flex1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.signInBox-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10005;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox {
|
||||||
|
width: 1060px;
|
||||||
|
height: 658px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
position: relative;
|
||||||
|
filter: drop-shadow(0 -5px 0 #f7c308);
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-head {
|
||||||
|
position: relative;
|
||||||
|
height: 64px;
|
||||||
|
border-bottom: 1px dotted #d7d7d7;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-head .header-bi {
|
||||||
|
width: 83px;
|
||||||
|
height: 99px;
|
||||||
|
position: absolute;
|
||||||
|
top: -61px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-head .header-halo {
|
||||||
|
width: 160px;
|
||||||
|
height: 154px;
|
||||||
|
position: absolute;
|
||||||
|
top: -89px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-head .header-cross {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box {
|
||||||
|
width: 538px;
|
||||||
|
padding: 20px 30px;
|
||||||
|
border-right: 1px dotted #d7d7d7;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box .content-header {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #555555;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box .content-header .bi-img {
|
||||||
|
width: 25px;
|
||||||
|
height: 30px;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box .content-header .bi-value {
|
||||||
|
font-family: Arial-Black, "Arial Black", sans-serif;
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #000000;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box .content-header .bi-text {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #555555;
|
||||||
|
line-height: normal;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.signInBox-mask .signInBox .signInBox-content .left-box .content-header .bi-rule {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
135
css/signIn.less
Normal file
135
css/signIn.less
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: rgba(238, 242, 245, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexflex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexcenter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexjcenter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexacenter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signInBox-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
// background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 10005;
|
||||||
|
|
||||||
|
.signInBox {
|
||||||
|
width: 1060px;
|
||||||
|
height: 658px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
position: relative;
|
||||||
|
filter: drop-shadow(0 -5px 0 rgba(247, 195, 8, 1));
|
||||||
|
|
||||||
|
.signInBox-head {
|
||||||
|
position: relative;
|
||||||
|
height: 64px;
|
||||||
|
|
||||||
|
border-bottom: 1px dotted #d7d7d7;
|
||||||
|
|
||||||
|
.header-bi {
|
||||||
|
width: 83px;
|
||||||
|
height: 99px;
|
||||||
|
position: absolute;
|
||||||
|
top: -61px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-halo {
|
||||||
|
width: 160px;
|
||||||
|
height: 154px;
|
||||||
|
position: absolute;
|
||||||
|
top: -89px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-cross {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.signInBox-content {
|
||||||
|
.left-box {
|
||||||
|
width: 538px;
|
||||||
|
padding: 20px 30px;
|
||||||
|
border-right: 1px dotted #d7d7d7;
|
||||||
|
|
||||||
|
.content-header {
|
||||||
|
font-size: 15px;
|
||||||
|
color: rgb(85, 85, 85);
|
||||||
|
line-height: 40px;
|
||||||
|
|
||||||
|
.bi-img {
|
||||||
|
width: 25px;
|
||||||
|
height: 30px;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi-value {
|
||||||
|
font-family: Arial-Black, "Arial Black", sans-serif;
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 28px;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi-text {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #555555;
|
||||||
|
line-height: normal;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi-rule {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container" id="details" v-cloak>
|
<div class="container" id="details" v-cloak>
|
||||||
<div class="templateValue" ref="uniqidRef">uzP1eSyPjvvD</div>
|
<div class="templateValue" ref="uniqidRef">fi88yrHXiDSj</div>
|
||||||
|
|
||||||
<div class="head-top flexacenter">
|
<div class="head-top flexacenter">
|
||||||
<img class="logo" src="https://oss.gter.net/logo" alt="" />
|
<img class="logo" src="https://oss.gter.net/logo" alt="" />
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
|
|
||||||
<div class="title" v-if="info.title">{{ info.title }}</div>
|
<div class="title" v-if="info.title">{{ info.title }}</div>
|
||||||
|
|
||||||
<div class="html" v-html="info.content"></div>
|
<div class="html" v-html="info.content" @click="handleAnswerText"></div>
|
||||||
|
|
||||||
<div class="last-time">最后编辑:{{ updatedTime || timestamp }}</div>
|
<div class="last-time">最后编辑:{{ updatedTime || timestamp }}</div>
|
||||||
<div class="action-bar flexacenter">
|
<div class="action-bar flexacenter">
|
||||||
@@ -482,9 +482,11 @@
|
|||||||
|
|
||||||
<like v-if="isLikeGif"></like>
|
<like v-if="isLikeGif"></like>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="./js/axios.min.js"></script>
|
<script src="./js/axios.min.js"></script>
|
||||||
<script src="./js/public.js"></script>
|
<script src="./js/public.js"></script>
|
||||||
<script type="module" src="./js/details.js"></script>
|
<script type="module" src="./js/details.js"></script>
|
||||||
|
<script type="module" src=" https://app.gter.net/image/gter/commonCom/preview-image/preview.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
BIN
img/halo-icon.png
Normal file
BIN
img/halo-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -89,8 +89,6 @@ const appSectionIndex = createApp({
|
|||||||
|
|
||||||
const checkWConfig = () => {
|
const checkWConfig = () => {
|
||||||
const wConfig = JSON.parse(localStorage.getItem("wConfig")) || {};
|
const wConfig = JSON.parse(localStorage.getItem("wConfig")) || {};
|
||||||
console.log("wConfig", wConfig);
|
|
||||||
|
|
||||||
if (wConfig.time) {
|
if (wConfig.time) {
|
||||||
const time = new Date(wConfig.time);
|
const time = new Date(wConfig.time);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -127,10 +125,11 @@ const appSectionIndex = createApp({
|
|||||||
const data = res.data;
|
const data = res.data;
|
||||||
|
|
||||||
let targetInfo = data.info;
|
let targetInfo = data.info;
|
||||||
console.log("data", data);
|
|
||||||
|
|
||||||
if (!targetInfo.hidden) targetInfo.hidden = 0;
|
if (!targetInfo.hidden) targetInfo.hidden = 0;
|
||||||
|
|
||||||
|
targetInfo.content = '如果你热爱古典文献,又希望在现代职场大展身手——这个项目可能就是你的“本命”!作为香港最正统的中国语言文学项目,它既传承经典,又为你打跨境传播等全新赛道!\n\n<b>🌟 项目核心亮点</b>权威认证:中国语言文学专业认证,考公考编无障碍\n古今结合:深耕古典文献与理论,同时对接AI内容创作等新兴领域\n语言友好:全程中文授课(普通话+粤语),无语言适应压力\n规模可观:每年录取150+,机会相对较多\n\n点击前往 [港校项目库] 查看 \n<a href="https://program.gter.net/details/tf1yFYIBSda7Y5k7s9iHeLVSxDiuYTljNA~~" target="_blank" contenteditable="false">中国语言文学</a>\n手机扫码查看\n[attachimg]1008942[/attachimg]\n\n<b>🎯 谁最适合申请?</b>中文系、汉语言、古代文学等对口专业背景\n希望在教育、传媒、AI内容或国际中文教育领域发展\n看重学校声誉与专业正统性的同学\n<b>💼 毕业出路超多元</b>除了教师、公务员等传统路径,毕业生还活跃于:\n✔ 跨境文化传播\n✔ AI内容策划与生成\n✔ 国际中文教育\n✔ 出版与编辑行业\n<b>📌 申请指南</b>专业背景:严格限定中文相关专业,暂不接受跨专业申请\n成绩要求:985/211同学建议86+\n语言成绩:雅思7.0(小分5.5)即可\n面试体验:氛围轻松,专业问题较少\n<b>💡 内部消息参考</b>前几轮拿到面试邀请的同学基本都能录取\n985背景优势明显,建议尽早提交申请\n双非同学如背景特别匹配也可尝试\n<b>🤝 欢迎交流</b>你对中国文学在AI时代的发展有什么想法?或者对哪个就业方向,申请问题欢迎在评论区分享交流!\n欢迎加入寄托香港群交流\n\n[attachimg]969489[/attachimg]';
|
||||||
|
|
||||||
// 替换换行
|
// 替换换行
|
||||||
targetInfo.content = targetInfo.content?.replace(/\n/g, "<br>") || "";
|
targetInfo.content = targetInfo.content?.replace(/\n/g, "<br>") || "";
|
||||||
|
|
||||||
@@ -177,6 +176,9 @@ const appSectionIndex = createApp({
|
|||||||
|
|
||||||
let html = formattedText;
|
let html = formattedText;
|
||||||
|
|
||||||
|
html = html.replaceAll('<b>', "[b]");
|
||||||
|
html = html.replaceAll('</b>', "[/b]");
|
||||||
|
|
||||||
// 1. 还原换行符为<br>标签
|
// 1. 还原换行符为<br>标签
|
||||||
html = html.replace(/\n/g, "<br>");
|
html = html.replace(/\n/g, "<br>");
|
||||||
|
|
||||||
@@ -190,6 +192,8 @@ const appSectionIndex = createApp({
|
|||||||
// 4. 还原粗体标记为h2标签
|
// 4. 还原粗体标记为h2标签
|
||||||
html = html.replace(/\[b\]([\s\S]*?)\[\/b\]/gi, "<h2>$1</h2>");
|
html = html.replace(/\[b\]([\s\S]*?)\[\/b\]/gi, "<h2>$1</h2>");
|
||||||
|
|
||||||
|
console.log(html);
|
||||||
|
|
||||||
// 5. 统一在单次遍历中按出现顺序替换 attach/attachimg
|
// 5. 统一在单次遍历中按出现顺序替换 attach/attachimg
|
||||||
const byAid = new Map();
|
const byAid = new Map();
|
||||||
imageList.forEach((e) => byAid.set(Number(e.aid), { type: "image", ...e }));
|
imageList.forEach((e) => byAid.set(Number(e.aid), { type: "image", ...e }));
|
||||||
@@ -214,7 +218,7 @@ const appSectionIndex = createApp({
|
|||||||
html = html.replace(/(<span class="blue">[^<]+<\/span>)\s+/gi, '$1 <span class="fill"></span> ');
|
html = html.replace(/(<span class="blue">[^<]+<\/span>)\s+/gi, '$1 <span class="fill"></span> ');
|
||||||
|
|
||||||
// 7. 清理多余的<br>标签
|
// 7. 清理多余的<br>标签
|
||||||
html = html.replace(/<br><br>/g, "<br>");
|
// html = html.replace(/<br><br>/g, "<br>");
|
||||||
|
|
||||||
if (type != "comment") {
|
if (type != "comment") {
|
||||||
byAid.forEach((item, aid) => {
|
byAid.forEach((item, aid) => {
|
||||||
@@ -271,8 +275,6 @@ const appSectionIndex = createApp({
|
|||||||
actions: ["like", "collection"],
|
actions: ["like", "collection"],
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log("res", res);
|
|
||||||
|
|
||||||
const data = res.data;
|
const data = res.data;
|
||||||
const like = data.like;
|
const like = data.like;
|
||||||
const collection = data.collection;
|
const collection = data.collection;
|
||||||
@@ -418,7 +420,6 @@ const appSectionIndex = createApp({
|
|||||||
let commentTotalCount = ref(0);
|
let commentTotalCount = ref(0);
|
||||||
|
|
||||||
const getComment = () => {
|
const getComment = () => {
|
||||||
console.log("commentPage.value", commentPage.value);
|
|
||||||
if (commentPage.value == 0 || isgetCommentSate || !token) return;
|
if (commentPage.value == 0 || isgetCommentSate || !token) return;
|
||||||
isgetCommentSate = true;
|
isgetCommentSate = true;
|
||||||
ajaxGet(`/v2/api/forum/getCommentList?token=${token}&page=${commentPage.value}&limit=20`)
|
ajaxGet(`/v2/api/forum/getCommentList?token=${token}&page=${commentPage.value}&limit=20`)
|
||||||
@@ -439,7 +440,7 @@ const appSectionIndex = createApp({
|
|||||||
if (element.child.length > 0) {
|
if (element.child.length > 0) {
|
||||||
element.child.forEach((el) => {
|
element.child.forEach((el) => {
|
||||||
el["picture"] = [];
|
el["picture"] = [];
|
||||||
el.timestamp = strtimeago(element.created_at, 4);
|
el.timestamp = strtimeago(el.created_at, 4);
|
||||||
el["isReplyBoxShow"] = 0;
|
el["isReplyBoxShow"] = 0;
|
||||||
|
|
||||||
if (el["content"]) el["content"] = restoreHtml(el["content"], el.attachments, "comment");
|
if (el["content"]) el["content"] = restoreHtml(el["content"], el.attachments, "comment");
|
||||||
@@ -518,16 +519,7 @@ const appSectionIndex = createApp({
|
|||||||
const handleAnswerText = (e) => {
|
const handleAnswerText = (e) => {
|
||||||
if (e.target.tagName === "IMG") {
|
if (e.target.tagName === "IMG") {
|
||||||
var src = e.target.getAttribute("src");
|
var src = e.target.getAttribute("src");
|
||||||
const div = document.createElement("div");
|
previewImage.initComponent(src);
|
||||||
div.innerHTML = `<div class="detail-image flexcenter"><img class="detail-img" src="${src}" /></div>`;
|
|
||||||
div.className = "detail-image-mask flexcenter";
|
|
||||||
div.addEventListener("click", () => {
|
|
||||||
document.body.style.overflow = "auto";
|
|
||||||
div.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.appendChild(div);
|
|
||||||
document.body.style.overflow = "hidden";
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -775,8 +767,6 @@ const appSectionIndex = createApp({
|
|||||||
images: image,
|
images: image,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("userInfoWin", userInfoWin.value);
|
|
||||||
|
|
||||||
ajax("/v2/api/forum/postComment", {
|
ajax("/v2/api/forum/postComment", {
|
||||||
content,
|
content,
|
||||||
token,
|
token,
|
||||||
@@ -872,12 +862,10 @@ const appSectionIndex = createApp({
|
|||||||
let target = {};
|
let target = {};
|
||||||
if (i != null) target = list[index]["child"][i];
|
if (i != null) target = list[index]["child"][i];
|
||||||
else target = list[index];
|
else target = list[index];
|
||||||
console.log("target", target);
|
|
||||||
|
|
||||||
editToken.value = target.token || "";
|
editToken.value = target.token || "";
|
||||||
editInput.value = target.content || "";
|
editInput.value = target.content || "";
|
||||||
editPicture.value = target.attachments?.images || [];
|
editPicture.value = target.attachments?.images || [];
|
||||||
console.log("editCommentState", editPicture.value);
|
|
||||||
|
|
||||||
editCommentState.value = true;
|
editCommentState.value = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ const ajax = (url, data) => {
|
|||||||
|
|
||||||
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
if (location.hostname == "127.0.0.1") axios.defaults.headers.common["Authorization"] = "n1pstcsmw6m6bcx49z705xhvduqviw29";
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.post(url, data, {
|
.post(url, data, {
|
||||||
emulateJSON: true,
|
emulateJSON: true,
|
||||||
@@ -67,6 +69,8 @@ const ajaxGet = (url) => {
|
|||||||
|
|
||||||
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
url = url.indexOf("https://") > -1 ? url : forumBaseURL + url;
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
if (location.hostname == "127.0.0.1") axios.defaults.headers.common["Authorization"] = "n1pstcsmw6m6bcx49z705xhvduqviw29";
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.get(
|
.get(
|
||||||
url,
|
url,
|
||||||
|
|||||||
63
js/signIn.js
Normal file
63
js/signIn.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
const { createApp, ref, onMounted, nextTick, onUnmounted, computed, watch, provide } = Vue;
|
||||||
|
|
||||||
|
const appSectionIndex = createApp({
|
||||||
|
setup() {
|
||||||
|
onMounted(() => {
|
||||||
|
console.log("signIn");
|
||||||
|
|
||||||
|
getFirstDay();
|
||||||
|
});
|
||||||
|
|
||||||
|
let dayOfWeek = ref(0); // 当月第一天是星期几
|
||||||
|
let totalDaysInMonth = ref(0); // 当月第一共今天
|
||||||
|
let currentDay = ref(0); // 今天几号
|
||||||
|
let showList = ref([]); // 展示的 签到列表
|
||||||
|
|
||||||
|
const getFirstDay = () => {
|
||||||
|
const firstDayOfMonth = new Date();
|
||||||
|
firstDayOfMonth.setDate(1);
|
||||||
|
// 获取当月第一天是星期几(0 表示星期日,1 表示星期一,依此类推)
|
||||||
|
dayOfWeek.value = firstDayOfMonth.getDay();
|
||||||
|
|
||||||
|
const currentDate = new Date();
|
||||||
|
const currentMonth = currentDate.getMonth() + 1;
|
||||||
|
const currentYear = currentDate.getFullYear();
|
||||||
|
currentDay.value = currentDate.getDate();
|
||||||
|
|
||||||
|
// 获取当前月份的总天数
|
||||||
|
totalDaysInMonth.value = new Date(currentYear, currentMonth, 0).getDate();
|
||||||
|
|
||||||
|
init();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
const init = () => {
|
||||||
|
ajaxGet("https://api.gter.net/v2/api/forum/getSignInfo").then((res) => {
|
||||||
|
if (res.code != 200) return;
|
||||||
|
console.log("res", res);
|
||||||
|
const data = res.data;
|
||||||
|
|
||||||
|
const list = data.list || {};
|
||||||
|
this.getDateList(list);
|
||||||
|
|
||||||
|
const issign = data.issign || 0;
|
||||||
|
if (issign == 1) wx.setStorageSync("signInState", util.getCurrentDate()); // 存储签到时间
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
tips: data.tips || [],
|
||||||
|
integral: Number(data.integral) || 0,
|
||||||
|
token: data.token || "",
|
||||||
|
signnum: data.signnum || 0,
|
||||||
|
signreward: data.signreward || 0,
|
||||||
|
issign,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("integral", this.data.integral);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return { dayOfWeek };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
appSectionIndex.mount("#signInBox");
|
||||||
62
signIn.html
Normal file
62
signIn.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/css/signIn.css">
|
||||||
|
<script src="./js/vue.global.js"></script>
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="signInBox" class="signInBox-mask flexcenter">
|
||||||
|
<div class="signInBox">
|
||||||
|
<div class="signInBox-head">
|
||||||
|
<img class="header-halo" src="/img/halo-icon.png">
|
||||||
|
<img class="header-bi" src="/img/coin-icon.png">
|
||||||
|
<img class="header-cross" src="/img/cross-icon.png">
|
||||||
|
</div>
|
||||||
|
<div class="signInBox-content">
|
||||||
|
<div class="left-box">
|
||||||
|
<div class="content-header">
|
||||||
|
<div class="content-header-left flexcenter">
|
||||||
|
<img class="bi-img" src="/img/coin-icon.png">
|
||||||
|
<div class="bi-value">216</div>
|
||||||
|
<div class="bi-text">寄托币</div>
|
||||||
|
<div class="bi-rule" bindtap="cutRing">签到规则</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="calendar">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="calendar-box flexflex">
|
||||||
|
<div class="sign-in-text flexacenter">
|
||||||
|
本月已签到 <span class="sign-in-value">{{ signnum }}</span> 天,共领 <span class="sign-in-value">{{ signreward }}</span> 寄托币
|
||||||
|
</div>
|
||||||
|
<div class="calendar flexflex">
|
||||||
|
<!-- formerly: 已经过去没有签到 already: 签到 today: 今天 没有签到的 -->
|
||||||
|
<div class="calendar-item flexcenter" v-for="(item, index) in dayOfWeek" :key="index"></div>
|
||||||
|
<div class="calendar-item flexcenter {{ calendarClass[item.type] }}" v-for="(item, index) in dateList" :key="index">
|
||||||
|
{{ item.name }}
|
||||||
|
<img class="yellow-tick" src="https://app.gter.net/image/miniApp/offer/yellow-tick.svg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!islogin" class="sign-in-btn flexcenter" bind:tap="postSign">立即签到</div>
|
||||||
|
<div v-else-if="issign == 1" class="sign-in-btn flexcenter already">今天已签到,明天记得来哦~</div>
|
||||||
|
<div v-else class="sign-in-btn flexcenter" bind:tap="postSign">立即签到</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/axios.min.js"></script>
|
||||||
|
<script src="/js/public.js"></script>
|
||||||
|
<script src="/js/signIn.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user