Files
PC-Light-Forum/component/item-head/item-head.js
DESKTOP-RQ919RC\Pc 51179c3842 refactor: 移除调试日志并优化代码结构
移除多个文件中的console.log调试语句
添加search-tag.css和search-tag.less中的set-hint-box样式
新增recommend.js推荐功能模块
优化ajaxGet调用和用户信息处理逻辑
2025-12-17 19:36:53 +08:00

172 lines
9.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// my-component.js
// 引入全局 Vue 对象(因在 HTML 中通过 script 引入Vue 已挂载到 window
const { defineComponent, ref, provide, onMounted, inject, defineAsyncComponent } = Vue;
// const { report } = await import(withVer("../report/report.js"));
const report = defineAsyncComponent(() => import(withVer("../report/report.js")).then((m) => m.report));
// 定义组件(直接使用模板)
export const itemHead = defineComponent({
name: "item-head",
props: {
itemdata: {
type: Object,
default: () => {},
},
page: {
type: String,
default: "",
},
},
setup(props) {
let sectionn = ref([]);
let tags = ref([]);
let item = ref({ ...props.itemdata });
if (!item.value.hidden) item.value.hidden = 0;
// item.value['best'] = 0
// item.value['recommend'] = 1
let timestamp = ref(strtimeago(item.value.release_at, 4));
if (item.value.type == "tenement") timestamp = timeago(item.value.updatetime, 2);
sectionn.value = item.value.sectionn || [];
const sectionNameSet = new Set(sectionn.value.map((item) => item.name));
tags.value = item.value?.tags || [];
tags.value = tags.value?.filter((tagName) => !sectionNameSet.has(tagName)) || [];
// const sectionSet = new Set(sectionn.value);
// tags.value = item.value.tags?.filter((tag) => !sectionSet.has(tag));
let show = ref(false);
const cutShow = () => {
show.value = !show.value; // 修改为切换显示状态
};
let reportState = ref(false);
provide("reportState", reportState);
let ismanager = ref(false); // 添加管理员状态变量
let permissions = ref([]);
let valueUrl = ref("");
onMounted(() => {
setTimeout(() => {
permissions.value = window["permissions"] || [];
ismanager.value = permissions.value.indexOf("topic:manager") >= 0;
}, 1000);
const valueA = document.querySelector(".valueA");
valueUrl.value = valueA.innerText;
});
// 举报
const report = () => {
cutShow();
reportState.value = true;
};
// 隐藏
const hide = () => {
const target = item.value;
managerHide(target.token, target.hidden, target.type).then((value) => {
target.hidden = value;
item.value = target;
cutShow();
});
};
// 推荐
const recommend = () => {
const target = item.value;
managerRecommend(target.token, target.recommend).then((value) => {
target.recommend = value;
item.value = target;
cutShow();
});
};
// 精华
const essence = () => {
const target = item.value;
managerEssence(target.token, target.best).then((value) => {
target.best = value;
item.value = target;
cutShow();
});
};
// let handleDelete = inject("handleDelete");
let itemHead = ref(null);
// 删除
const deleteItem = () => {
const target = item.value;
managerDelete(target.token)
.then(() => {
const targetNode = itemHead.value;
if (!targetNode) return;
const parentItemBox = targetNode.parentElement;
if (parentItemBox?.classList.contains("item-box")) parentItemBox.style.display = "none";
})
.finally(() => {
cutShow();
});
};
// 编辑
const edit = () => {
const target = item.value;
redirectToExternalWebsite(`/publish?uniqid=${target.uniqid}`);
};
const goPersonalHomepage = (token) => {
if (!token) return;
redirectToExternalWebsite(`/u/${token}`);
};
const openedit = (type) => {
let url = ``;
if (type == "offer") url = `https://offer.gter.net/post/modify?id=${item.value.token}`;
else if (type == "offer_summary") url = `https://offer.gter.net/post/summary`;
redirectToExternalWebsite(url);
};
const anonymousState = ref(false);
const cutAnonymous = () => {
anonymousState.value = !anonymousState.value;
};
const cutAnonymousState = (state) => {
const target = item.value;
ajax("/v2/api/forum/setTopicAnonymousStatus", {
token: target.token,
anonymous: state,
})
.then((res) => {
if (res.code != 200) return;
const data = res.data || {};
target.anonymous = data.anonymous || 0;
item.value = target;
creationAlertBox("success", res.message || "操作成功");
})
.finally(() => {
cutAnonymous();
});
};
return { valueUrl, itemHead, cutAnonymousState, cutAnonymous, anonymousState, openedit, edit, deleteItem, goPersonalHomepage, reportState, cutShow, show, item, timestamp, sectionn, tags, ismanager, report, hide, recommend, essence };
},
components: {
report,
},
template: `<div class="item-head flexacenter" 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"> <img class="item icon" v-if="item.recommend == 1" :src="valueUrl + '/img/recommend-icon.png'" /> <img class="item icon" v-if="item.best == 1" :src="valueUrl + '/img/essence-icon.png'" /> <a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a> <a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a></div><report v-if="reportState" :itemdata="item"></report>`,
});