|
|
@ -1,35 +1,52 @@ |
|
|
<template> |
|
|
<template> |
|
|
<view class="item-container"> |
|
|
<view class="item-container"> |
|
|
<view v-if="bookList.length !== 0" class="count-text"> |
|
|
|
|
|
|
|
|
<!-- 加载状态 --> |
|
|
|
|
|
<view v-if="isLoading" class="loading-container"> |
|
|
|
|
|
<uni-icons type="loading" size="40" color="#01a4fe" spin></uni-icons> |
|
|
|
|
|
<text class="loading-text">加载中...</text> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 内容区域 --> |
|
|
|
|
|
<view v-else> |
|
|
|
|
|
<!-- 图书数量提示 --> |
|
|
|
|
|
<view v-if="bookList.length > 0" class="count-text"> |
|
|
<text>图书数量 ({{ bookList.length }})</text> |
|
|
<text>图书数量 ({{ bookList.length }})</text> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 借阅列表 --> |
|
|
<view class="car-list" v-for="item in bookList" :key="item.barcode"> |
|
|
<view class="car-list" v-for="item in bookList" :key="item.barcode"> |
|
|
<checkbox :checked="item.checked" @click="toggleItem(item)" /> |
|
|
|
|
|
|
|
|
<checkbox :checked="item.checked" @click="toggleItem(item)" class="checkbox" /> |
|
|
|
|
|
|
|
|
<view class="book-item-box"> |
|
|
|
|
|
|
|
|
<view class="book-item-box" @click="toggleItem(item)"> |
|
|
<view class="item-box-left"> |
|
|
<view class="item-box-left"> |
|
|
<image class="img-item" :src="defaultCover" mode="aspectFill" /> |
|
|
|
|
|
|
|
|
<image class="img-item" :src="item.cover || defaultCover" mode="aspectFill" /> |
|
|
</view> |
|
|
</view> |
|
|
<view class="item-box-right"> |
|
|
<view class="item-box-right"> |
|
|
<view class="item-title line-clamp-2">{{ item.title || '暂无标题' }}</view> |
|
|
<view class="item-title line-clamp-2">{{ item.title || '暂无标题' }}</view> |
|
|
<view class="tag-box"> |
|
|
<view class="tag-box"> |
|
|
<text class="item-author">{{ item.author || '佚名' }}</text> |
|
|
<text class="item-author">{{ item.author || '佚名' }}</text> |
|
|
|
|
|
<text v-if="item.callno" class="item-callno">{{ item.callno }}</text> |
|
|
|
|
|
</view> |
|
|
|
|
|
<view class="item-desc"> |
|
|
|
|
|
<text class="return-label">应还时间:</text> |
|
|
|
|
|
<text :class="isOverdue(item.returndate) ? 'overdue-text' : ''">{{ item.returndate || '暂无' }}</text> |
|
|
</view> |
|
|
</view> |
|
|
<view class="item-desc">应还时间:{{ item.returndate || '暂无' }}</view> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 空状态 --> |
|
|
<view class="empty" v-if="bookList.length === 0"> |
|
|
<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> |
|
|
|
|
|
|
|
|
<uni-icons custom-prefix="iconfont" type="icon-kongshuju" size="80" color="#ccc"></uni-icons> |
|
|
|
|
|
<text class="empty-text">暂无借阅图书</text> |
|
|
|
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 底部占位 --> |
|
|
<view class="bottom-placeholder"></view> |
|
|
<view class="bottom-placeholder"></view> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 底部操作栏 --> |
|
|
<view class="car-bottom"> |
|
|
<view class="car-bottom"> |
|
|
<!-- 全选 --> |
|
|
|
|
|
<view class="all-check" @click="toggleAllCheck"> |
|
|
<view class="all-check" @click="toggleAllCheck"> |
|
|
<checkbox :checked="isAllChecked" /> |
|
|
<checkbox :checked="isAllChecked" /> |
|
|
<text style="margin-left:6px">全选</text> |
|
|
<text style="margin-left:6px">全选</text> |
|
|
@ -44,7 +61,7 @@ |
|
|
|
|
|
|
|
|
<script> |
|
|
<script> |
|
|
import { FetchInitScreenSetting } from '@/api/user'; |
|
|
import { FetchInitScreenSetting } from '@/api/user'; |
|
|
import { FetchRdloanlist, FetchRenewbook, FetchDeletebook } from '@/api/book'; |
|
|
|
|
|
|
|
|
import { FetchRdloanlist, FetchRenewbook } from '@/api/book'; |
|
|
import { getCurrentReaderCard } from '@/utils/storage'; |
|
|
import { getCurrentReaderCard } from '@/utils/storage'; |
|
|
|
|
|
|
|
|
export default { |
|
|
export default { |
|
|
@ -53,24 +70,73 @@ export default { |
|
|
bookList: [], |
|
|
bookList: [], |
|
|
defaultCover: '/static/images/default-book.png', |
|
|
defaultCover: '/static/images/default-book.png', |
|
|
screenConfig: {}, |
|
|
screenConfig: {}, |
|
|
|
|
|
isLoading: false, |
|
|
|
|
|
hasFetchedConfig: false |
|
|
}; |
|
|
}; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
onShow() { |
|
|
onShow() { |
|
|
this.getConfigAndList(); |
|
|
|
|
|
|
|
|
this.initPage(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
computed: { |
|
|
computed: { |
|
|
// 全选状态 |
|
|
|
|
|
isAllChecked() { |
|
|
isAllChecked() { |
|
|
return this.bookList.length > 0 && this.bookList.every(item => item.checked); |
|
|
return this.bookList.length > 0 && this.bookList.every(item => item.checked); |
|
|
}, |
|
|
}, |
|
|
// 是否有选中 |
|
|
|
|
|
hasChecked() { |
|
|
hasChecked() { |
|
|
return this.bookList.some(item => item.checked); |
|
|
return this.bookList.some(item => item.checked); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
methods: { |
|
|
methods: { |
|
|
|
|
|
/** |
|
|
|
|
|
* 初始化页面 |
|
|
|
|
|
*/ |
|
|
|
|
|
async initPage() { |
|
|
|
|
|
// 如果已经获取过配置且有数据,直接刷新列表 |
|
|
|
|
|
if (this.hasFetchedConfig && Object.keys(this.screenConfig).length > 0) { |
|
|
|
|
|
await this.getLendingList(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await this.getConfigAndList(); |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取配置并加载列表 |
|
|
|
|
|
*/ |
|
|
async getConfigAndList() { |
|
|
async getConfigAndList() { |
|
|
|
|
|
this.isLoading = true; |
|
|
|
|
|
uni.showLoading({ title: '加载中...' }); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
|
|
|
// 1. 获取配置 |
|
|
|
|
|
await this.fetchScreenConfig(); |
|
|
|
|
|
|
|
|
|
|
|
// 2. 获取读者证 |
|
|
|
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
|
|
|
if (!currentReaderCard) { |
|
|
|
|
|
this.handleNoReaderCard(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3. 加载借阅列表 |
|
|
|
|
|
await this.getLendingList(); |
|
|
|
|
|
this.hasFetchedConfig = true; |
|
|
|
|
|
|
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
console.error('初始化失败:', err); |
|
|
|
|
|
uni.showToast({ title: '初始化失败', icon: 'none' }); |
|
|
|
|
|
} finally { |
|
|
|
|
|
this.isLoading = false; |
|
|
|
|
|
uni.hideLoading(); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取屏幕配置 |
|
|
|
|
|
*/ |
|
|
|
|
|
async fetchScreenConfig() { |
|
|
const res = await FetchInitScreenSetting({ libcode: '1201' }); |
|
|
const res = await FetchInitScreenSetting({ libcode: '1201' }); |
|
|
this.screenConfig = { |
|
|
this.screenConfig = { |
|
|
thirdUrl: res.data.open_lib_http?.context || '', |
|
|
thirdUrl: res.data.open_lib_http?.context || '', |
|
|
@ -79,17 +145,16 @@ export default { |
|
|
sm4Key: res.data.sm4_key?.context || '', |
|
|
sm4Key: res.data.sm4_key?.context || '', |
|
|
opuser: res.data.op_user?.context || 'JH001', |
|
|
opuser: res.data.op_user?.context || 'JH001', |
|
|
}; |
|
|
}; |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
|
|
|
if (currentReaderCard) { |
|
|
|
|
|
this.isBindLibraryCard = true; |
|
|
|
|
|
this.getLendingList(); |
|
|
|
|
|
} else { |
|
|
|
|
|
this.isBindLibraryCard = false; |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理未绑定读者证情况 |
|
|
|
|
|
*/ |
|
|
|
|
|
handleNoReaderCard() { |
|
|
this.bookList = []; |
|
|
this.bookList = []; |
|
|
uni.showModal({ |
|
|
uni.showModal({ |
|
|
title: '提示', |
|
|
title: '提示', |
|
|
content: '请您绑定读者证', |
|
|
|
|
|
|
|
|
content: '请先绑定读者证', |
|
|
confirmText: '去绑定', |
|
|
confirmText: '去绑定', |
|
|
cancelText: '取消', |
|
|
cancelText: '取消', |
|
|
success: (res) => { |
|
|
success: (res) => { |
|
|
@ -100,40 +165,80 @@ export default { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
|
|
|
} catch (err) {} |
|
|
|
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取借阅列表 |
|
|
|
|
|
*/ |
|
|
async getLendingList() { |
|
|
async getLendingList() { |
|
|
|
|
|
uni.showLoading({ title: '加载中...' }); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
// 使用带缓存降级的函数获取读者证 |
|
|
|
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
console.log('当前证:', currentReaderCard); |
|
|
|
|
|
|
|
|
if (!currentReaderCard) { |
|
|
|
|
|
this.bookList = []; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const params = { |
|
|
const params = { |
|
|
...this.screenConfig, |
|
|
...this.screenConfig, |
|
|
rdid: currentReaderCard.bindValue, |
|
|
rdid: currentReaderCard.bindValue, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const res = await FetchRdloanlist(params); |
|
|
const res = await FetchRdloanlist(params); |
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
|
|
|
|
|
|
|
|
// 每条数据加 checked: false 购物车选中状态 |
|
|
|
|
|
|
|
|
// 添加选中状态和封面处理 |
|
|
this.bookList = (result.loanlist || []).map(item => ({ |
|
|
this.bookList = (result.loanlist || []).map(item => ({ |
|
|
...item, |
|
|
...item, |
|
|
checked: false |
|
|
|
|
|
|
|
|
checked: false, |
|
|
|
|
|
cover: this.getBookCover(item) |
|
|
})); |
|
|
})); |
|
|
|
|
|
|
|
|
} catch (err) { |
|
|
} catch (err) { |
|
|
|
|
|
console.error('获取借阅列表失败:', err); |
|
|
uni.showToast({ title: '加载失败', icon: 'none' }); |
|
|
uni.showToast({ title: '加载失败', icon: 'none' }); |
|
|
|
|
|
this.bookList = []; |
|
|
|
|
|
} finally { |
|
|
|
|
|
uni.hideLoading(); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取图书封面(如果有) |
|
|
|
|
|
*/ |
|
|
|
|
|
getBookCover(item) { |
|
|
|
|
|
// 如果有封面信息,返回封面路径 |
|
|
|
|
|
if (item.coverurl) { |
|
|
|
|
|
return item.coverurl; |
|
|
|
|
|
} |
|
|
|
|
|
// 如果有图片相关信息,可以尝试构建封面URL |
|
|
|
|
|
if (item.imgId) { |
|
|
|
|
|
return `/api/fileRelevant/getImg?imgType=2&imgId=${item.imgId}`; |
|
|
} |
|
|
} |
|
|
|
|
|
return null; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 单个勾选(购物车逻辑) |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 判断是否逾期 |
|
|
|
|
|
*/ |
|
|
|
|
|
isOverdue(returndate) { |
|
|
|
|
|
if (!returndate) return false; |
|
|
|
|
|
const today = new Date(); |
|
|
|
|
|
const returnDate = new Date(returndate); |
|
|
|
|
|
return returnDate < today; |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 切换单个选中状态 |
|
|
|
|
|
*/ |
|
|
toggleItem(item) { |
|
|
toggleItem(item) { |
|
|
item.checked = !item.checked; |
|
|
item.checked = !item.checked; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 全选/取消全选 |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 全选/取消全选 |
|
|
|
|
|
*/ |
|
|
toggleAllCheck() { |
|
|
toggleAllCheck() { |
|
|
const isAll = this.isAllChecked; |
|
|
const isAll = this.isAllChecked; |
|
|
this.bookList.forEach(item => { |
|
|
this.bookList.forEach(item => { |
|
|
@ -141,7 +246,9 @@ export default { |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// 一键续借 |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 一键续借 |
|
|
|
|
|
*/ |
|
|
async handleRenew() { |
|
|
async handleRenew() { |
|
|
const checkedBooks = this.bookList.filter(item => item.checked); |
|
|
const checkedBooks = this.bookList.filter(item => item.checked); |
|
|
if (checkedBooks.length === 0) { |
|
|
if (checkedBooks.length === 0) { |
|
|
@ -149,13 +256,17 @@ export default { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const barcodes = checkedBooks.map(item => item.barcode).join('|'); |
|
|
|
|
|
uni.showLoading({ title: '续借中...' }); |
|
|
uni.showLoading({ title: '续借中...' }); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
// 使用带缓存降级的函数获取读者证 |
|
|
|
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
const currentReaderCard = await getCurrentReaderCard(); |
|
|
|
|
|
if (!currentReaderCard) { |
|
|
|
|
|
uni.hideLoading(); |
|
|
|
|
|
uni.showToast({ title: '请先绑定读者证', icon: 'none' }); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const barcodes = checkedBooks.map(item => item.barcode).join('|'); |
|
|
const params = { |
|
|
const params = { |
|
|
...this.screenConfig, |
|
|
...this.screenConfig, |
|
|
rdid: currentReaderCard.bindValue, |
|
|
rdid: currentReaderCard.bindValue, |
|
|
@ -164,22 +275,31 @@ export default { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const res = await FetchRenewbook(params); |
|
|
const res = await FetchRenewbook(params); |
|
|
|
|
|
|
|
|
// 解析接口返回的 data 字符串 |
|
|
|
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
|
|
const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
|
|
|
|
|
|
|
|
|
|
|
await this.handleRenewResult(result); |
|
|
|
|
|
|
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
console.error('续借异常:', err); |
|
|
|
|
|
uni.hideLoading(); |
|
|
|
|
|
uni.showToast({ title: '网络异常,续借失败', icon: 'none' }); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理续借结果 |
|
|
|
|
|
*/ |
|
|
|
|
|
async handleRenewResult(result) { |
|
|
uni.hideLoading(); |
|
|
uni.hideLoading(); |
|
|
|
|
|
|
|
|
if (result.success === true) { |
|
|
if (result.success === true) { |
|
|
// 续借成功 |
|
|
|
|
|
uni.showToast({ |
|
|
uni.showToast({ |
|
|
title: `续借成功!`, |
|
|
|
|
|
|
|
|
title: '续借成功!', |
|
|
icon: 'success' |
|
|
icon: 'success' |
|
|
}); |
|
|
}); |
|
|
// 刷新列表 |
|
|
// 刷新列表 |
|
|
this.getLendingList(); |
|
|
|
|
|
|
|
|
await this.getLendingList(); |
|
|
} else { |
|
|
} else { |
|
|
// 续借失败 → 取后台提示信息 |
|
|
|
|
|
let msg = '续借失败'; |
|
|
let msg = '续借失败'; |
|
|
if (result.messagelist && result.messagelist.length > 0) { |
|
|
if (result.messagelist && result.messagelist.length > 0) { |
|
|
msg = result.messagelist[0].message; |
|
|
msg = result.messagelist[0].message; |
|
|
@ -190,13 +310,7 @@ export default { |
|
|
duration: 3000 |
|
|
duration: 3000 |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
uni.hideLoading(); |
|
|
|
|
|
uni.showToast({ title: '网络异常,续借失败', icon: 'none' }); |
|
|
|
|
|
console.error('续借异常:', err); |
|
|
|
|
|
} |
|
|
} |
|
|
}, |
|
|
|
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
</script> |
|
|
</script> |
|
|
@ -206,62 +320,169 @@ export default { |
|
|
padding: 10px; |
|
|
padding: 10px; |
|
|
background: #f5f6f7; |
|
|
background: #f5f6f7; |
|
|
min-height: 100vh; |
|
|
min-height: 100vh; |
|
|
overflow: hidden; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 加载状态 */ |
|
|
|
|
|
.loading-container { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
height: 60vh; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.loading-text { |
|
|
|
|
|
margin-top: 16px; |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 数量提示 */ |
|
|
.count-text { |
|
|
.count-text { |
|
|
margin-bottom: 10px; |
|
|
margin-bottom: 10px; |
|
|
font-size: 14px; |
|
|
font-size: 14px; |
|
|
color: #333; |
|
|
color: #333; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 列表项 */ |
|
|
.car-list { |
|
|
.car-list { |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: flex-start; |
|
|
align-items: flex-start; |
|
|
overflow-y: auto; |
|
|
|
|
|
margin-bottom: 10px; |
|
|
margin-bottom: 10px; |
|
|
checkbox { |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.checkbox { |
|
|
margin-top: 15px; |
|
|
margin-top: 15px; |
|
|
padding: 0 10px; |
|
|
padding: 0 10px; |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.book-item-box { |
|
|
.book-item-box { |
|
|
flex: 1; |
|
|
flex: 1; |
|
|
background: #fff; |
|
|
background: #fff; |
|
|
border-radius: 8px; |
|
|
border-radius: 8px; |
|
|
padding: 12px; |
|
|
padding: 12px; |
|
|
display: flex; |
|
|
display: flex; |
|
|
.item-box-left { |
|
|
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-box-left { |
|
|
margin-right: 12px; |
|
|
margin-right: 12px; |
|
|
.img-item { |
|
|
|
|
|
|
|
|
flex-shrink: 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.img-item { |
|
|
width: 64px; |
|
|
width: 64px; |
|
|
height: 90px; |
|
|
height: 90px; |
|
|
border-radius: 6px; |
|
|
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; } |
|
|
|
|
|
|
|
|
background: #f5f5f5; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-box-right { |
|
|
|
|
|
flex: 1; |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-title { |
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
font-size: 15px; |
|
|
|
|
|
color: #333; |
|
|
|
|
|
margin-bottom: 6px; |
|
|
|
|
|
line-height: 1.4; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.tag-box { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-wrap: wrap; |
|
|
|
|
|
gap: 6px; |
|
|
|
|
|
margin-bottom: 8px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-author { |
|
|
|
|
|
font-size: 12px; |
|
|
|
|
|
background: #f4f6fc; |
|
|
|
|
|
color: #666; |
|
|
|
|
|
padding: 2px 8px; |
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-callno { |
|
|
|
|
|
font-size: 12px; |
|
|
|
|
|
background: #fff3e0; |
|
|
|
|
|
color: #ff9800; |
|
|
|
|
|
padding: 2px 8px; |
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.item-desc { |
|
|
|
|
|
font-size: 13px; |
|
|
|
|
|
color: #999; |
|
|
|
|
|
margin-top: auto; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.return-label { |
|
|
|
|
|
color: #999; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.overdue-text { |
|
|
|
|
|
color: #ff4444; |
|
|
|
|
|
font-weight: bold; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 空状态 */ |
|
|
|
|
|
.empty { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
flex-direction: column; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
height: calc(100vh - 140px); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.empty-text { |
|
|
|
|
|
margin-top: 20px; |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
color: #999; |
|
|
} |
|
|
} |
|
|
.bottom-placeholder { height: 60px; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 底部占位 */ |
|
|
|
|
|
.bottom-placeholder { |
|
|
|
|
|
height: 80px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 底部操作栏 */ |
|
|
.car-bottom { |
|
|
.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); |
|
|
|
|
|
|
|
|
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 10px rgba(0, 0, 0, 0.05); |
|
|
} |
|
|
} |
|
|
.all-check { display: flex; align-items: center; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.all-check { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
align-items: center; |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
color: #333; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.join-btn { |
|
|
.join-btn { |
|
|
font-size: 14px; color: #fff; |
|
|
|
|
|
background: #01a4fe !important; border-radius: 23px; |
|
|
|
|
|
|
|
|
font-size: 15px; |
|
|
|
|
|
color: #fff; |
|
|
|
|
|
background: #01a4fe !important; |
|
|
|
|
|
border-radius: 23px; |
|
|
padding: 0 30px; |
|
|
padding: 0 30px; |
|
|
&::after{ border: none !important; } |
|
|
|
|
|
&[disabled] { background: #ccc !important; } |
|
|
|
|
|
} |
|
|
|
|
|
.empty { |
|
|
|
|
|
padding: 0 !important; |
|
|
|
|
|
height: calc(100vh - 80px); |
|
|
|
|
|
|
|
|
height: 40px; |
|
|
|
|
|
&::after { |
|
|
|
|
|
border: none !important; |
|
|
|
|
|
} |
|
|
|
|
|
&[disabled] { |
|
|
|
|
|
background: #ccc !important; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |