| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- <template>
- <div class="forumTop"></div>
- <div style="display: flex; justify-content: center" class="main-content-wrapper">
- <a-card :bordered="false" class="box-width">
- <a-space>
- <div style="display: flex">
- <a-tooltip :getPopupContainer="(trigger) => trigger.parentElement">
- <template #title>
- <span>回到首页</span>
- </template>
- <a-button @click="goToHome">
- <HomeOutlined />
- </a-button>
- </a-tooltip>
- </div>
- <a-input-search
- v-model:value="searchFormState.postTitle"
- placeholder="请输入名称关键词"
- enter-button
- allowClear
- @search="onSearch"
- :maxlength="30"
- />
- <a-select
- v-model:value="typeVal"
- placeholder="所有类型"
- style="width: 110px"
- :options="typeOptionsVal"
- @change="handleChangeVal"
- allowClear
- ></a-select>
- <a-select
- v-if="typeVal == 0"
- v-model:value="typeValue"
- placeholder="所有类型"
- style="width: 100px"
- :options="typeOptions"
- @change="handleChange"
- allowClear
- ></a-select>
- <a-radio-group v-model:value="searchFormState.sortOrder" button-style="solid">
- <a-radio-button
- v-for="module in moduleTypeList"
- :key="module.id"
- :value="module.id"
- @click="moduleClock(module.id, module.type)"
- >
- {{ module.title }}
- </a-radio-button>
- </a-radio-group>
- <a-button type="primary" @click="formRef.onOpen(undefined, searchFormState.sortOrder)">
- <template #icon><plus-outlined /></template>
- 创建新主题
- </a-button>
- </a-space>
- <a-table
- ref="table"
- class="mt-2"
- :columns="columns"
- :dataSource="tableData"
- :row-key="(record) => record.id"
- :custom-row="customRow"
- :pagination="false"
- style="width: 100%"
- :loading="tableLoading"
- >
- <template #bodyCell="{ column, record }">
- <template v-if="column.dataIndex === 'postTitle'">
- <div class="forum-list-title one-line">{{ record.postTitle }}</div>
- <div class="forum-list-type">
- {{ postName(record.postType) }} {{ record.typeName ? '|' : '' }} {{ record.typeName }}
- </div>
- <div class="forum-list-content one-line" v-html="record.postContent"></div>
- </template>
- <template v-if="column.dataIndex === 'lastReplyUserAvatar'">
- <div v-if="record.replyCount==0">
- <span>无人回复</span>
- </div>
- <div v-if="record.replyCount>0">
- <a-tooltip :title="record.lastReplyUserNickName" placement="top">
- <a-avatar :src="record.lastReplyUserAvatar"></a-avatar>
- </a-tooltip>
- </div>
- </template>
- <template v-if="column.dataIndex === 'lastReplyTime'">
- <div>{{ formatDateTime(record.lastReplyTime) }}</div>
- </template>
- </template>
- </a-table>
- <div style="text-align: center; cursor: pointer" class="mt-2" @click="moreList">{{ moreText }}</div>
- <Form ref="formRef" @successful="resetLoad()" />
- </a-card>
- </div>
- </template>
- <script setup name="forumList">
- import forumApi from '@/api/forum/forumApi'
- import Form from './form.vue'
- import { parseTime } from '@/utils/exam'
- import { useRoute, useRouter } from 'vue-router'
- import EventBus from "@/utils/EventBus";
- const route = useRoute()
- const router = useRouter()
- const formRef = ref()
- const tableLoading = ref(false)
- let searchFormState = reactive({
- sortOrder: 0,
- postTitle: '',
- postType: route.query.postType ?? null
- })
- const table = ref(null)
- const moduleTypeList = ref([
- {
- title: '最新',
- id: 0,
- type: 1,
- state: 0
- },
- {
- title: '热门',
- id: 1,
- type: 1,
- state: 1
- },
- {
- title: '我发布的',
- id: 2,
- type: 2,
- state: 1
- },
- {
- title: '我回复的',
- id: 3,
- type: 2,
- state: 2
- },
- {
- title: '关于我的',
- id: 4,
- type: 2,
- state: 3
- },
- {
- title: '我点赞的',
- id: 5,
- type: 2,
- state: 4
- }
- ])
- const columns = [
- {
- title: '主题',
- dataIndex: 'postTitle'
- },
- {
- title: '最后回复人',
- dataIndex: 'lastReplyUserAvatar',
- align: 'center',
- width: 120
- },
- {
- title: '回复量',
- dataIndex: 'replyCount',
- align: 'center',
- width: 100
- },
- {
- title: '浏览量',
- dataIndex: 'viewCount',
- align: 'center',
- width: 100
- },
- {
- title: '最后回复时间',
- dataIndex: 'lastReplyTime',
- align: 'center',
- width: 120
- }
- ]
- const typeVal = ref('所有类型')
- const typeOptionsVal = ref([
- {
- label: '普通帖子',
- value: 0
- },
- {
- label: '技术支持',
- value: 1
- },
- {
- label: '内容纠错',
- value: 2
- },
- {
- label: '章节讨论',
- value: 3
- }
- ])
- const pagination = ref({
- current: 1,
- size: 10
- })
- const postName = computed(() => {
- return (val) => {
- return typeOptionsVal.value.find((r) => r.value == val).label
- }
- })
- const typeValue = ref('所有分类')
- const typeOptions = ref([])
- const handleChange = (value) => {
- searchFormState.typeId = value
- resetLoad()
- }
- const handleChangeVal = (value) => {
- searchFormState.postType = value
- searchFormState.typeId = ''
- typeValue.value = '所有分类'
- resetLoad()
- }
- function formatDateTime(val) {
- if (!val) return ''
- return parseTime(val, '{y}-{m}-{d} {h}:{i}:{s}')
- }
- // 查询
- const onSearch = () => {
- resetLoad()
- }
- function customRow(record) {
- return {
- onClick: () => itemSelect(record)
- }
- }
- function itemSelect(record) {
- router.push({
- path: '/forum/detail',
- query: {
- postId: record.postId,
- postType: route.query.postType ?? ''
- }
- })
- }
- function getTypeList() {
- forumApi.forumTypeList().then((data) => {
- typeOptions.value = data.map((r) => {
- return {
- label: r.typeName,
- value: r.typeId,
- ...r
- }
- })
- })
- }
- const exType = ref(1)
- const tableData = ref([])
- const tableTotal = ref(0)
- const resetLoad = () => {
- pagination.value.current = 1
- moreText.value = '加载更多'
- loadData(pagination.value)
- }
- const loadData = (parameter, a) => {
- tableLoading.value = true
- if (exType.value == 2) {
- let postExtend = moduleTypeList.value.find((r) => r.id == searchFormState.sortOrder).state
- return forumApi
- .moreList(Object.assign(parameter, searchFormState, { postExtend: postExtend }))
- .then((data) => {
- tableTotal.value = data.total
- if (a) {
- tableData.value = Object.assign(tableData.value, data.records)
- } else {
- if (data) {
- tableData.value = data.records
- } else {
- tableData.value = []
- }
- }
- })
- .finally(() => {
- tableLoading.value = false
- })
- } else {
- return forumApi
- .forumList(Object.assign(parameter, searchFormState))
- .then((data) => {
- tableTotal.value = data.total
- if (a) {
- tableData.value = tableData.value.concat(data.records)
- } else {
- if (data) {
- tableData.value = data.records
- } else {
- tableData.value = []
- }
- }
- })
- .finally(() => {
- tableLoading.value = false
- })
- }
- }
- // 切换应用标签查询菜单列表
- const moduleClock = (value, t) => {
- exType.value = t
- searchFormState.sortOrder = value
- pagination.value.current = 1
- moreText.value = '加载更多'
- loadData(pagination.value)
- }
- const moreText = ref()
- const moreList = () => {
- if (tableTotal.value > pagination.value.current * pagination.value.size) {
- pagination.value.current += 1
- loadData(pagination.value, 1)
- moreText.value = '加载更多'
- } else {
- moreText.value = '全部加载完成'
- }
- }
- // 定义滚动函数
- const handleScroll = () => {
- const tableContainer = window.document.querySelector('.main-content-wrapper')
- const scrollPosition = tableContainer.scrollTop
- const isBottom = tableContainer.scrollHeight - scrollPosition - 20 < tableContainer.clientHeight
- if (isBottom) {
- if (tableTotal.value > pagination.value.current * pagination.value.size) {
- pagination.value.current += 1
- loadData(pagination.value, 1)
- moreText.value = '加载更多'
- } else {
- moreText.value = '全部加载完成'
- }
- }
- }
- //回到首页
- const goToHome = () => {
- router.push({
- path: '/'
- })
- EventBus.emit('onSetHeader','')
- }
- onMounted(() => {
- getTypeList()
- loadData(pagination.value)
- nextTick(() => {
- // 添加scroll监听
- if (table.value) {
- const tableContainer = window.document.querySelector('.main-content-wrapper')
- tableContainer.addEventListener('scroll', handleScroll)
- }
- })
- })
- onBeforeUnmount(() => {
- // 移除scroll监听
- nextTick(() => {
- if (table.value) {
- const tableContainer = window.document.querySelector('.main-content-wrapper')
- tableContainer.removeEventListener('scroll', handleScroll)
- }
- })
- })
- </script>
- <style scoped>
- .forum-list-title {
- font-size: 16px;
- font-weight: bold;
- }
- .forum-list-type {
- font-size: 12px;
- }
- .forum-list-content {
- font-size: 14px;
- color: #696969;
- }
- .one-line {
- max-width: 900px;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 1;
- line-clamp: 1;
- overflow: hidden;
- }
- .forumTop {
- background-color: #1890ff;
- height: 55px;
- }
- .main-content-wrapper {
- padding: 0px;
- height: calc(100% - 55px);
- }
- .box-width {
- width: 1624px;
- }
- </style>
|