Files
PC-Light-Forum/component/item-head/item-head.js
DESKTOP-RQ919RC\Pc 003b5992a5 refactor(components): 使用defineAsyncComponent优化异步组件加载
fix(public.js): 添加getScriptParameter函数并处理请求参数
style(index.html): 移除多余空行和注释
perf(bi.js): 移除冗余ajax方法并优化请求参数处理
docs(sign-in.txt): 调整样式和响应式布局
2025-12-05 19:07:33 +08:00

170 lines
8.9 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([]);
onMounted(() => {
setTimeout(() => {
permissions.value = window["permissions"] || [];
ismanager.value = permissions.value.indexOf("topic:manager") >= 0;
}, 1000);
});
// 举报
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) => {
console.log("token", 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) => {
console.log("res", res);
if (res.code != 200) return;
const data = res.data || {};
target.anonymous = data.anonymous || 0;
item.value = target;
creationAlertBox("success", res.message || "操作成功");
})
.finally(() => {
cutAnonymous();
});
};
return { itemHead, cutAnonymousState, cutAnonymous, anonymousState, openedit, edit, deleteItem, goPersonalHomepage, reportState, cutShow, show, item, timestamp, sectionn, tags, ismanager, report, hide, recommend, essence };
},
components: {
report,
},
template: `<div class="item-head flexacenter" 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="/img/pen-icon.png" /> </div> <div class="flexacenter" style="position: relative;"> <div class="anonymous-box flexcenter" @click.stop="cutAnonymous" v-if="page == 'edit' && (item.type == 'vote' || item.type == 'interviewexperience')"> <span v-if="item.anonymous == 0">公开</span> <span v-else>匿名</span> </div> <!-- 是否 公开发表 --> <template v-if="anonymousState"> <div class="mask" @click.stop="cutAnonymous"></div> <div class="isPublicityBox"> <div class="isPublicity-item" :class="{'green': item.anonymous == 0}" @click.stop="cutAnonymousState(0)">公开发表 <img v-if="item.anonymous == 0" class="isPublicityIcon" src="/img/u1829.svg"></image> </div> <div class="isPublicity-item" :class="{'green': item.anonymous != 0}" @click.stop="cutAnonymousState(1)">匿名发表 <img v-if="item.anonymous != 0" class="isPublicityIcon" src="/img/u1829.svg"></image> </div> </div> </template> </div> <div class="view flexacenter"> <img class="icon" src="/img/eye-icon.svg" /> <div class="text">{{ item.views }}</div> </div> <div v-if="item.type != 'tenement'" class="btn flexcenter" @click.stop="cutShow"> <img class="icon" src="/img/dot-dot-dot-gray.png" /> </div> <div v-if="show"> <div class="mask" @click.stop="cutShow"></div> <div class="operate"> <div class="item" @click.stop="report">举报</div> <template v-if="ismanager"> <div class="item" @click.stop="hide">{{ item.hidden == 0 ? "隐藏" : "显示" }}</div> <div class="item" @click.stop="recommend">{{ item.recommend == 1 ? "取消" : "" }}推荐</div> <div class="item" @click.stop="essence">{{ item.best == 1 ? "取消" : "" }}精华</div> </template> <template v-if="item.type == 'thread' && item.ismyself"> <div class="item" @click.stop="edit">编辑</div> <div class="item" @click.stop="deleteItem">删除</div> </template> <div class="item" v-if="page == 'edit' && item.type == 'vote'" @click.stop="deleteItem">删除</div> </div> </div></div><div class="label flexflex" v-if="sectionn?.length || tags?.length || item.recommend == 1 || item.best == 1"> <img class="item icon" v-if="item.recommend == 1" src="/img/recommend-icon.png" /> <img class="item icon" v-if="item.best == 1" src="/img/essence-icon.png" /> <a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a> <a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a></div><report v-if="reportState" :itemdata="item"></report>`,
});