// 评论的回答者 提问者
// 列表 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 = ref(false)

        // 获取列表数据
        const getList = () => {
            if (page == 0 || loading.value) return
            loading.value = 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 (list.value.length != data['count']) page++
                else page = 0

                if (keyword.value) isSearchMode.value = true
                else isSearchMode.value = false


            }).finally(() => loading.value = 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

                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']--

            })
        }

        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)
                let merged = [...answerList.value[index]['commentList'], ...slice3.filter(item2 => !answerList.value[index]['commentList'].find(item1 => item1.id == item2.id))];

                // 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 = {
                        id: data['commentid'],
                        content,
                        isauthor: 1,
                        islike: 0,
                        likenum: 0,
                        ...data,
                        child: []
                    }
                    targetAnswerList[index]['commentList'].unshift(targetData)
                    targetAnswerList[index]['commentCount']++
                }

                closeAnswerCommentsChild()

                handleMsg('success', res['message'] || '操作成功')
            })
        }

        // 回答-评论 点赞 
        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) => {
            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;
            // 判断滚动到底部
            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'] || []
                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: "017189d7d01fa8ccf649f36e82807937"   // 头部标记
                    }
                }).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', '举报成功')
            })
        }

        watch(() => {
            if (questionsSetp.value || myType.value || IAnswerEditState.value || IAnswerState.value || dialogSrc.value) document.body.style.overflow = 'hidden'
            else document.body.style.overflow = 'auto'
        })

        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,
            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,
            loading,
        };

    }
})

forumApp.mount("#answer-app"); //初始化