Compare commits
No commits in common. 'master' and 'main' have entirely different histories.
@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<div class="book-management">
|
||||
<!-- 页面头部 -->
|
||||
<header class="header">
|
||||
<h2>图书管理</h2>
|
||||
<button @click="showAddForm = true" class="btn add-btn">添加图书</button>
|
||||
</header>
|
||||
|
||||
<!-- 添加图书表单弹窗 -->
|
||||
<div v-if="showAddForm" class="modal-overlay">
|
||||
<div class="form-modal">
|
||||
<h3>{{ editMode ? '编辑图书' : '添加图书' }}</h3>
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<label for="bookName">图书标题</label>
|
||||
<input id="bookName" v-model="bookForm.bookName" type="text" required />
|
||||
|
||||
<label for="bookAuthor">作者</label>
|
||||
<input id="bookAuthor" v-model="bookForm.author" type="text" required />
|
||||
|
||||
<label for="bookPrice">价格</label>
|
||||
<input id="bookPrice" v-model="bookForm.price" type="number" required />
|
||||
|
||||
<label for="bookQuantity">库存</label>
|
||||
<input id="bookQuantity" v-model="bookForm.quantity" type="number" required />
|
||||
|
||||
<label for="bookCover">封面图片路径</label>
|
||||
<input id="bookCover" v-model="bookForm.cover" type="text" required />
|
||||
|
||||
<label for="bookType">类型</label>
|
||||
<input id="bookType" v-model="bookForm.type" type="text" required />
|
||||
|
||||
<label for="bookDescription">描述</label>
|
||||
<textarea id="bookDescription" v-model="bookForm.description" required></textarea>
|
||||
|
||||
<div class="form-buttons">
|
||||
<button type="submit" class="btn confirm-btn">{{ editMode ? '确认修改' : '确认添加' }}</button>
|
||||
<button type="button" class="btn cancel-btn" @click="closeForm">取消</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图书列表 -->
|
||||
<div class="book-list">
|
||||
<div class="book-card" v-for="book in bookList" :key="book.book_id">
|
||||
<div class="book-details">
|
||||
<h3>{{ book.bookName }}</h3>
|
||||
<p>作者: {{ book.author }}</p>
|
||||
<p>价格: ¥{{ book.price }}</p>
|
||||
<p>库存: {{ book.quantity }}</p>
|
||||
<p>类型: {{ book.type }}</p>
|
||||
<p>描述: {{ book.description }}</p>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<button @click="editBook(book)" class="btn edit-btn">编辑</button>
|
||||
<button @click="deleteBook(book.book_id)" class="btn delete-btn">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'BookManagement',
|
||||
data() {
|
||||
return {
|
||||
showAddForm: false,
|
||||
editMode: false,
|
||||
bookForm: {
|
||||
bookName: '',
|
||||
author: '',
|
||||
price: 0,
|
||||
quantity: 0,
|
||||
cover: '',
|
||||
type: '',
|
||||
description: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['bookList'])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['ADDBOOK', 'UPDATE_BOOK', 'DELETE_BOOK']),
|
||||
closeForm() {
|
||||
this.showAddForm = false;
|
||||
this.bookForm = {
|
||||
bookName: '',
|
||||
author: '',
|
||||
price: 0,
|
||||
quantity: 0,
|
||||
cover: '',
|
||||
type: '',
|
||||
description: ''
|
||||
};
|
||||
this.editMode = false;
|
||||
},
|
||||
handleSubmit() {
|
||||
if (this.editMode) {
|
||||
const index = this.bookList.findIndex(book => book.book_id === this.bookForm.book_id);
|
||||
this.UPDATE_BOOK({ index, book: { ...this.bookForm } });
|
||||
} else {
|
||||
this.ADDBOOK({ ...this.bookForm, book_id: Date.now() });
|
||||
}
|
||||
this.closeForm();
|
||||
},
|
||||
editBook(book) {
|
||||
this.bookForm = { ...book };
|
||||
this.editMode = true;
|
||||
this.showAddForm = true;
|
||||
},
|
||||
deleteBook(book_id) {
|
||||
this.DELETE_BOOK(book_id);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('showAddForm:', this.showAddForm);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.book-management {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f9;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.header h2 {
|
||||
font-size: 2.5rem;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.book-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 30px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.book-card {
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
padding: 30px;
|
||||
width: 300px;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.book-card:hover {
|
||||
transform: translateY(-10px);
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.book-details h3 {
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 10px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.book-details p {
|
||||
margin: 5px 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.card-actions button {
|
||||
margin: 0;
|
||||
padding: 10px 20px;
|
||||
font-size: 1rem;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card-actions button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
background-color: #1abc9c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.form-modal {
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
padding: 40px;
|
||||
width: 500px;
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.form-modal h3 {
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-modal label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-modal input,
|
||||
.form-modal textarea {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-modal textarea {
|
||||
resize: vertical;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.form-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.form-buttons button {
|
||||
padding: 12px 24px;
|
||||
font-size: 1rem;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.form-buttons button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background-color: #27ae60;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #95a5a6;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
Loading…
Reference in new issue