提交 a52045a2 编写于 作者: Y yao_wang

0919

上级 4f159122
<template>
<el-autocomplete
v-model="state"
:fetch-suggestions="querySearch"
popper-class="my-autocomplete"
placeholder="Please input"
@select="handleSelect"
@link-selected="handleLinkSelected"
><!-- 添加监听事件 -->
<template #suffix>
<el-icon class="el-input__icon" @click="handleIconClick">
<edit/>
</el-icon>
</template>
<template #default="{ item }">
<div class="value">{{ item.value }}</div>
<span class="link">{{ item.link }}</span>
</template>
</el-autocomplete>
</template>
<script lang="ts" setup>
import {computed, onMounted, ref} from 'vue'
import {Edit} from '@element-plus/icons-vue'
import {mapState} from "vuex";
import axios from "axios";
interface LinkItem {
value: string
link: string
}
const state = ref('')
const links = ref<LinkItem[]>([])
const querySearch = (queryString: string, cb) => {
const results = queryString
? links.value.filter(createFilter(queryString))
: links.value
// call callback function to return suggestion objects
cb(results)
}
const createFilter = (queryString) => {
return (restaurant) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
)
}
}
const getList = () => {
}
const loadAll = () => {
return axios.get('http://localhost:8000/books/getList/')
.then((res) => {
console.log(res);
console.log(typeof res.data);
if (Array.isArray(res.data)) {
// 响应数据是数组
console.log('Response data is an array');
return res.data; // 返回数据数组
} else {
// 尝试将响应数据转换为数组
const dataArray = Array.from(res.data);
console.log('Response data is not an array, but converted to an array:', dataArray);
return dataArray; // 返回转换后的数组
}
})
.catch((err) => {
console.log(err);
return null;
});
}
// const loadAll = () => {
// return [
// {value: '红与黑', link: 9787544629362},
// {value: '长安的荔枝', link: 9787572608582},
// {value: '三体', link: 9787229166922},
// {value: '明朝那些事(全集)', link: 9787801656179},
// {value: '活着', link: 9787530221532},
// {value: '平凡的世界(全三部)', link: 9787530221396},
// {value: '追风筝的人', link: 9787208061644},
// {value: '杀死一只知更鸟', link: 9787544766500},
// {value: '南京大屠杀', link: 9787508653389},
// {value: '白夜行', link: 9787544258609},
// {value: '白鹿原', link: 9787020090297},
// {value: '我们仨', link: 9787108018809},
// {value: '小王子', link: 9787020042494},
// {value: '一个叫欧维的男人决定去死', link: 9787541142185},
// {value: '置身事内:中国政府与经济发展', link: 9787208171336},
// {value: '围城', link: 9787020127894},
// {value: '东汉至魏晋时期的瘟疫、战争与社会', link: 9787553818016},
// {value: '冰路狂花', link: 9787559861030},
// {value: '写作是一把刀', link: 9787208182721},
// {value: '重读鲁迅', link: 9787308235372},
// {value: '思想之诗', link: 9787559858184},
// {value: '明清白莲教社会历史调查', link: 9787100184168},
// {value: '为书籍的一生', link: 9787108064370},
// {value: '消费图像', link: 9787568938945},
// {value: '杂文的自觉', link: 9787108059345},
// {value: '风痕', link: 9787108075864},
// ]
// }
const emit = defineEmits() // 引入 emit 函数
const handleSelect = (item: LinkItem) => {
// console.log(item)
// 触发自定义事件 'link-selected',并传递选中的 Link 对象
// this.$emit('自定义事件名称', 传递的数据)
emit('link-selected', item)
}
const handleLinkSelected = (linkItem) => {
// 处理选中的 Link 对象
console.log('选中的 Link 对象:', linkItem)
}
const handleIconClick = (ev: Event) => {
console.log(ev)
}
// 在获取数据后手动分配给 links
loadAll().then((data) => {
links.value = data;
});
// onMounted(() => {
// links.value = loadAll();
// // links.value = getList()
// })
</script>
<style scoped>
input {
width: 500px !important;
}
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
.my-autocomplete li .name {
text-overflow: ellipsis;
overflow: hidden;
}
.my-autocomplete li .addr {
font-size: 12px;
color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
color: #ddd;
}
</style>
......@@ -11,25 +11,24 @@ export default {
link: [
{
id: 1,
name: "数字图书",
href: "#"
},
{
id: 2,
name: "热门必读",
href: "/bookList"
},
{
id: 3,
id: 2,
name: "借阅",
href: "/borrowing"
},
{
id: 4,
name: "查询和申报",
id: 3,
name: "用户记录",
href: "/table"
},
{
id: 4,
name: "数据申报",
href: "/modify"
},
]
}
},
......
......@@ -80,7 +80,6 @@ export default {
}
this.books = res.data.books
this.play = true
})
.catch((err) => {
console.log("数据提交失败" + err)
......
<script>
import {mapState} from "vuex";
import axios from "axios";
import Autocomplete from "../nav/autocomplete.vue";
export default {
components: {
Autocomplete,
},
data() {
return {
msg: ''
msg: '000',
play: false,
add: true,
active: '',
isbn: '',
// 空书籍对象,用于清空数据
emptyBook: {},
book: {
bookname: "",
pic: "",
author: "",
isbn: '',
lang: '',
publisher: '',
type: '',
price: '',
intro: '',
updated_time: '',
Listing_time: '',
},
}
},
methods: {
getAuthority() {
axios.post(this.baseUrl + '/user/manage/')
.then((res) => {
console.log(res.data)
console.log(res.data.msg)
this.msg = res.data.msg
if (res.data.code === 200) {
this.play = true
} else {
this.play = false
}
})
.catch((err) => {
console.log(err)
})
},
getBook(link) {
// console.log(link)
let formData = new FormData()
formData.append('way', 'isbn')
formData.append('name', link)
axios.post(this.baseUrl + '/books/query/', formData)
.then((res) => {
if (res.data.books.length === 0) {
alert("未检索到数据")
}
// console.log(res.data.books[0].fields)
this.book = res.data.books[0].fields
})
.catch((err) => {
console.log("数据提交失败" + err)
})
},
handleLinkSelected(linkItem) {
// 在这里处理从子组件传递过来的数据,即选中的 Link 对象
console.log('选中的 Link 对象:', linkItem)
// this.link = linkItem
this.isbn = linkItem.link
this.getBook(linkItem.link)
},
toggle(type) {
if (type === 'false') {
this.add = false
this.book = this.emptyBook
} else {
this.add = true
}
},
submit() {
if (this.add) {
console.log("修改")
const url = this.baseUrl + '/books/fix/'
this.fixBook(url)
}
if (!this.add) {
console.log("添加")
const url = this.baseUrl + '/books/add/'
this.addBook(url)
}
},
fixBook(url) {
axios.post(url, {'isbn': this.link, 'book': this.book})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
},
addBook(url) {
axios.post(url, {'book': this.book})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
}
},
computed: {
......@@ -26,14 +116,131 @@ export default {
},
mounted() {
this.getAuthority()
this.emptyBook = this.book;
console.log(this.emptyBook)
}
}
</script>
<template>
<h1>{{ msg }}</h1>
<h1 v-if="!this.play">{{ this.msg }}</h1>
<div class="box" v-if="this.play">
<div class="row">
<div :class="{'active':add}" @click="toggle('true')"><p>书籍纠错</p></div>
<div :class="{'active':!add}" @click="toggle('false')"><p>增加新书</p></div>
</div>
<div class="block">
<div class="fix" v-if="add">
书籍检索
<Autocomplete @link-selected="handleLinkSelected"></Autocomplete>
</div>
<div class="add" v-else>
<h3>添加图书</h3>
</div>
</div>
<div class="form">
<el-form :model="book" label-width="120px">
<el-form-item label="书名:">
<el-input v-model="book.bookname"/>
</el-form-item>
<el-form-item label="作者:">
<el-input v-model="book.author"/>
</el-form-item>
<el-form-item label="出版社:">
<el-input v-model="book.publisher"/>
</el-form-item>
<el-form-item label="语言:">
<el-input v-model="book.lang"/>
</el-form-item>
<el-form-item label="ISBN:">
<el-input v-model="book.isbn"/>
</el-form-item>
<el-form-item label="类型:">
<el-input v-model="book.type"/>
</el-form-item>
<el-form-item label="定价:">
<el-input v-model.number="book.price"/>
</el-form-item>
<el-form-item label="封面链接:">
<el-input v-model="book.pic"/>
</el-form-item>
<el-form-item label="出版日期:">
<el-input v-model="book.Listing_time" placeholder="YYYY-MM-DD"/>
</el-form-item>
<el-form-item label="介绍:">
<el-input
v-model="book.intro"
:rows="5"
type="textarea"
placeholder="Please input"
/>
<el-button type="primary" class="btn" @click.prevent="submit()">提交</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<style scoped lang="scss">
$aColor: #1A535E;
$btnColor: #38B081;
$bgColor: #ECFBFB;
.box {
background: $bgColor;
padding: 30px;
border-radius: 10px;
}
.block {
.fix {
font-weight: bold;
}
}
.row {
display: flex;
width: 300px;
height: 60px;
line-height: 60px;
color: #919191;
cursor: pointer;
margin-bottom: 30px;
div {
text-align: center;
padding: 5px 10px;
margin-right: 20px;
transition: all .5s ease;
}
}
.active {
border-bottom: 3px solid $aColor;
color: $btnColor;
font-weight: bold;
}
.form {
margin-top: 30px;
width: 600px;
el-form-item {
font-weight: bold;
}
.btn {
padding: 20px 30px;
font-size: 20px;
margin-top: 30px;
}
}
</style>
\ No newline at end of file
<script>
import fixBook from "./fixBook.vue";
import {mapState} from "vuex";
export default {
components:{
fixBook
},
computed: {
...mapState(['baseUrl'])
},
}
</script>
<template>
<div class="container">
<fix-book></fix-book>
</div>
</template>
<style scoped lang="scss">
</style>
\ No newline at end of file
......@@ -28,18 +28,15 @@ export default {
if (type === 'borrow') {
this.borrow = true;
this.buy = false
this.fix = false
this.getRecord('borrow')
} else if (type === 'buy') {
this.borrow = false;
this.buy = true
this.fix = false
this.getRecord('buy')
} else {
this.borrow = false;
this.buy = false
this.fix = true
this.$router.push('/table/fixBook')
}
},
getRecord(type) {
......@@ -122,10 +119,6 @@ export default {
</tbody>
</table>
</div>
<div class="view" v-if="fix">
<router-view></router-view>
</div>
</div>
</div>
......@@ -195,11 +188,5 @@ $bgColor: #ECFBFB;
}
}
}
.fix_view{
padding: 50px 0;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
\ No newline at end of file
......@@ -30,7 +30,7 @@ import axios from "axios";
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
console.log(token)
// console.log(token)
if (token) {
config.headers.Authorization = `Token ${token}`;
}
......
......@@ -6,6 +6,7 @@ import Borrowing from "../components/secondary/borrowing.vue";
import Table from "../components/secondary/table.vue"
import Details from "../components/secondary/details.vue";
import FixBook from "../components/secondary/fixBook.vue";
import Modify from "../components/secondary/modify.vue";
const router = createRouter({
......@@ -14,15 +15,14 @@ const router = createRouter({
{path: '/', component: Home},
{path: '/login', component: Login},
{path: '/bookList', component: BookList},
{path: '/borrowing', component: Borrowing,meta: {requiresAuth: true}},
{path: '/table', component: Table,
{path: '/borrowing', component: Borrowing, meta: {requiresAuth: true}},
{
path: '/table', component: Table,
meta: {requiresAuth: true},
children:[
{path:'fixBook',component:FixBook}
]
},
// meta: {requiresAuth: true} 需要身份认证的路由
{path:'/details',component:Details,meta:{requiresAuth: true}}
{path: '/details', component: Details, meta: {requiresAuth: true}},
{path: '/modify', component: Modify, meta: {requiresAuth: true}}
],
})
......
# 将第一个组数据和第二个组数据分别存储在两个列表中
data1 = [
'红与黑',
'长安的荔枝',
'三体',
'明朝那些事(全集)',
'活着',
'平凡的世界(全三部)',
'追风筝的人',
'杀死一只知更鸟',
'南京大屠杀',
'白夜行',
'白鹿原',
'我们仨',
'小王子',
'一个叫欧维的男人决定去死',
'置身事内:中国政府与经济发展',
'围城',
'东汉至魏晋时期的瘟疫、战争与社会',
'冰路狂花',
'写作是一把刀',
'重读鲁迅',
'思想之诗',
'明清白莲教社会历史调查',
'为书籍的一生',
'消费图像',
'杂文的自觉',
'风痕'
]
data2 = [
9787544629362,
9787572608582,
9787229166922,
9787801656179,
9787530221532,
9787530221396,
9787208061644,
9787544766500,
9787508653389,
9787544258609,
9787020090297,
9787108018809,
9787020042494,
9787541142185,
9787208171336,
9787020127894,
9787553818016,
9787559861030,
9787208182721,
9787308235372,
9787559858184,
9787100184168,
9787108064370,
9787568938945,
9787108059345,
9787108075864,
]
# 创建一个空列表来存储转换后的数据
result = []
# 遍历两个列表,并将它们一一对应转换成所需的形式
for value, link in zip(data1, data2):
book = {'value': value, 'link': link}
result.append(book)
# 打印转换后的数据
for book in result:
print(book)
# Generated by Django 4.2.5 on 2023-09-19 00:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='book',
name='Listing_time',
field=models.DateField(verbose_name='出版时间'),
),
]
......@@ -5,7 +5,7 @@ class Book(models.Model):
bookname = models.CharField('书名', max_length=64)
author = models.CharField("作者", max_length=64)
isbn = models.CharField('ISBN', unique=True, max_length=20)
Listing_time = models.DateTimeField("出版时间")
Listing_time = models.DateField("出版时间")
updated_time = models.DateTimeField("添加时间", auto_now_add=True)
type = models.CharField("类型", max_length=32)
lang = models.CharField("语言", max_length=32)
......
......@@ -4,4 +4,7 @@ from . import views
urlpatterns = [
path('all/', views.all_view),
path('query/',views.query_view),
path('add/', views.add_view),
path('fix/', views.fix_view),
path('getList/', views.getList_view)
]
from books.models import Book
from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponse
import json
......@@ -30,9 +31,21 @@ def all_view(request):
return JsonResponse({"data": data, "pagination_info": pagination_info}, safe=False)
def getList_view(requst):
if requst.method == 'GET':
books = Book.objects.all()
book_list = []
def query_view(request):
for book in books:
book_info = {
'value': book.bookname,
'link': book.isbn
}
book_list.append(book_info)
return HttpResponse(json.dumps(book_list, ensure_ascii=False), content_type='application/json')
def query_view(request):
# 书籍查询,
# 参数:
# name
......@@ -60,3 +73,77 @@ def query_view(request):
# 使用JsonResponse返回数据
return JsonResponse({'books': book_data}, safe=False)
def add_view(request):
if request.method == 'POST':
try:
# 从请求体中解析出前端发送的book对象
data = json.loads(request.body)
book_data = data.get('book', {}) # 假设前端将数据放在名为'book'的字段中
print(book_data)
# 在这里执行保存或处理book数据的逻辑
# 例如,使用Django模型创建新的书籍记录
# 请根据您的模型和业务逻辑来实现
# 以下示例假设您有一个名为Book的Django模型
book_instance = Book(
bookname=book_data.get('bookname'),
pic=book_data.get('pic'),
author=book_data.get('author'),
isbn=book_data.get('isbn'),
lang=book_data.get('lang'),
publisher=book_data.get('publisher'),
type=book_data.get('type'),
price=book_data.get('price'),
intro=book_data.get('intro'),
Listing_time=book_data.get('Listing_time'),
)
book_instance.save()
return JsonResponse({'message': '提交成功'})
except Exception as e:
return JsonResponse({'message': '提交失败', 'error': str(e)})
return JsonResponse({'message': '仅支持POST请求'})
def fix_view(request):
if request.method == 'POST':
try:
# 从请求体中解析出前端发送的book对象
data = json.loads(request.body)
isbn = data.get('isbn', '')
book_data = data.get('book', {}) # 假设前端将数据放在名为'book'的字段中
# 获取要修改的书籍记录
book_isbn = book_data.get('isbn', None) # 假设前端传递了书籍的唯一标识符
if book_isbn is not None:
try:
# 使用ISBN值来查询要修改的书籍记录
book_instance = Book.objects.get(isbn=book_isbn)
# 根据前端发送的book对象更新数据库记录的字段
book_instance.bookname = book_data.get('bookname', book_instance.bookname)
book_instance.pic = book_data.get('pic', book_instance.pic)
book_instance.author = book_data.get('author', book_instance.author)
book_instance.isbn = book_data.get('isbn', book_instance.isbn)
book_instance.lang = book_data.get('lang', book_instance.lang)
book_instance.publisher = book_data.get('publisher', book_instance.publisher)
book_instance.type = book_data.get('type', book_instance.type)
book_instance.price = book_data.get('price', book_instance.price)
book_instance.intro = book_data.get('intro', book_instance.intro)
book_instance.Listing_time = book_data.get('Listing_time', book_instance.Listing_time)
# 保存更新后的数据
book_instance.save()
return JsonResponse({'message': '修改成功'})
except Book.DoesNotExist:
return JsonResponse({'message': '未找到书籍记录'})
else:
return JsonResponse({'message': '未提供书籍ID'})
except Exception as e:
return JsonResponse({'message': '修改失败', 'error': str(e)})
return JsonResponse({'message': '仅支持POST请求'})
......@@ -139,7 +139,12 @@ CORS_ORIGIN_WHITELIST = (
CORE_ALLOW_METHODS = ('DELETE', 'GET', 'POST', 'PUT')
CORS_ALLOWED_ORIGINS = [
"http://10.218.39.118:5173", # 允许跨域请求的前端应用的域名
]
CORS_ALLOW_HEADERS = (
"content-type",
'XMLHttpRequest',
'x_FILENAME',
'accept-encoding',
......
......@@ -83,7 +83,7 @@ def manage_view(request):
if request.method == 'POST':
user_id = request.user.id # 从令牌中解析出user_id
# 获取用户对象,如果不存在则返回404错误页面
print(user_id)
# print(user_id)
try:
user = UserInfo.objects.get(id=user_id)
except UserInfo.DoesNotExist:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册