分页查询,树形查询前端Vue3

index.js

<template>
  <el-config-provider>
    <router-view></router-view>
  </el-config-provider>
</template>

<script setup>
import { ElConfigProvider } from 'element-plus'
</script>

PolicyDetail.vue

<template>
  <div class="policy-detail">
    <el-card>
      <template #header>
        <div class="card-header">
          <h2>{{ policy.name }}</h2>
          <el-button @click="goBack">返回列表</el-button>
        </div>
      </template>
      
      <el-descriptions :column="2" border>
        <el-descriptions-item label="政策类型">{{ policy.type }}</el-descriptions-item>
        <el-descriptions-item label="发布机构">{{ policy.organ }}</el-descriptions-item>
        <el-descriptions-item label="发布日期">{{ policy.pubdata }}</el-descriptions-item>
        <el-descriptions-item label="政策分类">{{ policy.category }}</el-descriptions-item>
        <el-descriptions-item label="适用范围">{{ policy.range }}</el-descriptions-item>
        <el-descriptions-item label="文号">{{ policy.document }}</el-descriptions-item>
        <el-descriptions-item label="主题词" :span="2">{{ policy.theme }}</el-descriptions-item>
        <el-descriptions-item label="关键词" :span="2">{{ policy.keyword }}</el-descriptions-item>
      </el-descriptions>

      <div class="policy-text">
        <h3>政策正文</h3>
        <div class="text-content">{{ policy.text }}</div>
      </div>

      <div v-if="policy.pdf" class="pdf-link">
        <el-link type="primary" :href="policy.pdf" target="_blank">查看PDF文件</el-link>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import axios from 'axios'

const route = useRoute()
const router = useRouter()
const policy = ref({})

const fetchPolicyDetail = async () => {
  try {
    const response = await axios.get(`http://localhost:8090/policy/${route.params.id}`)
    policy.value = response.data
  } catch (error) {
    console.error('获取政策详情失败:', error)
  }
}

const goBack = () => {
  router.back()
}

onMounted(() => {
  fetchPolicyDetail()
})
</script>

<style scoped>
.policy-detail {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.policy-text {
  margin-top: 20px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 4px;
}

.text-content {
  white-space: pre-wrap;
  line-height: 1.6;
}

.pdf-link {
  margin-top: 20px;
  text-align: center;
}
</style>

PolicyList.vue

<template>
  <div class="policy-container">
    <el-container>
      <el-aside width="250px">
        <el-tree
          ref="treeRef"
          :data="typeTree"
          :props="defaultProps"
          @check="handleCheck"
          show-checkbox
          node-key="id"
          default-expand-all
        />
      </el-aside>
      
      <el-main>
        <div class="search-bar">
          <el-input
            v-model="searchKeyword"
            placeholder="请输入关键词搜索"
            class="search-input"
            @keyup.enter="handleSearch"
          >
            <template #append>
              <el-button @click="handleSearch">搜索</el-button>
            </template>
          </el-input>
          <el-button type="primary" @click="handleTypeSearch" style="margin-left: 10px">按分类筛选</el-button>
        </div>

        <el-table :data="policies" border style="width: 100%">
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column prop="name" label="政策名称" />
          <el-table-column prop="type" label="类型" width="120" />
          <el-table-column prop="organ" label="发布机构" width="200" />
          <el-table-column prop="pubdata" label="发布日期" width="120" />
          <el-table-column fixed="right" label="操作" width="120">
            <template #default="scope">
              <el-button link type="primary" @click="viewDetails(scope.row)">查看详情</el-button>
            </template>
          </el-table-column>
        </el-table>

        <div class="pagination">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-main>
    </el-container>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'

const router = useRouter()
const policies = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const searchKeyword = ref('')

const fetchPolicies = async () => {
  try {
    const response = await axios.get('http://localhost:8090/policy/search', {
      params: {
        keyword: searchKeyword.value,
        current: currentPage.value,
        size: pageSize.value
      }
    })
    policies.value = response.data.records
    total.value = response.data.total
  } catch (error) {
    console.error('获取政策列表失败:', error)
  }
}

const handleSearch = () => {
  currentPage.value = 1
  fetchPolicies()
}

const handleSizeChange = (val) => {
  pageSize.value = val
  fetchPolicies()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchPolicies()
}

const viewDetails = (row) => {
  router.push(`/policy/${row.id}`)
}

const typeTree = ref([])
const defaultProps = {
  children: 'children',
  label: 'label'
}

const fetchTypeTree = async () => {
  try {
    const response = await axios.get('http://localhost:8090/policy/types')
    typeTree.value = response.data
  } catch (error) {
    console.error('获取分类树失败:', error)
  }
}

const handleNodeClick = async (data) => {
  try {
    currentPage.value = 1;
    console.log('点击的节点数据:', data);
    console.log('传递的分类名称:', data.label); // 使用label获取type值
    
    const response = await axios.get('http://localhost:8090/policy/search/byType', {
      params: {
        type: data.label, // 改用type字段进行查询
        current: currentPage.value,
        size: pageSize.value
      }
    })
    if (response.data) {
      console.log('接收到的响应数据:', response.data);
      policies.value = response.data.records || []
      total.value = response.data.total || 0
    }
  } catch (error) {
    console.error('按分类获取政策列表失败:', error)
    policies.value = []
    total.value = 0
  }
}

onMounted(() => {
  fetchTypeTree()
  fetchPolicies()
})

const treeRef = ref(null)
const selectedTypes = ref([])

// 替换原来的handleNodeClick为handleCheck
const handleCheck = (data, checked) => {
  console.log('选中的节点:', checked.checkedNodes)
  selectedTypes.value = checked.checkedNodes.map(node => node.label)
}

// 添加新的分类搜索方法
const handleTypeSearch = async () => {
  if (selectedTypes.value.length === 0) {
    ElMessage.warning('请至少选择一个分类')
    return
  }

  try {
    currentPage.value = 1
    console.log('选中的分类:', selectedTypes.value)
    
    const response = await axios.get('http://localhost:8090/policy/search/byTypes', {
      params: {
        types: selectedTypes.value.join(','),
        current: currentPage.value,
        size: pageSize.value
      }
    })
    if (response.data) {
      console.log('接收到的响应数据:', response.data)
      policies.value = response.data.records || []
      total.value = response.data.total || 0
    }
  } catch (error) {
    console.error('按分类获取政策列表失败:', error)
    policies.value = []
    total.value = 0
  }
}
</script>

<style scoped>
.policy-container {
  height: 100vh;
}

.el-aside {
  background-color: #f5f7fa;
  padding: 20px;
  border-right: 1px solid #e6e6e6;
}

.el-main {
  padding: 20px;
}

.search-bar {
  margin-bottom: 20px;
}

.search-input {
  width: 300px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}
</style>

App.vue

<template>
  <el-config-provider>
    <router-view></router-view>
  </el-config-provider>
</template>

<script setup>
import { ElConfigProvider } from 'element-plus'
</script>

main.js

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(ElementPlus)
app.use(router)
app.mount('#app')
posted @ 2025-03-29 19:23  QixunQiu  阅读(23)  评论(0)    收藏  举报