|
|
<template> <view class="reader-card"> <image class="card-top-bg" src="@/static/images/card-img1.png" mode="widthFix" />
<view class="edit-btn" @click="toggleEditMode"> {{ isEditMode ? '完成' : '解绑' }} </view>
<view class="card-list"> <view class="card-list-item" v-for="(item, index) in cardList" :key="item.id" @click="handleSelectItem(item.bindValue)" :class="{ active: selectedValue === item.bindValue || (!isEditMode && item.bindDefault) }" > <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> <text class="default-tag" v-if="item.bindDefault">默认证</text> </view>
<!-- 编辑模式显示单选框 --> <radio v-if="isEditMode" :value="item.bindValue" :checked="selectedValue === item.bindValue"/>
<!-- 非编辑模式才显示:设置默认 + 二维码 --> <view class="card-setting" v-else> <button v-if="!item.bindDefault" type="default" size="mini" @click.stop="setDefaultCard(item.bindValue)">设置默认</button> <uni-icons class="erweima-style" custom-prefix="iconfont" type="icon-erweima" size="28" @click.stop="showQrcode(item.bindValue)"></uni-icons> </view> </view>
<view class="add-card-btn" @click="toAddReaderCard" v-if="!isEditMode"> <uni-icons type="plus" size="20" color="#01a4fe"></uni-icons> <text>绑定读者证</text> </view> </view>
<!-- 编辑模式显示底部解绑按钮 --> <button v-if="isEditMode" class="unbind-btn" :disabled="!selectedValue" :class="{disabled: !selectedValue}" @click="handleUnbind" > 确认解绑 </button>
<!-- 二维码弹窗 --> <uni-popup ref="popup" type="center" @maskClick="closePopup"> <view class="qrcode-popup"> <view class="qrcode-title">读者证二维码</view> <w-qrcode v-if="qrcodeText" :value="qrcodeText" :size="160" foreground="#333" background="#f5f5f5" /> <view class="qrcode-num">{{ qrcodeText }}</view> <!-- <view class="close-btn" @click="closePopup">关闭</view> --> </view> </uni-popup>
<button class="register-btn" type="primary" @click="goRegister">在线办证</button> </view></template>
<script>import { FetchFindAllReaderBindByOpenId, FetchSetDefaultReadCard, FetchUnbindReadCard } from '@/api/user';import { getReaderCardList, getOpenId, setCurrentReaderCard, clearReaderCardCache, STORAGE_KEYS } from '@/utils/storage';import config from '@/utils/config';
export default { data() { return { isEditMode: false, selectedValue: '', cardList: [], qrcodeText: '', loading: false, } }, onShow() { this.getBindReaderCardList(); }, methods: { 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); } },
toggleEditMode() { this.isEditMode = !this.isEditMode; this.selectedValue = ''; },
async getBindReaderCardList(forceRefresh = false) { if (this.loading) return; this.loading = true;
try { const readerList = await getReaderCardList(forceRefresh); this.cardList = readerList; } catch (err) { console.error(err); const cachedList = uni.getStorageSync(STORAGE_KEYS.READER_CARD_LIST) || []; this.cardList = cachedList; } finally { this.loading = false; } },
handleSelectItem(value) { if (this.isEditMode) { this.selectedValue = this.selectedValue === value ? '' : value; } },
async setDefaultCard(value) { const currentDefault = this.cardList.find(item => item.bindDefault === true); if (currentDefault && currentDefault.bindValue === value) { uni.showToast({ title: '当前已是默认证', icon: 'none' }); return; }
const openId = await getOpenId(); if (!openId) { uni.showToast({ title: '获取用户信息失败', icon: 'none' }); return; }
uni.showModal({ title: '提示', content: `确定设置【${value}】为默认读者证吗?`, success: async (res) => { if (!res.confirm) return; try { await FetchSetDefaultReadCard({ bindType: 'rdid', bindValue: value, libcode: config.LIB_CODE, openid: openId }); setCurrentReaderCard(value); await this.getBindReaderCardList(true); uni.showToast({ title: '设置成功', icon: 'success' }); } catch (err) { console.error(err); uni.showToast({ title: '设置失败', icon: 'none' }); } } }); },
showQrcode(bindValue) { this.qrcodeText = bindValue; this.$refs.popup.open(); },
closePopup() { this.qrcodeText = ''; this.$refs.popup.close(); },
async handleUnbind() { if (!this.selectedValue) { uni.showToast({ title: '请选择要解绑的读者证', icon: 'none' }); return; }
const openId = await getOpenId(); if (!openId) { uni.showToast({ title: '获取用户信息失败', icon: 'none' }); return; }
const unbindItem = this.cardList.find(item => item.bindValue === this.selectedValue); const isUnbindDefault = unbindItem?.bindDefault === true;
uni.showModal({ title: '提示', content: `确定要解绑读者证【${this.selectedValue}】吗?`, success: async (res) => { if (!res.confirm) return;
try { const result = await FetchUnbindReadCard({ bindType: "rdid", bindValue: this.selectedValue, libcode: config.LIB_CODE, openid: openId });
if (result.code === 200) { uni.showToast({ title: '解绑成功', icon: 'success' }); this.selectedValue = ''; await this.getBindReaderCardList(true);
if (isUnbindDefault && this.cardList.length > 0) { const newValue = this.cardList[0].bindValue; await FetchSetDefaultReadCard({ bindType: 'rdid', bindValue: newValue, libcode: config.LIB_CODE, openid: openId }); setCurrentReaderCard(newValue); await this.getBindReaderCardList(true); }
if (this.cardList.length === 0) { clearReaderCardCache(); setTimeout(() => uni.navigateBack(), 1000); } } } catch (err) { console.error(err); uni.showToast({ title: '解绑失败', icon: 'none' }); } } }); },
toAddReaderCard() { uni.navigateTo({ url: "/pages/login/login" }); }, // 跳转到在线办证页面
goRegister() { uni.navigateTo({ url: '/pages/register/register' }); } }}</script>
<style lang="scss" scoped>.reader-card{ position: relative; min-height: 100vh; background-color: #f5f5f5; .card-top-bg{ position: absolute; left: 0; top: 0; width: 100%; }
.edit-btn{ position: absolute; right: 20px; top: 20px; z-index: 100; font-size: 15px; } .card-list{ position: absolute; left: 0; top: 60px; width: calc(100% - 24px); height: calc(100vh - 195px); overflow-y: auto; padding: 12px; z-index: 999; .card-list-item{ display: flex; justify-content: space-between; align-items: center; padding: 10px; margin-bottom: 12px; border: 2px solid #C6C6E2; border-radius: 8px; background: rgba(241,241,249,0.4); cursor: pointer; transition: all 0.2s; &.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: 4px; } .info-num{ font-size: 14px; color: #999; } .default-tag{ width: 46px; font-size: 12px; color: #01a4fe; border:1px solid #01a4fe; border-radius: 4px; padding: 2px 0; text-align: center; display: inline-block; margin-top: 4px; } } } }
.add-card-btn { display: flex; align-items: center; justify-content: center; margin-top: 15px; height: 44px; border: 1px dashed #01a4fe; border-radius: 8px; color: #01a4fe; font-size: 15px;
uni-icons { margin-right: 6px; } } .unbind-btn{ position: fixed; bottom: 40px; left: 0; right: 0; width: calc(100% - 40px); margin: 0 auto; padding: 4px 0; color: #fff; background-color: #01a4fe; border-radius: 23px; font-size: 16px; &.disabled{ background-color: #ccc; } }}
.card-setting{ display: flex; flex-direction: column; align-items: flex-end; justify-content: center; button{ padding: 0 8px !important; margin-bottom: 16px; font-size: 12px; } ::v-deep .icon-erweima{ color: #999 !important; }}</style>
|