|
|
<template> <view style="padding-bottom: 20px;"> <view class="top-bar"> <uni-icons class="erweima-top" custom-prefix="iconfont" type="icon-erweima" size="22" color="#fff" @click="showTopImgPopup"></uni-icons> <image class="top-bar-bg" src="@/static/images/mingqi-beij@2x.png" mode="aspectFill"></image> <view class="library-info"> <image class="avatar" src="@/static/images/logo.jpg" mode="aspectFill"></image> <view class="library-name">葛店经济技术开发区图书馆</view> </view> <uni-icons class="search-icon" type="search" size="24" @click="onToSearch"></uni-icons> </view>
<view class="status-cards"> <view class="status-card" @click="toBorrowPage(0)"> <view class="status-icon icon-color1" > <uni-icons custom-prefix="iconfont" type="icon-daiban02" size="22"></uni-icons> </view> <view class="status-label">在借中</view> </view> <view class="status-card" @click="toBorrowPage(1)"> <view class="status-icon icon-color4" > <uni-icons custom-prefix="iconfont" type="icon-a-zhidu4" size="22"></uni-icons> </view> <view class="status-label">历史借阅</view> </view> </view>
<swiper class="banner-swiper" interval="3000" circular :vertical="false" :indicator-dots="true" :autoplay="true"> <swiper-item> <image data-post-id="3" src="https://mmbiz.qpic.cn/mmbiz_jpg/bVyA57fUOMicbQqItawJwQlR2oCoYql1icEbuH45ibSAzZsk2T3aDbUOIdMyOOc2CzkYouok0El5u5U3LONACaeNw/640?wx_fmt=jpeg&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1#imgIndex=1"></image> </swiper-item> <swiper-item> <image data-post-id="4" src="https://mmbiz.qpic.cn/sz_mmbiz_gif/tuyGibvSXrsqqiaNpAFJ7lbfGL5vibHtUdV5SUk1RWnlq3QqDe9liaWhdS91L0orEsFxZMiaHOFxDOzINmkiby24fYmmWstiayUgywfVia1pwMcNpBA/640?wx_fmt=gif&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1#imgIndex=3"></image> </swiper-item> </swiper>
<swiper class="menu-swiper" interval="6000" :vertical="false" :autoplay="false"> <swiper-item> <view class="menu-grid"> <view class="menu-item" @click="onToSearch"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-ziyuan" size="22"></uni-icons> </view> <view class="menu-label">书目检索</view> </view> <view class="menu-item" @click="onToLendCar"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-z_renew_normal" size="24"></uni-icons> </view> <view class="menu-label">图书续借</view> </view> <view class="menu-item" @click="toLibraryCard"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-duzhezheng" size="26"></uni-icons> </view> <view class="menu-label">电子证</view> </view> <view class="menu-item" @click="toRanking"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-paihangbang" size="22"></uni-icons> </view> <view class="menu-label">借阅排行</view> </view> <view class="menu-item" @click="toActivityList"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-remenhuodong" size="26"></uni-icons> </view> <view class="menu-label">活动报名</view> </view> <view class="menu-item" @click="toFeedback"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-ruguanyuyue" size="26"></uni-icons> </view> <view class="menu-label">预约入馆</view> </view> <view class="menu-item" @click="onToUser"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-yonghuxinxi-gerenxinxi" size="20"></uni-icons> </view> <view class="menu-label">个人中心</view> </view> <view class="menu-item" @click="goRegister"> <view class="menu-icon"> <uni-icons custom-prefix="iconfont" type="icon-daohang-banzhengxuzhi" size="25"></uni-icons> </view> <view class="menu-label">在线办证</view> </view> </view> </swiper-item> </swiper>
<view v-if="isBindLibraryCard" class="library-card-has"> <view class="section-title">我的借阅证</view> <swiper class="card-swiper" :circular="false" > <swiper-item v-for="item in readerCardList" :key="item.id"> <view class="card-item" @click.stop="showQrcode(item.bindValue)"> <image class="card-left-img" src="@/static/images/card-img2.png" mode="widthFix" /> <view class="card-right-info"> <text class="info-title">读者证号</text> <text class="info-num">{{ formatCardNo(item.bindValue) }}</text> </view> <view class="default-tag" v-if="item.bindDefault">默认证</view> <uni-icons class="erweima-style" custom-prefix="iconfont" type="icon-erweima" size="28"></uni-icons> </view> </swiper-item> </swiper> </view>
<view class="library-card-section" @click="toCheckLogin" v-else> <view class="section-title">借阅证</view> <image class="card-icon" src="@/static/images/card-img2.png"></image> <view class="card-tip">您还没有绑定读者证哦~</view> <button class="bind-btn">立即绑定</button> </view>
<root-portal> <uni-popup ref="popup" type="center" :mask-click="true" @maskClick="closeAllPopup" > <view class="qrcode-popup"> <view class="qrcode-title">读者证二维码</view> <w-qrcode v-if="qrcodeText" :value="qrcodeText" :size="160" foreground="#333" background="#ffffff" /> <view class="qrcode-num" v-if="qrcodeText">{{ qrcodeText }}</view> </view> </uni-popup>
<uni-popup ref="erweimapopup" type="center" :mask-click="true" @maskClick="closeErweiPopup" :custom-style="popupFixedStyle" > <view class="qrcode-popup" style="width: auto !important;"> <image v-if="wecharQRCode" :src="wecharQRCode" style="width:200px;height:200px;" mode="aspectFit" :show-menu-by-longpress="true" @longpress="onQRCodeLongPress" ></image> </view> </uni-popup> </root-portal>
<view class="recommendation-section"> <view class="section-title"> <text class="left-txt">图书推荐</text> <view class="more-link" @click="getMoreBoook" v-if="!(recommendedBooks.length === 0 && !isLoading)"> <text style="margin-right: 5px;">查看更多</text> <uni-icons custom-prefix="iconfont" type="icon-gengduo" size="12"></uni-icons> </view> </view> <view class="recommendation-list"> <uni-load-more status="loading" v-if="isLoading"></uni-load-more> <view v-else class="book-item" v-for="(item,index) in recommendedBooks.slice(0,3)" @click="goToBookDetail(item)" :key="index" > <image class="book-cover" :src="item.coverUrl || '/static/images/default-book.png'" @error="onImgError" ></image> <view class="book-title">{{item.name}}</view> </view> </view> <view class="empty" v-if="recommendedBooks.length === 0 && !isLoading"> <uni-icons custom-prefix="iconfont" type="icon-kongshuju" size="80"></uni-icons> <text style="margin-top: 20px;">暂无推荐书籍~</text> </view> </view> </view></template>
<script>import { FetchInitScreenSetting, FetchOpenId, FetchFindAllReaderBindByOpenId} from '@/api/user';import { FetchInitScreenBookRecommend } from '@/api/book';import config from '@/utils/config';import { STORAGE_KEYS } from '@/utils/storage';
export default { data() { return { isLoading: true, recommendedBooks: [], userInfo: {}, isBindLibraryCard: false, readerCardList: [], baseUrl: config.baseUrl, qrcodeText: '', popupFixedStyle: 'position:fixed;top:0;left:0;right:0;bottom:0;', wecharQRCode: null }; }, onLoad() { this.getRecommendBooks(); this.getScreenSetting() }, onShow() { this.initUserAndCheckBind(); }, methods:{ async getScreenSetting() { const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE }); if (res.data.wechar_qr_code && res.data.wechar_qr_code.context) { // 直接使用图片url,不再转base64
this.wecharQRCode = this.baseUrl + '/api/fileRelevant/getImg?imgType=1&imgId=' + res.data.wechar_qr_code.context; } else { this.wecharQRCode = null; } }, showTopImgPopup() { if (!this.wecharQRCode) { uni.showToast({ title: '暂无图片', icon: 'none' }) return } this.$refs.erweimapopup.open() },
formatCardNo(cardNo) { if (!cardNo) return ''; const str = String(cardNo); const len = str.length;
if (len > 8) { const front = str.substring(0, 2); const end = str.substring(len - 2); const star = '*'.repeat(len - 4); return front + star + end; } else { return '***' + str.substring(len - 2); } }, onImgError(e) { // 图片加载失败,替换默认图
e.target.src = "/static/images/default-book.png"; }, async initUserAndCheckBind() { try { let openId = uni.getStorageSync('wx_login_code'); if (!openId) { const loginRes = await new Promise((resolve, reject) => { uni.login({ success: resolve, fail: reject }); });
if (!loginRes.code) { uni.showToast({ title: '授权失败', icon: 'none' }); return; }
const openRes = await FetchOpenId({ libcode: config.LIB_CODE, code: loginRes.code });
if (openRes.code !== 200 || !openRes.data) { return; }
openId = openRes.data; uni.setStorageSync('wx_login_code', openId); }
const res = await FetchFindAllReaderBindByOpenId({ libcode: config.LIB_CODE, openId: openId });
if (res.code === 200 && res.data.length > 0) { this.isBindLibraryCard = true; const defaultCard = res.data.find(item => item.bindDefault === true); const otherCards = res.data.filter(item => !item.bindDefault); this.readerCardList = defaultCard ? [defaultCard, ...otherCards] : res.data; uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, this.readerCardList); uni.setStorageSync(STORAGE_KEYS.CURRENT_READER_CARD, defaultCard); } else { this.isBindLibraryCard = false; this.readerCardList = []; uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, []); uni.setStorageSync(STORAGE_KEYS.CURRENT_READER_CARD, null); }
} catch (err) { console.error('初始化失败:', err); const list = uni.getStorageSync(STORAGE_KEYS.READER_CARD_LIST) || []; const defaultCard = list.find(item => item.bindDefault === true); const otherCards = list.filter(item => !item.bindDefault); this.readerCardList = defaultCard ? [defaultCard, ...otherCards] : list;
this.isBindLibraryCard = list.length > 0; } }, async getRecommendBooks() { try { const res = await FetchInitScreenBookRecommend({ libcode: config.LIB_CODE }); let books = res.data || []; const limit = 3; const displayBooks = books.slice(0, limit); // 不再请求下载图片,直接拼接url
for (let i = 0; i < displayBooks.length; i++) { let item = displayBooks[i]; if (item.imgPath) { item.coverUrl = this.baseUrl + '/api/fileRelevant/getImg?imgType=2&imgId=' + item.imgPath; } else { item.coverUrl = ''; } }
this.recommendedBooks = displayBooks; this.isLoading = false; } catch (err) { console.error('获取图书推荐失败:', err); this.isLoading = false; } }, goToBookDetail(item) { uni.navigateTo({ url: "/subpkg/pages/book-detail/book-detail?bookData=" + encodeURIComponent(JSON.stringify(item)) + "&fromRecommend=true" }) }, getMoreBoook(){ uni.navigateTo({ url: "/subpkg/pages/book-list/book-list" }) }, onToSearch() { uni.switchTab({ url: "/pages/search/search" }); }, onToLendCar() { this.checkBindAndNavigate("/pages/lendCar/lendCar", "请您绑定读者证", true); }, toCheckLogin() { uni.navigateTo({ url: "/pages/login/login" }); }, toRanking(){ uni.navigateTo({ url: "/subpkg/pages/ranking/ranking" }) }, toActivityList(){ this.checkBindAndNavigate("/subpkg/pages/activity-list/activity-list", "请您绑定读者证"); }, toBorrowPage(index) { if (this.isBindLibraryCard) { uni.setStorageSync('switch_tab_index', index); uni.navigateTo({ url: '/subpkg/pages/myLending/myLending' }); } else { uni.showModal({ title: '提示', content: '请您绑定读者证', confirmText: '去绑定', cancelText: '取消', success: (res) => { if (res.confirm) { uni.navigateTo({ url: "/pages/login/login" }); } } }); } }, toBorrowCar() { uni.switchTab({ url: '/pages/lendCar/lendCar' }); }, toFeedback() { uni.navigateTo({ url: '/subpkg/pages/seat-booking/seat-booking' }); }, toLibraryCard() { if (this.isBindLibraryCard) { uni.navigateTo({ url: '/subpkg/pages/reader-card/reader-card' }); } else { uni.navigateTo({ url: "/pages/login/login" }); } }, onToUser() { this.checkBindAndNavigate("/pages/user/user", "请您绑定读者证", true); }, checkBindAndNavigate(url, message, isSwitchTab = false) { if (this.isBindLibraryCard) { if (isSwitchTab) { uni.switchTab({ url }); } else { uni.navigateTo({ url }); } } else { uni.showModal({ title: '提示', content: message, confirmText: '去绑定', cancelText: '取消', success: (res) => { if (res.confirm) { uni.navigateTo({ url: "/pages/login/login" }); } } }); } }, showQrcode(bindValue) { this.qrcodeText = bindValue; this.$refs.popup.open(); }, closeAllPopup() { this.qrcodeText = ''; this.$refs.popup.close(); }, closeErweiPopup() { this.$refs.erweimapopup.close() }, onQRCodeLongPress() { }, // 【已废弃】不再使用urlToBase64
goRegister() { uni.navigateTo({ url: '/pages/register/register' }); } }}</script>
<style lang="scss" scoped>.top-bar{ .erweima-top{ position: absolute; left: 16px; top: 15px; z-index: 999; } .search-icon{ position: absolute; right: 16px; top: 15px; z-index: 22; ::v-deep .uni-icons{ color: #fff !important; } }}
.status-cards { display: flex; background-color: #fff; margin: 10px; border-radius: 8px; padding: 20px 10px; box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05); .status-card { flex: 1; display: flex; flex-direction: column; align-items: center; } .status-icon { display: flex; justify-content: center; align-items: center; width: 40px; height: 40px; margin-bottom: 6px; border-radius: 50%; } .icon-color1{ background-color: #e4f2ff; } .icon-color2{ background-color: #ffeff0; } .icon-color3{ background-color: #e4fff4; } .icon-color4{ background-color: #fef8e2; } .status-label { font-size: 12px; color: #333; }}
swiper.banner-swiper{ width: 100%; height: 130px;}swiper.banner-swiper image{ width: 100%; height: 130px;}swiper.menu-swiper{ width:100%; margin-top: 10px; background-color: #fff;}
.menu-grid { display: grid; grid-template-columns: repeat(4, 1fr); .menu-item { flex: 1; display: flex; flex-direction: column; align-items: center; padding: 10px 0; .menu-icon{ display: flex; flex-direction: column; justify-content: center; height: 30px; ::v-deep .uni-icons{ color: #01a4fe !important; } } .menu-label { font-size: 12px; color: #333; text-align: center; } }}
.library-card-section { display: flex; flex-direction: column; justify-content: space-between; align-items: center; width: 100%; padding: 20px 0; .section-title { font-size: 22px; font-weight: bold; background: linear-gradient(140deg, #01a4ff, #2ec8fe); -webkit-background-clip: text; color: transparent; letter-spacing: 0.1em; margin-bottom: 5px; } .card-icon { width: 80px; height: 80px; } .card-tip { font-size: 12px; color: #999; margin: 5px 0; } .bind-btn { display: flex; flex-direction: row; align-items: center; justify-content: center; border: 1px solid #06a8ff ; width: 128px !important; height: 28px; border-radius: 28px; background: linear-gradient(140deg, #01a4ff, #2ec8fe); font-size: 14px; color: #fff; line-height: 28px; }}
.recommendation-section { background-color: #fff; margin: 10px; border-radius: 8px; padding: 0 0 10px 0; box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05); .section-title{ display: flex; flex-direction: row; justify-content: space-between; align-items: center; height: 40px; padding: 0 10px; .left-txt{ color: #343434; font-size: 15px; font-weight: 700; } .more-link{ display: flex; flex-direction: row; justify-content: flex-start; align-items: center; color: #999; font-size: 11px; } }
}
.library-card-has { width: 100%; padding: 20px 10px; box-sizing: border-box; .section-title { font-size: 22px; font-weight: bold; background: linear-gradient(140deg, #01a4ff, #2ec8fe); -webkit-background-clip: text; color: transparent; letter-spacing: 0.1em; margin-bottom: 10px; padding-left: 5px; }
.card-list { width: 100%; }}
.card-swiper { height: 106px; .card-item{ display: flex; justify-content: space-between; align-items: center; padding: 10px; border: 2px solid #C6C6E2; border-radius: 8px; background: rgba(241,241,249,0.4); cursor: pointer; &.active{ border-color: #01a4fe; background: rgba(1, 164, 254, 0.1); } .card-left-img{ width: 80px; margin-right: 12px; display: block; } .card-right-info{ flex: 1; display: flex; flex-direction: column; .info-title{ font-size: 16px; color: #333; font-weight: bold; padding-bottom: 12px; } .info-num{ font-size: 14px; color: #999; } }
.default-tag { position: absolute; right: 12px; top: 12px; font-size: 11px; color: #01a4fe; border: 1px solid #01a4fe; border-radius: 4px; padding: 2px 6px; } }}
.erweima-style{ position: absolute; right: 12px; bottom: 22px; ::v-deep .icon-erweima{ color: #999 !important; }}</style>
|