PC-questions-answers/js/index.js
2023-12-01 15:33:30 +08:00

1411 lines
49 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.

// 评论的回答者 提问者
// 列表 hot标签
Object.assign(window, Vue)
const forumApp = Vue.createApp({
setup() {
const baseURL = "https://ask.gter.net"
let type = ref('list') // list details
onMounted(() => {
getUrlParams()
getUserData()
getListClass()
window.addEventListener('scroll', handleScroll);
getHistoricalSearchList()
})
onUnmounted(() => {
window.removeEventListener('keydown', handleKeydown)
window.removeEventListener('scroll', handleScroll);
});
let initParams = {}
// 获取url的参数
const getUrlParams = () => {
const params = {};
const regex = /[?&]([^=#]+)=([^&#]*)/g;
let match;
while ((match = regex.exec(window.location.href))) {
params[match[1]] = decodeURIComponent(match[2]);
}
initParams = params
if (params['uniqid']) getDetails(params['uniqid'])
if (params['keyword']) keyword.value = params['keyword']
if (params['tid']) typePitch.value = params['tid']
getList()
}
// 获取当前url
const getCurrentUrl = () => {
return window.location.href;
}
// 我的 数据 数量
let myCount = ref({}) //
// 获取用户数据
const getUserData = () => {
$ajax("/api/user").then(res => {
if (res.code != 200) return
let data = res.data
myCount.value = data.count
})
}
// 是否是搜索模式
let isSearchMode = ref(false)
// 获取历史记录方法
const getHistoricalSearchList = () => {
const list = localStorage.getItem('historical-Search');
if (list) historicalSearchList.value = JSON.parse(list) || []
else historicalSearchList.value = []
}
// 存入历史记录 随便去重 和 限制长度 方法
const setHistoricalSearchList = () => {
historicalSearchList.value.unshift(keyword.value)
historicalSearchList.value = [...new Set(historicalSearchList.value)]
historicalSearchList.value = historicalSearchList.value.slice(0, 10)
localStorage.setItem('historical-Search', JSON.stringify(historicalSearchList.value));
}
// 搜索点击事件
const searchClick = () => {
if (keyword.value == "") return
setHistoricalSearchList()
page = 1
list.value = []
type.value = 'list'
pitchIndex.value = null
replaceState({ keyword: keyword.value })
searchBlur()
getList()
}
// 搜索获取焦点
const searchFocus = () => {
if (historicalSearchList.value.length == 0) return
historicalSearchState.value = true
}
// 搜索失去焦点
const searchBlur = () => {
setTimeout(() => historicalSearchState.value = false, 300)
}
// 点击历史记录 item
const handleClickHistoricalItem = (value) => {
keyword.value = value
searchClick()
}
// 点击清除搜索
const handleClickClear = () => {
keyword.value = ""
page = 1
list.value = []
type.value = 'list'
pitchIndex.value = null
getList()
deleteState(['keyword'])
}
let historicalSearchState = ref(false) // 历史记录弹窗状态
let historicalSearchList = ref([]) // 历史记录数据
let tabListFixeState = ref(false) // 顶部 类型的 固定状态
const handleScroll = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = document.documentElement.clientHeight;
// 列表下 滑动到底部 获取新数据
// console.log("type.value == 'list'", type.value == 'list', scrollTop + clientHeight, scrollHeight);
// if (scrollTop + clientHeight >= scrollHeight - 40 && type.value == 'list') getList()
// 列表下 滚动到顶部 触发类型的固定状态
if (scrollTop > 115 && type.value == 'list') tabListFixeState.value = true
else tabListFixeState.value = false
}
let keyword = ref('') // 搜索的值
let keywordText = ref('') // 搜索的文本
let list = ref([]) // 列表数据
let page = 1
let total = ref(0) // 回答总数
let loading = false
// 获取列表数据
const getList = () => {
if (page == 0 || loading) return
loading = true
$ajax("/api/lists", {
page,
limit: 20,
keyword: keyword.value,
type: typePitch.value,
}
).then(res => {
if (res.code != 200) return
let data = res.data
list.value = list.value.concat(data.data || [])
total.value = data.count || 0
keywordText.value = keyword.value || ''
page++
if (keyword.value) isSearchMode.value = true
else isSearchMode.value = false
}).finally(() => loading = false)
}
let typeList = ref([])
let typePitch = ref(null)
// 获取分类数据 列表分类
const getListClass = () => {
$ajax("/api/common/typeList").then(res => {
if (res.code != 200) return
let data = res.data
typeList.value = data
console.log("data", data);
getPageHeight()
})
}
let pageHeaderHeight = ref(0) // 头部的高度
let pageListHeight = ref(0) // 底部列表的高度
const getPageHeight = () => {
let pageHeader = document.querySelector("#pageHeader")
// let pageHeader = document.querySelector("#pageHeader")
pageHeaderHeight.value = pageHeader.clientHeight + 10
pageListHeight.value = window.innerHeight - pageHeaderHeight.value
}
let detailsInfo = ref({}) // 详情信息
let detailsIsanswered = ref(0) // 详情信息
let detailsIscollection = ref(0) // 详情信息
let detailsIsmyself = ref(0) // 详情信息
let detailsToken = '' // 详情信息
let detailShare = ref({}) // 详情信息
let detailLoading = ref(false) // 详情加载
// 获取详情
const getDetails = (uniqid, index, isOpenAnswer) => {
if (detailLoading.value) return
detailLoading.value = true
// uniqid = "fubm5CnD05qj" // 标记一下 8yr1m1fOH5CS
detailsInfo.value = {}
answerList.value = []
answerPage.value = 0
$ajax("/api/details", { uniqid }).then(res => {
if (res.code != 200) return
let data = res.data
detailsInfo.value = data['info'] || {}
detailsIsanswered.value = data['isanswered'] || 0
detailsIscollection.value = data['iscollection'] || 0
detailsIsmyself.value = data['ismyself'] || 0
detailsToken = data['token'] || ''
detailShare.value = data['share'] || {}
type.value = 'details'
if (index !== null && index !== undefined) cut(index)
else calculateListIndex(data.info, uniqid)
answerList.value = []
answerPage.value = 1
getAnswerList()
closeAllTransmitState()
if (isOpenAnswer) openIAnswer()
replaceState({ uniqid })
}).finally(() => {
detailLoading.value = false
})
}
//
const calculateListIndex = (info, uniqid) => {
let targetList = [...list.value]
if (targetList.length == 0 && isSearchMode.value == false) {
setTimeout(() => calculateListIndex(info, uniqid), 200)
return
}
let valve = false
targetList.forEach((element, index) => {
if (element['uniqid'] == uniqid) {
cut(index)
valve = true
}
})
if (!valve) {
let content = ""
if (info['content'].indexOf('<img') == -1) content = info['content']
list.value.unshift({
answers: info['answers'],
content,
publicationdate: info['publicationdate'],
title: info['title'],
uniqid,
})
cut(0)
}
}
let answerList = ref([]) // 回答列表数据
let answerPage = ref(1) // 回答列表页数
let answerLoading = false // 回答列表加载
// 获取详情的回答数据
const getAnswerList = () => {
if (answerLoading || answerPage.value == 0) return
answerLoading = true
$ajax("/api/details/answerList", { token: detailsToken, limit: 20, page: answerPage.value }).then(res => {
if (res.code != 200) return
let data = res.data
data.data.forEach(element => {
element['commentList'] = []
})
answerList.value = answerList.value.concat(data.data)
if (answerList.value.length == data['count']) answerPage.value = 0
else answerPage.value++
}).finally(() => answerLoading = false)
}
// 操作 - 点赞
const operateLike = (token, index) => {
$ajax("/api/operate/like", { token }).then(res => {
if (res.code != 200) return
let data = res.data
answerList.value[index]['islike'] = data['status']
answerList.value[index]['likenum'] = data['count']
handleMsg('success', res['message'] || '操作成功')
})
}
let isNeedNewColletData = false // 是否需要获取新的收藏数据 ,顶部的我的弹窗需要
// 操作 - 收藏
const operateCollect = (token = detailsToken, index) => {
$ajax("/api/operate/collect", { token }).then(res => {
if (res.code != 200) return
let data = res.data
isNeedNewColletData = true
myCollectionPage = 1
myCollectionList.value = []
if (data['type'] == 'askquestioncollection') detailsIscollection.value = data['status']
else {
answerList.value[index]['iscollection'] = data['status']
answerList.value[index]['collectionnum'] = data['count']
}
handleMsg('success', res['message'] || '操作成功')
if (data['status']) myCount.value['collect']++
else myCount.value['collect']--
})
}
// 操作 - 回答
const operateIAnswer = (token = detailsToken, index) => {
$ajax("/api/publish/answerSubmit", { token }).then(res => {
console.log("res", res);
})
}
let IAnswerState = ref(false) // 我来回答-弹窗的状态
let IAnswerEditState = ref(false) // 编辑回答-弹窗的状态
let IAnswerInfo = ref({}) // 我来回答-弹窗的信息
// 开启我来回答
const openIAnswer = (index, type) => {
if (index == null) {
IAnswerInfo.value = {
title: detailsInfo.value['title'],
content: detailsInfo.value['content'],
anonymous: 0,
}
IAnswerState.value = true
nextTick(() => {
handleInput()
})
} else {
// IAnswerInfo.value = answerList.value[index]
if (type == 'my') {
IAnswerInfo.value = {
title: detailsInfo.value['title'],
...myAnswerList.value[index],
text: myAnswerList.value[index]['content'],
content: detailsInfo.value['content'],
}
myType.value = ""
} else {
IAnswerInfo.value = {
title: detailsInfo.value['title'],
...answerList.value[index],
text: answerList.value[index]['content'],
content: detailsInfo.value['content'],
}
}
IAnswerEditState.value = true
nextTick(() => {
handleInput()
})
}
}
// 关闭我来回答
const closeIAnswer = () => {
IAnswerState.value = false
IAnswerEditState.value = false
}
// 修改我来回答的匿名状态
const amendIAnswer = () => {
IAnswerInfo.value['anonymous'] = IAnswerInfo.value['anonymous'] == 0 ? 1 : 0
}
let isNeedNewAnswersData = false // 是否需要获取新的我的回答数据
// 提交回答
const submitAnswer = () => {
const questionTextarea = document.querySelector(".question-textarea")
IAnswerInfo.value['text'] = questionTextarea.innerHTML
$ajax("/api/publish/answerSubmit", {
token: IAnswerInfo.value['token'] || detailsToken,
anonymous: IAnswerInfo.value['anonymous'] || 0,
content: IAnswerInfo.value['text'],
}).then(res => {
if (res.code == 200) {
answerList.value = []
answerPage.value = 1
getAnswerList()
closeIAnswer()
isNeedNewAnswersData = true
handleMsg('success', res['message'] || '操作成功')
if (!IAnswerInfo.value['token']) myCount.value['answer']++
}
})
}
// 打开回答的评论
const openCommentState = index => {
if (answerList.value[index]['commentState']) answerList.value[index]['commentState'] = false
else answerList.value[index]['commentState'] = true
if (answerList.value[index]['commentList'].length == 0 && answerList.value[index]['commentnum'] != 0) getAnswerCommentList(index)
// answerList.value[index]['commentState'] = true
}
let answerCommentLimit = 3
// 获取回答评论的数据
const getAnswerCommentList = (index) => {
getAnswerCommentPublic(index).then(res => {
let data = res.data
answerList.value[index]['commentList'] = answerList.value[index]['commentList'].concat(data.data)
answerList.value[index]['commentCount'] = data['count']
})
}
// 获取全部评论
const handleAllComment = index => {
answerCommentLimit = 1000
getAnswerCommentPublic(index).then(res => {
if (res.code != 200) return
let data = res.data
let slice3 = data.data.slice(3)
console.log(answerList.value[index]['commentList'], "commentList");
answerList.value[index]['commentList'] = answerList.value[index]['commentList'].concat(data.data.slice(3))
answerList.value[index]['commentList'] = merged
handleMsg('success', res['message'] || '操作成功')
})
}
// 获取评论数据的公共接口
const getAnswerCommentPublic = (index) => {
return new Promise((resolve, reject) => {
$ajax("/api/comment/lists", {
token: answerList.value[index]['token'],
limit: answerCommentLimit,
childlimit: 1,
}).then(res => {
if (res.code != 200) return
resolve(res)
})
})
}
// 提交回答-评论
const submitAnswerComments = (index, ind, i) => {
// answerList.value[index]['commentState'] = true
const targetAnswerList = [...answerList.value]
let content = ""
let parentid = null
let token = targetAnswerList[index]['token']
if (i != null) {
content = targetAnswerList[index]['commentList'][ind]['child'][i]['commentInput']
parentid = targetAnswerList[index]['commentList'][ind]['child'][i]['id']
} else if (ind != null) {
content = targetAnswerList[index]['commentList'][ind]['commentInput']
parentid = targetAnswerList[index]['commentList'][ind]['id']
} else content = targetAnswerList[index]['commentInput']
$ajax("/api/comment/submit", {
content,
token,
parentid,
}).then(res => {
if (res.code != 200) return
let data = res.data
if (i != null) {
let targetData = {
id: data['commentid'],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: {
nickname: targetAnswerList[index]['commentList'][ind]['child'][i]['nickname']
},
...data,
}
targetAnswerList[index]['commentList'][ind]['child'].unshift(targetData)
targetAnswerList[index]['commentList'][ind]['childnum']++
} else if (ind != null) {
let targetData = {
id: data['commentid'],
content,
isauthor: 1,
islike: 0,
likenum: 0,
reply: [],
...data,
}
targetAnswerList[index]['commentList'][ind]['child'].unshift(targetData)
targetAnswerList[index]['commentList'][ind]['childnum']++
} else {
let targetData = {
content,
isauthor: 1,
islike: 0,
likenum: 0,
...data,
child: []
}
targetAnswerList[index]['commentList'].unshift(targetData)
}
closeAnswerCommentsChild()
handleMsg('success', res['message'] || '操作成功')
})
}
// 回答-评论 点赞 operateIAnswer
const operateAnswerCommentsLike = (token, index, ind, i) => {
$ajax("/api/comment/like", {
token,
}).then(res => {
if (res.code != 200) return
let data = res.data
const targetAnswerList = [...answerList.value]
if (i == null) {
targetAnswerList[index]['commentList'][ind]['islike'] = data['status']
targetAnswerList[index]['commentList'][ind]['likenum'] = data['likenum']
} else {
targetAnswerList[index]['commentList'][ind]['child'][i]['islike'] = data['status']
targetAnswerList[index]['commentList'][ind]['child'][i]['likenum'] = data['likenum']
}
answerList.value = targetAnswerList
handleMsg('success', res['message'] || '操作成功')
})
}
// 打开 回答-评论 的子评论
const openAnswerCommentsChild = (index, ind, i) => {
console.log("");
closeAnswerCommentsChild()
if (i == null) {
answerList.value[index].commentList[ind]['childState'] = true
} else {
answerList.value[index].commentList[ind]['child'][i]['childState'] = true
}
}
// 关闭 回答-评论 的子评论
const closeAnswerCommentsChild = (index, ind, i) => {
const targetAnswerList = [...answerList.value]
targetAnswerList.forEach(element => {
if (element['commentList'] && element['commentList'].length != 0) {
element['commentList'].forEach(ele => {
ele['childState'] = false
if (ele['child'] && ele['child'].length != 0) {
ele['child'].forEach(el => {
el['childState'] = false
})
}
})
}
})
answerList.value = targetAnswerList
}
// 获取剩下的子评论
const alsoCommentsData = (index, ind) => {
const targetAnswerList = [...answerList.value]
const parentid = targetAnswerList[index]['commentList'][ind]['id']
const token = targetAnswerList[index]['token']
$ajax("/api/comment/childrenList", {
token,
parentid,
limit: 20,
page: 1,
childlimit: 1,
}).then(res => {
if (res.code != 200) return
let data = res.data
let merged = [...targetAnswerList[index]['commentList'][ind]['child'], ...data.data.filter(item2 => !targetAnswerList[index]['commentList'][ind]['child'].find(item1 => item1.id == item2.id))];
targetAnswerList[index]['commentList'][ind]['child'] = merged
answerList.value = targetAnswerList
})
}
let myType = ref('') // collect answers questions
// 专门处理 我的 弹窗数据
const handleMy = (key) => {
// if ((key == 'collect' && isNeedNewColletData) || (key == 'collect' && myCollectionList.value.length == 0)) {
if (key == 'collect') {
myCollectionList.value = []
myCollectionPage = 1
getMyCollection()
return
} else if (key == 'answers') {
myAnswerList.value = []
myAnswerPage = 1
getMyAnswer()
return
} else if (key == 'questions') {
myQuestionsList.value = []
myQuestionsPage = 1
getMyQuestions()
return
}
// myType.value = key
}
let myCollectionList = ref([]) // 我的收藏列表
let myCollectionCount = ref(0) // 我的收藏数量
let myCollectionPage = 1 // 我的收藏页数
let myCollectionLading = false // 我的收藏加载中
// 获取我的收藏
const getMyCollection = () => {
if (myCollectionPage == 0 || myCollectionLading) return
myCollectionLading = true
$ajax("/api/user/collect", {
limit: 20,
page: myCollectionPage,
}).then(res => {
if (res.code != 200) return
let data = res.data
myType.value = 'collect'
isNeedNewColletData = false
myCollectionList.value = myCollectionList.value.concat(data.data)
myCollectionCount.value = data.count
if (myCollectionList.value.length != data['count']) myCollectionPage++
else myCollectionPage = 0
}).finally(() => myCollectionLading = false)
}
// 取消收藏
const cancelCollection = (token, index) => {
$ajax("/api/user/deleteCollect", { token }).then(res => {
if (res.code == 200) {
myCollectionList.value.splice(index, 1)
myCollectionCount.value--
myCount.value['collect']--
handleMsg('success', res['message'] || '操作成功')
}
})
}
// 监听 我的收藏滚动到底部
const handleCollectionScroll = (e) => {
const el = e.target;
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return
getMyCollection()
}
let myAnswerList = ref([]) // 我的回答数据
let myAnswerCount = ref(0) // 我的回答数量
let myAnswerPage = 1
let myAnswerloadimg = false
// 获取我的回答
const getMyAnswer = () => {
if (myAnswerPage == 0 || myAnswerloadimg) return
myAnswerloadimg = true
$ajax("/api/user/answer", {
limit: 20,
page: myAnswerPage,
}).then(res => {
if (res.code != 200) return
let data = res.data
data.data.forEach(element => {
element['popupState'] = false
})
myAnswerList.value = myAnswerList.value.concat(data.data)
myAnswerCount.value = data.count
if (myAnswerList.value.length != data['count']) myAnswerPage++
else myAnswerPage = 0
myType.value = 'answers'
isNeedNewAnswersData = false
}).finally(() => myAnswerloadimg = false)
}
// 我的回答 的滚动到底部事件
const handleAnswersScroll = e => {
const el = e.target;
// 判断滚动到底部
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return
getMyAnswer()
}
let answerIndexOld = null
// 切换 我的提问的公开匿名 弹窗状态
const cutAnswerPopupState = index => {
myAnswerList.value[index]['popupState'] = true
if (answerIndexOld == index) {
myAnswerList.value[index]['popupState'] = false
answerIndexOld = null
} else {
myAnswerList.value[index]['popupState'] = true
if (answerIndexOld != null) myAnswerList.value[answerIndexOld]['popupState'] = false
answerIndexOld = index
}
}
// 更改匿名状态
const changeAnonymous = (token, anonymous, index) => {
$ajax("/api/publish/changeAnonymous", { token, anonymous }).then(res => {
if (res.code != 200) return
let data = res.data
myAnswerList.value[index]['anonymous'] = anonymous
cutAnswerPopupState(index)
handleMsg('success', res['message'] || '操作成功')
})
}
let myQuestionsList = ref([]) // 我的提问数据
let myQuestionsCount = ref(0) // 我的提问数量
let myQuestionsPage = 0 // 我的提问页数
let myQuestionsloading = false // 我的提问页数
// 获取我的提问
const getMyQuestions = () => {
if (myQuestionsPage == 0 || myQuestionsloading) return
myQuestionsloading = true
$ajax("/api/user/questions", {
limit: 20,
page: myQuestionsPage,
}).then(res => {
if (res.code != 200) return
let data = res.data
myQuestionsList.value = myQuestionsList.value.concat(data.data)
myQuestionsCount.value = data.count
myType.value = 'questions'
if (myQuestionsList.value.length != data['count']) myQuestionsPage++
else myQuestionsPage = 0
}).finally(() => myQuestionsloading = false)
}
// 我的提问 的滚动到底部 事件
const handleQuestionsScroll = e => {
const el = e.target;
// 判断滚动到底部
console.log(el.scrollHeight - el.scrollTop >= el.clientHeight + 10);
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 10) return
getMyQuestions()
}
let questionsIndexOld = null
// 切换 我的提问的公开匿名 弹窗状态
const cutQuestionsPopupState = index => {
myQuestionsList.value[index]['popupState'] = true
if (questionsIndexOld == index) {
myQuestionsList.value[index]['popupState'] = false
questionsIndexOld = null
} else {
myQuestionsList.value[index]['popupState'] = true
if (questionsIndexOld != null) myQuestionsList.value[questionsIndexOld]['popupState'] = false
questionsIndexOld = index
}
}
// 更改匿名状态
const changeAnonymousQuestions = (token, anonymous, index) => {
$ajax("/api/publish/changeAnonymous", { token, anonymous }).then(res => {
if (res.code != 200) return
let data = res.data
myQuestionsList.value[index]['anonymous'] = anonymous
cutQuestionsPopupState(index)
handleMsg('success', res['message'] || '操作成功')
})
}
let questionsSetp = ref(0) // 提问的步骤
// 切换提问步骤
const cutQuestionsSetp = (value) => {
questionsSetp.value = value
}
let questionsTypeList = ref([]) // 提问的类型主题
let questionsObj = ref({ // 提问的内容
token: "",
title: "",
content: "",
tags: "",
tid: "",
anonymous: 0,
})
// 报 提问的初始化
const questionsInit = () => {
$ajax("/api/publish/questions").then(res => {
if (res.code != 200) return
let data = res.data
questionsObj.value['token'] = data['token']
questionsTypeList.value = data['typeList'] || []
console.log("data['typeList']", data['typeList']);
cutQuestionsSetp(1)
})
}
// 选择提问主题
const choosingTheme = (id) => {
questionsObj.value.tid = id
cutQuestionsSetp(2)
}
// 切换匿名状态
const cutAnonymous = () => {
questionsObj.value.anonymous = questionsObj.value.anonymous == 0 ? 1 : 0
}
// 发布问题
const postingIssue = () => {
$ajax("/api/publish/questionsSubmit", questionsObj.value).then(res => {
if (res.code == 200) {
myCount.value['questions']++
questionsSetp.value = 0
questionsObj.value = {
token: "",
title: "",
content: "",
tags: "",
tid: "",
anonymous: 0,
}
handleMsg('success', res['message'] || '操作成功')
let data = res.data
// calculateListIndex(res)
getDetails(data['uniqid'])
return
}
handleMsg('error', res['message'] || '刷新重试!!!')
})
}
let pitchIndex = ref(null) // 选中的下标
// 切换 滚动列表
const cut = index => {
// if (pitchIndex.value == null) type.value = type.value == 'list' ? 'details' : 'list'
pitchIndex.value = index
setTimeout(() => {
scrollLeftInMiddle()
}, 350)
}
// 滚动左边在中间
const scrollLeftInMiddle = () => {
let list = document.querySelector(".list-box")
list.scrollTo({
// top: 128 * pitchIndex.value - pageListHeight.value / 2 - 385,
top: 128 * pitchIndex.value + 68 - pageListHeight.value / 2,
behavior: 'smooth'
})
}
const listStyle = () => {
const newtype = type.value
let width = ""
let margin = ""
if (newtype == 'list') {
width = '1200px'
margin = '0 auto'
} else {
width = 'calc((100vw - 1200px) / 2 + 512px)'
margin = 'initial'
}
return {
width,
margin
}
}
const itemStyle = (index, content) => {
const newtype = type.value
// let itemHeight = content == "" ? 106 : 128
let obj = {}
if (newtype == 'list') {
let top = Math.floor(index / 2) * 128 + 'px'
obj['top'] = top
if (index % 2 == 0) obj['left'] = 0
else obj['left'] = 649 + 'px'
} else {
obj['top'] = index * 128 + 'px'
obj['left'] = 0
obj['width'] = '100%'
// obj['backgroundColor'] = '#fbfbfb'
obj['paddingLeft'] = 'calc((100vw - 1200px) / 2)'
}
return obj
};
// list-box
const listBoxStyle = () => {
const newtype = type.value
let obj = {}
if (newtype == 'list') {
obj['overflow'] = 'visible'
} else {
// obj['height'] = 'calc(100vh - ' + pageHeaderHeight.value + 'px)'
obj['height'] = pageListHeight.value + 'px'
}
return obj
}
const $ajax = (url, data) => {
url = url.indexOf('//') > -1 ? url : baseURL + url;
return new Promise(function (resolve, reject) {
// var xhr = new XMLHttpRequest()
// xhr.responseType = "json"
// xhr.withCredentials = true
// xhr.onreadystatechange = function () {
// if (xhr.readyState === 4) {
// if (xhr.status === 200) {
// if (xhr.response.code != 200) handleMsg('error', xhr.response['message'] || '报错了,请重试!!!')
// resolve(xhr.response)
// } else {
// if (xhr.response.status == 401) window.location.href = 'https://passport.gter.net';
// }
// }
// }
// xhr.open("POST", url, true)
// xhr.setRequestHeader("Content-Type", "application/json")
// xhr.setRequestHeader("authorization", "63c9bef150557f9c90e93f98d2e2497e")
// xhr.send(JSON.stringify(data))
axios.post(url, data, {
emulateJSON: true,
withCredentials: true,
headers: {
authorization: "efd8239b3f9ab533ac59311096738096"
}
}).then(function (res) {
var data = null
try {
data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data;
if (data['code'] != 200) handleMsg('error', data['message'] || '报错了,请重试!!!')
if (data['code'] == 401) window.location.href = 'https://passport.gter.net';
} catch (error) { }
resolve(data)
}).catch(err => {
if (err.response.status == 401) window.location.href = 'https://passport.gter.net';
})
});
}
// 处理时间
const handleDate = (dateTimeStamp = new Date()) => {
dateTimeStamp = dateTimeStamp ? dateTimeStamp : null;
var timestamp = new Date(dateTimeStamp)
timestamp = timestamp.getTime()
var minute = 1000 * 60;
var hour = minute * 60;
var day = hour * 24;
var now = new Date().getTime();
var diffValue = now - timestamp;
var result;
if (diffValue < 0) return;
var dayC = diffValue / day;
var hourC = diffValue / (hour + 1);
var minC = diffValue / minute;
if (dayC >= 7) {
let date = new Date(timestamp);
let Y = date.getFullYear() + '-';
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
result = "" + Y + M + D + h + m;
} else if (dayC >= 1) result = "" + Math.round(dayC) + "天前";
else if (hourC >= 1) result = "" + Math.round(hourC) + "小时前";
else if (minC >= 1) result = "" + Math.round(minC) + "分钟前";
else result = "刚刚";
return result;
}
let questionsTransmitState = ref(false) // 问题的转发 弹窗状态
let questionsTransmitMaskState = ref(false) // 问题的转发 弹窗蒙版状态状态
// 关闭转发状态
const closeTransmitState = () => {
questionsTransmitState.value = true
questionsTransmitMaskState.value = true
countForwardingTimes(detailsToken)
}
// 关闭全部转发状态
const closeAllTransmitState = () => {
answerList.value.forEach(element => {
element['transmitState'] = false
})
questionsTransmitState.value = false
questionsTransmitMaskState.value = false
}
// 开启和关闭回答的转发状态 type open close
const handleAnswerTransmitList = (Iindex, type) => {
answerList.value[Iindex]['transmitState'] = true
questionsTransmitMaskState.value = true
countForwardingTimes(answerList.value[Iindex]['token'])
}
// 统计转发次数
const countForwardingTimes = (token) => {
$ajax("/api/operate/share", { token }).then()
}
// 关闭详情模式
const closeDetailMode = () => {
type.value = 'list'
pitchIndex.value = null
replaceState()
}
// 全部的启动到底部
const handleListScroll = (e) => {
const el = e.target;
if (el.scrollHeight - el.scrollTop >= el.clientHeight + 40) return
getList()
}
// 处理 回答弹窗的复制图片
const handlePaste = (event) => {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (const item of items) {
if (item.type.indexOf('image') === 0) {
// 如果包含图片,阻止默认行为
event.preventDefault();
handleMsg('warning', '上传图片中')
const file = item.getAsFile();
const reader = new FileReader();
reader.onload = (e) => {
const base64 = e.target.result
uploadImg(base64).then(res => {
const questionTextarea = document.querySelector(".question-textarea")
let imgNode = document.createElement('img');
imgNode.setAttribute('src', res.url);
imgNode.setAttribute('data-aid', res.aid);
questionTextarea.appendChild(imgNode);
handleInput()
handleMsg('warning', '上传成功')
})
};
reader.readAsDataURL(file);
}
}
}
// 上传图片 获取图片url
const uploadImg = (base64) => {
return new Promise((resolve, reject) => {
$ajax("/api/common/upload", { data: base64 }).then(res => {
if (res.code != 200) return
let data = res.data
resolve(data)
})
})
}
// 回答 的 placeholder 状态
let questionPlaceholderState = ref(false)
// 回答的输入事件 判断是否显示 placeholder 用
const handleInput = (event) => {
// IAnswerInfo.value['text'] = event.target.innerHTML;
const questionTextarea = document.querySelector(".question-textarea")
const html = questionTextarea.innerHTML
if (html) questionPlaceholderState.value = false
else questionPlaceholderState.value = true
}
let msg = ref({}) // 提示文本的对象 state 类型 type success warning error 显示状态 text 内容
// 调用 提示框方法
const handleMsg = (type, text) => {
msg.value['state'] = true
msg.value['type'] = type
msg.value['text'] = text
}
// 修改提示框类型
const boxClass = () => {
msgShowTimer()
return type ? `box-item-${msg.value['type']}` : ''
}
let msgTimer = null
const msgShowTimer = () => {
clearTimeout(msgTimer)
msgTimer = setTimeout(() => {
msg.value['state'] = false
}, 1000)
}
// 复制
let copyText = text => {
if (navigator.clipboard) {
copyText = () => {
navigator.clipboard.writeText(text)
handleMsg('success', '复制成功')
}
} else {
copyText = () => {
var tempInput = document.createElement("input")
tempInput.value = text
document.body.appendChild(tempInput)
tempInput.select()
document.execCommand("copy")
document.body.removeChild(tempInput)
handleMsg('success', '复制成功')
}
}
copyText()
}
// 修改 url
const replaceState = (obj = {}) => {
// 获取当前URL参数
let params = new URLSearchParams(window.location.search);
for (const key in obj) {
params.set(key, obj[key]);
}
// 替换当前URL但不刷新页面
window.history.replaceState({}, '', `${window.location.pathname}?${params}`);
}
// 删除 url 参数的key
const deleteState = (keys = []) => {
let params = new URLSearchParams(window.location.search);
keys.forEach(key => {
params.delete(key);
})
window.history.replaceState({}, '', `${window.location.pathname}?${params}`);
}
// 我的打开 详情
const myOpenDetails = (value) => {
getDetails(value.data['uniqid'])
myType.value = ""
}
// 详情页滚动事件
const handleDetailsScroll = e => {
const el = e.target;
// 判断滚动到底部
if (el.scrollHeight - el.scrollTop !== el.clientHeight) return
getAnswerList()
}
let dialogSrc = ref("") // 大图的src
// 处理点击答案图片 展开大图
const handleAnswerText = e => {
if (e.target.tagName === 'IMG') {
var src = e.target.getAttribute('src');
dialogSrc.value = src
window.addEventListener('keydown', handleKeydown)
}
}
// 大图的监听 esc 键盘按钮
const handleKeydown = event => {
if (event.key !== 'Escape') return
dialogSrc.value = ""
window.removeEventListener('keydown', handleKeydown) // 取消监听
}
// 切换顶部的 type
const cutType = (id) => {
typePitch.value = id
page = 1
list.value = []
type.value = 'list'
pitchIndex.value = null
if (id != null) {
replaceState({ tid: id })
deleteState(['uniqid'])
} else deleteState(['tid', 'uniqid'])
getList()
}
// 打开举报
const handleMenuState = (index, ind, i) => {
if (i === undefined) reportToken = answerList.value[index].commentList[ind]['token']
else reportToken = answerList.value[index].commentList[ind]['child'][i]['token']
alertShow.value = true
}
// 举报 token
let reportToken = ""
const reasonList = ['广告', '辱骂', '重复发送', '不良信息', '其他']
let checkList = ref([])
let alertShow = ref(false)
let alertText = ref("")
const selectRadio = value => {
const index = checkList.value.indexOf(value);
if (index === -1) checkList.value.push(value);
else checkList.value.splice(index, 1);
}
// 举报提交
const alertSubmit = () => {
checkList.value.push(alertText.value)
$ajax("/api/operate/report", {
message: checkList.value,
token: reportToken,
}).then(res => {
checkList.value = []
reportToken = ""
alertShow.value = false
handleMsg('success', '举报成功')
})
}
return {
handleMenuState,
reasonList,
checkList,
alertShow,
alertText,
selectRadio,
alertSubmit,
cutType,
dialogSrc,
answerPage,
handleDetailsScroll,
replaceState,
copyText,
boxClass,
questionPlaceholderState,
handleInput,
handlePaste,
itemStyle,
listStyle,
listBoxStyle,
myType,
type,
pitchIndex,
cut,
list,
keyword,
keywordText,
getList,
total,
typeList,
typePitch,
getDetails,
detailsInfo,
detailsIsanswered,
detailsIscollection,
detailsIsmyself,
detailShare,
detailLoading,
answerList,
operateLike,
operateCollect,
IAnswerState,
IAnswerEditState,
IAnswerInfo,
amendIAnswer,
openIAnswer,
closeIAnswer,
operateIAnswer,
submitAnswer,
openCommentState,
submitAnswerComments,
operateAnswerCommentsLike,
openAnswerCommentsChild,
closeAnswerCommentsChild,
alsoCommentsData,
handleAllComment,
myCollectionList,
myCollectionCount,
myQuestionsList,
myQuestionsCount,
myAnswerList,
myAnswerCount,
cutAnswerPopupState,
handleDate,
handleCollectionScroll,
handleAnswersScroll,
handleQuestionsScroll,
cancelCollection,
getMyCollection,
questionsSetp,
questionsObj,
cutAnonymous,
cutQuestionsSetp,
cutQuestionsPopupState,
questionsTypeList,
postingIssue,
choosingTheme,
handleMy,
changeAnonymous,
changeAnonymousQuestions,
pageHeaderHeight,
pageListHeight,
questionsTransmitState,
questionsTransmitMaskState,
closeAllTransmitState,
closeTransmitState,
handleAnswerTransmitList,
closeDetailMode,
tabListFixeState,
handleListScroll,
historicalSearchState,
historicalSearchList,
searchFocus,
searchBlur,
searchClick,
handleClickHistoricalItem,
handleClickClear,
isSearchMode,
questionsInit,
myCount,
msg,
myOpenDetails,
handleAnswerText,
getCurrentUrl
};
}
})
forumApp.mount("#answer-app"); //初始化