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.
246 lines
6.8 KiB
246 lines
6.8 KiB
<template>
|
|
<view class="item-container">
|
|
<view v-if="bookList.length !== 0" class="count-text">
|
|
<text>图书数量 ({{ bookList.length }})</text>
|
|
</view>
|
|
|
|
<view class="car-list" v-for="item in bookList" :key="item.barcode">
|
|
<checkbox :checked="item.checked" @click="toggleItem(item)" />
|
|
|
|
<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>
|
|
|
|
<view class="empty" v-if="bookList.length === 0">
|
|
<uni-icons style="margin-left: 20px;" custom-prefix="iconfont" type="icon-kongshuju" size="80"></uni-icons>
|
|
<text style="margin-top: 20px;">暂无相关数据</text>
|
|
</view>
|
|
|
|
<view class="bottom-placeholder"></view>
|
|
|
|
<view class="car-bottom">
|
|
<!-- 全选 -->
|
|
<view class="all-check" @click="toggleAllCheck">
|
|
<checkbox :checked="isAllChecked" />
|
|
<text style="margin-left:6px">全选</text>
|
|
</view>
|
|
|
|
<button class="join-btn" @click="handleRenew" :disabled="!hasChecked">
|
|
一键续借
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { FetchInitScreenSetting } from '@/api/user';
|
|
import { FetchRdloanlist, FetchRenewbook, FetchDeletebook } from '@/api/book';
|
|
import { getCurrentReaderCard } from '@/utils/storage';
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
bookList: [],
|
|
defaultCover: '/static/images/default-book.png',
|
|
screenConfig: {},
|
|
};
|
|
},
|
|
onShow() {
|
|
this.getConfigAndList();
|
|
},
|
|
computed: {
|
|
// 全选状态
|
|
isAllChecked() {
|
|
return this.bookList.length > 0 && this.bookList.every(item => item.checked);
|
|
},
|
|
// 是否有选中
|
|
hasChecked() {
|
|
return this.bookList.some(item => item.checked);
|
|
}
|
|
},
|
|
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 || '',
|
|
opuser: res.data.op_user?.context || 'JH001',
|
|
};
|
|
this.getLendingList();
|
|
} catch (err) {}
|
|
},
|
|
|
|
async getLendingList() {
|
|
try {
|
|
// 使用带缓存降级的函数获取读者证
|
|
const currentReaderCard = await getCurrentReaderCard();
|
|
console.log('当前证:', currentReaderCard);
|
|
|
|
const params = {
|
|
...this.screenConfig,
|
|
rdid: currentReaderCard.bindValue,
|
|
};
|
|
const res = await FetchRdloanlist(params);
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
|
|
|
|
// 每条数据加 checked: false 购物车选中状态
|
|
this.bookList = (result.loanlist || []).map(item => ({
|
|
...item,
|
|
checked: false
|
|
}));
|
|
|
|
} catch (err) {
|
|
uni.showToast({ title: '加载失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
// 单个勾选(购物车逻辑)
|
|
toggleItem(item) {
|
|
item.checked = !item.checked;
|
|
},
|
|
|
|
// 全选/取消全选
|
|
toggleAllCheck() {
|
|
const isAll = this.isAllChecked;
|
|
this.bookList.forEach(item => {
|
|
item.checked = !isAll;
|
|
});
|
|
},
|
|
|
|
// 一键续借
|
|
async handleRenew() {
|
|
const checkedBooks = this.bookList.filter(item => item.checked);
|
|
if (checkedBooks.length === 0) {
|
|
uni.showToast({ title: '请选择图书', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
const barcodes = checkedBooks.map(item => item.barcode).join('|');
|
|
uni.showLoading({ title: '续借中...' });
|
|
|
|
try {
|
|
// 使用带缓存降级的函数获取读者证
|
|
const currentReaderCard = await getCurrentReaderCard();
|
|
|
|
const params = {
|
|
...this.screenConfig,
|
|
rdid: currentReaderCard.bindValue,
|
|
barcode: barcodes,
|
|
logtype: '30007'
|
|
};
|
|
|
|
const res = await FetchRenewbook(params);
|
|
|
|
// 解析接口返回的 data 字符串
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
|
|
|
|
uni.hideLoading();
|
|
|
|
if (result.success === true) {
|
|
// 续借成功
|
|
uni.showToast({
|
|
title: `续借成功!`,
|
|
icon: 'success'
|
|
});
|
|
// 刷新列表
|
|
this.getLendingList();
|
|
} else {
|
|
// 续借失败 → 取后台提示信息
|
|
let msg = '续借失败';
|
|
if (result.messagelist && result.messagelist.length > 0) {
|
|
msg = result.messagelist[0].message;
|
|
}
|
|
uni.showToast({
|
|
title: msg,
|
|
icon: 'none',
|
|
duration: 3000
|
|
});
|
|
}
|
|
|
|
} catch (err) {
|
|
uni.hideLoading();
|
|
uni.showToast({ title: '网络异常,续借失败', icon: 'none' });
|
|
console.error('续借异常:', err);
|
|
}
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.item-container {
|
|
padding: 10px;
|
|
background: #f5f6f7;
|
|
min-height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
.count-text {
|
|
margin-bottom: 10px;
|
|
font-size: 14px;
|
|
color: #333;
|
|
}
|
|
.car-list {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
overflow-y: auto;
|
|
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;
|
|
background: #01a4fe !important; border-radius: 23px;
|
|
padding: 0 30px;
|
|
&::after{ border: none !important; }
|
|
&[disabled] { background: #ccc !important; }
|
|
}
|
|
.empty {
|
|
padding: 0 !important;
|
|
height: calc(100vh - 80px);
|
|
}
|
|
</style>
|