You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							151 lines
						
					
					
						
							4.6 KiB
						
					
					
				
			
		
		
	
	
							151 lines
						
					
					
						
							4.6 KiB
						
					
					
				<template>
 | 
						|
  <div class="borrow-container">
 | 
						|
    <el-card class="borrow-card">
 | 
						|
      <h2 class="borrow-title">借阅图书</h2>
 | 
						|
      
 | 
						|
      <div class="search-bar">
 | 
						|
        <el-input 
 | 
						|
          v-model="searchKeyword" 
 | 
						|
          placeholder="搜索书名" 
 | 
						|
          clearable
 | 
						|
          @clear="searchBooks"
 | 
						|
          @keyup.enter="searchBooks"
 | 
						|
          class="search-input">
 | 
						|
          <template #append>
 | 
						|
            <el-button :icon="Search" @click="searchBooks" />
 | 
						|
          </template>
 | 
						|
        </el-input>
 | 
						|
      </div>
 | 
						|
      
 | 
						|
      <div class="books-grid">
 | 
						|
        <BookCard 
 | 
						|
          v-for="book in books" 
 | 
						|
          :key="book.id" 
 | 
						|
          :book="book"
 | 
						|
          @click="handleBorrow(book)" />
 | 
						|
      </div>
 | 
						|
      
 | 
						|
      <div class="pagination">
 | 
						|
        <el-pagination
 | 
						|
          v-model:current-page="currentPage"
 | 
						|
          v-model:page-size="pageSize"
 | 
						|
          :total="total"
 | 
						|
          layout="prev, pager, next, jumper"
 | 
						|
          @current-change="fetchBooks"
 | 
						|
          background />
 | 
						|
      </div>
 | 
						|
    </el-card>
 | 
						|
  </div>
 | 
						|
</template>
 | 
						|
 | 
						|
<script setup>
 | 
						|
import { ref, onMounted } from 'vue'
 | 
						|
import { useStore } from 'vuex'
 | 
						|
import { Search } from '@element-plus/icons-vue'
 | 
						|
import BookCard from '@/components/BookCard.vue'
 | 
						|
import { ElMessage } from 'element-plus'
 | 
						|
 | 
						|
const store = useStore()
 | 
						|
 | 
						|
const books = ref([])
 | 
						|
const searchKeyword = ref('')
 | 
						|
const currentPage = ref(1)
 | 
						|
const pageSize = ref(8)
 | 
						|
const total = ref(0)
 | 
						|
 | 
						|
onMounted(() => {
 | 
						|
  fetchBooks()
 | 
						|
})
 | 
						|
 | 
						|
const fetchBooks = async () => {
 | 
						|
  try {
 | 
						|
    const params = {
 | 
						|
      page: currentPage.value,
 | 
						|
      pageSize: pageSize.value,
 | 
						|
      keyword: searchKeyword.value
 | 
						|
    }
 | 
						|
    
 | 
						|
    const response = await store.dispatch('fetchBooks', params)
 | 
						|
    books.value = response.data.list
 | 
						|
    total.value = response.data.total
 | 
						|
  } catch (error) {
 | 
						|
    console.error('获取书籍列表失败:', error)
 | 
						|
    ElMessage.error('获取书籍列表失败')
 | 
						|
     // 预设数据
 | 
						|
     books.value = [
 | 
						|
       { id: 1, title: '三体', url: 'https://picsum.photos/id/24/200/300', money: 5, number: 12, state: '可借', content: '科幻' },
 | 
						|
      { id: 2, title: '人类简史', url: 'https://picsum.photos/id/25/200/300', money: 4, number: 10, state: '可借', content: '历史' },
 | 
						|
      { id: 3, title: '百年孤独', url: 'https://picsum.photos/id/26/200/300', money: 6, number: 0, state: '维护中', content: '文学' },
 | 
						|
      { id: 4, title: '活着', url: 'https://picsum.photos/id/27/200/300', money: 3, number: 15, state: '可借', content: '小说' },
 | 
						|
      { id: 5, title: '追风筝的人', url: 'https://picsum.photos/id/28/200/300', money: 4, number: 9, state: '可借', content: '小说' },
 | 
						|
      { id: 6, title: '解忧杂货店', url: 'https://picsum.photos/id/29/200/300', money: 5, number: 7, state: '可借', content: '小说' },
 | 
						|
      { id: 7, title: '小王子', url: 'https://picsum.photos/id/30/200/300', money: 2, number: 20, state: '可借', content: '童话' },
 | 
						|
      { id: 8, title: '围城', url: 'https://picsum.photos/id/31/200/300', money: 4, number: 18, state: '可借', content: '文学' },
 | 
						|
      { id: 9, title: '月亮与六便士', url: 'https://picsum.photos/id/32/200/300', money: 5, number: 16, state: '可借', content: '小说' },
 | 
						|
      { id: 10, title: '哈利波特', url: 'https://picsum.photos/id/33/200/300', money: 7, number: 25, state: '可借', content: '魔幻' },
 | 
						|
      { id: 11, title: '水浒传', url: 'https://picsum.photos/id/34/200/300', money: 6, number: 14, state: '可借', content: '古典' },
 | 
						|
      { id: 12, title: '三国演义', url: 'https://picsum.photos/id/35/200/300', money: 6, number: 12, state: '可借',content: '古典' }
 | 
						|
    ]
 | 
						|
    total.value = books.value.length
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const searchBooks = () => {
 | 
						|
  currentPage.value = 1
 | 
						|
  fetchBooks()
 | 
						|
}
 | 
						|
 | 
						|
const handleBorrow = async (book) => {
 | 
						|
  try {
 | 
						|
    if (book.number <= 0) {
 | 
						|
      ElMessage.warning('该书籍维护中,无法借阅')
 | 
						|
      return
 | 
						|
    }
 | 
						|
    
 | 
						|
    await store.dispatch('borrowBook', { title: book.title })
 | 
						|
    ElMessage.success(`成功借阅《${book.title}》`)
 | 
						|
    // 刷新列表
 | 
						|
    await fetchBooks()
 | 
						|
  } catch (error) {
 | 
						|
    console.error('借阅失败:', error)
 | 
						|
    ElMessage.error(error.message || '借阅失败')
 | 
						|
  }
 | 
						|
}
 | 
						|
</script>
 | 
						|
 | 
						|
<style scoped>
 | 
						|
.borrow-container {
 | 
						|
  padding: 20px;
 | 
						|
}
 | 
						|
 | 
						|
.borrow-card {
 | 
						|
  padding: 20px;
 | 
						|
}
 | 
						|
 | 
						|
.borrow-title {
 | 
						|
  text-align: center;
 | 
						|
  margin-bottom: 20px;
 | 
						|
}
 | 
						|
 | 
						|
.search-bar {
 | 
						|
  margin-bottom: 20px;
 | 
						|
  display: flex;
 | 
						|
}
 | 
						|
 | 
						|
.search-input {
 | 
						|
  width: 300px;
 | 
						|
}
 | 
						|
 | 
						|
.books-grid {
 | 
						|
  display: grid;
 | 
						|
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
 | 
						|
  gap: 20px;
 | 
						|
  margin-bottom: 30px;
 | 
						|
}
 | 
						|
 | 
						|
.pagination {
 | 
						|
  display: flex;
 | 
						|
  justify-content: center;
 | 
						|
  margin-top: 20px;
 | 
						|
}
 | 
						|
</style> |