图书馆小程序
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.
 
 
 
 
 

273 lines
6.7 KiB

<template>
<view class="item-container">
<!-- 图书数量 + 右侧设置按钮 -->
<view class="count-text">
<text>图书数量 ({{ bookList.length }})</text>
<text class="edit-btn" @click="toggleEdit">{{ editMode ? "完成" : "管理" }}</text>
</view>
<checkbox-group @change="checkboxChange">
<view class="car-list" v-for="item in bookList" :key="item.isbn">
<checkbox :value="item.isbn" :checked="item.checked" />
<view class="book-item-box">
<view class="item-box-left">
<image class="img-item" :src="defaultCover" mode="aspectFill" />
</view>
<view class="item-box-right">
<view class="item-title line-clamp-2">{{ item.title || '暂无标题' }}</view>
<view class="tag-box">
<text class="item-author">{{ item.author || '佚名' }}</text>
</view>
<view class="item-desc">
应还时间:{{ item.returndate || '暂无' }}
</view>
</view>
</view>
</view>
</checkbox-group>
<view class="bottom-placeholder"></view>
<view class="car-bottom">
<!-- 全选 -->
<view class="all-check" @click="handleAllCheck">
<checkbox :checked="isAllChecked" />
<text style="margin-left:6px">全选</text>
</view>
<!-- 根据编辑状态切换按钮续借 / 删除 -->
<button
class="join-btn"
@click="editMode ? handleDelete() : handleRenew()"
:disabled="!hasChecked"
>
{{ editMode ? "删除选中" : "一键续借" }}
</button>
</view>
</view>
</template>
<script>
import { FetchInitScreenSetting } from '@/api/user';
import { FetchRdloanlist, FetchRenewbook } from '@/api/book';
export default {
data() {
return {
editMode: false,
bookList: [],
defaultCover: 'https://qiniu.aiyxlib.com/1606124577077',
screenConfig: {},
// 用数组维护选中项(更稳定)
checkedValues: []
};
},
onLoad() {
this.getConfigAndList();
},
computed: {
isAllChecked() {
return this.bookList.length > 0 && this.checkedValues.length === this.bookList.length;
},
hasChecked() {
return this.checkedValues.length > 0;
}
},
methods: {
async getConfigAndList() {
try {
const res = await FetchInitScreenSetting({ libcode: '1201' });
this.screenConfig = {
thirdUrl: res.data.open_lib_http?.context || '',
thirdAppid: res.data.open_lib_appId?.context || '',
thirdSecret: res.data.open_lib_secret?.context || '',
sm4Key: res.data.sm4_key?.context || ''
};
this.getLendingList();
} catch (err) {}
},
async getLendingList() {
try {
const params = {
...this.screenConfig,
rdid: uni.getStorageSync('currentReaderCard'),
};
const res = await FetchRdloanlist(params);
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
this.bookList = result.loanlist || [];
// 切换列表时清空选中
this.checkedValues = [];
} catch (err) {
uni.showToast({ title: '加载失败', icon: 'none' });
}
},
toggleEdit() {
this.editMode = !this.editMode;
if (!this.editMode) {
this.checkedValues = [];
}
},
// ✅ 修复2:稳定的 checkbox 变更
checkboxChange(e) {
// 直接保存数组(字符串类型)
this.checkedValues = e.detail.value;
},
handleAllCheck() {
if (this.isAllChecked) {
// 取消全选
this.checkedValues = [];
} else {
// 全选:把所有 isbn 转字符串放进数组
this.checkedValues = this.bookList.map(item => String(item.isbn));
}
},
async handleRenew() {
// 从 checkedValues 过滤出对应图书
const checkedBooks = this.bookList.filter(item =>
this.checkedValues.includes(String(item.isbn))
);
if (checkedBooks.length === 0) {
uni.showToast({ title: '请选择要续借的图书', icon: 'none' });
return;
}
const barcodes = checkedBooks.map(item => item.barcode).join('|');
uni.showLoading({ title: '续借中...' });
try {
const params = {
...this.screenConfig,
rdid: uni.getStorageSync('currentReaderCard'),
barcode: barcodes,
logtype: '30007'
};
console.log('续借参数', params);
await FetchRenewbook(params);
uni.hideLoading();
uni.showToast({
title: `成功续借 ${checkedBooks.length}`,
icon: 'success'
});
this.getLendingList();
} catch (err) {
uni.hideLoading();
uni.showToast({ title: '续借失败', icon: 'none' });
}
},
handleDelete() {
// 只保留未选中的
this.bookList = this.bookList.filter(item =>
!this.checkedValues.includes(String(item.isbn))
);
uni.showToast({
title: `已删除 ${this.checkedValues.length}`,
icon: "success"
});
this.checkedValues = [];
this.editMode = false;
}
}
};
</script>
<style lang="scss" scss>
.item-container {
padding: 10px;
background: #f5f6f7;
min-height: 100vh;
}
.count-text {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.edit-btn {
color: #01a4fe;
font-size: 14px;
}
.car-list {
display: flex;
align-items: flex-start;
margin-bottom: 10px;
checkbox {
margin-top: 15px;
padding: 0 10px;
}
}
.book-item-box {
flex: 1;
background: #fff;
border-radius: 8px;
padding: 12px;
display: flex;
.item-box-left {
margin-right: 12px;
.img-item {
width: 64px;
height: 90px;
border-radius: 6px;
}
}
.item-box-right {
flex: 1;
}
.item-title {
font-weight: bold;
margin-bottom: 4px;
}
.item-author {
font-size: 12px;
background: #f4f6fc;
padding: 2px 6px;
border-radius: 4px;
margin-right: 6px;
}
.item-desc {
font-size: 12px;
color: #999;
margin-top: 6px;
}
}
.bottom-placeholder {
height: 60px;
}
.car-bottom {
position: fixed;
left: 0;
bottom: 0;
right: 0;
background: #fff;
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
}
.all-check {
display: flex;
align-items: center;
}
.join-btn {
font-size: 14px;
color: #fff;
margin: 0 !important;
background-color: #01a4fe !important;
border-radius: 23px;
padding: 0 30px;
&::after{
border: none !important;
}
&[disabled] {
background: #ccc !important;
}
}
</style>