Browse Source

banner+logo优化更新

master
xuhuajiao 3 weeks ago
parent
commit
bc8a13ff3d
  1. 8
      manifest.json
  2. 116
      pages/home/home.vue
  3. 38
      subpkg/pages/activity-record/activity-record.vue
  4. 113
      subpkg/pages/book-detail/book-detail.vue
  5. 25
      subpkg/pages/seat-record/seat-record.vue
  6. 32
      subpkg/pages/user-info/user-info.vue

8
manifest.json

@ -51,13 +51,19 @@
"mp-weixin" : {
/* */
"appid" : "wxa98bf58c54e9102e",
"libVersion": "2.24.4",
"__usePrivacyCheck__": true,
"setting" : {
"urlCheck" : false,
"checkSitMap" : false,
"minified" : true,
"postcss" : true
},
"usingComponents" : true
"usingComponents" : true,
"permission" : {},
"unipush" : {
"enable" : false
}
},
"vueVersion" : "2"
}

116
pages/home/home.vue

@ -4,12 +4,15 @@
<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>
<!-- 动态logo兜底本地静态图 -->
<image class="avatar" :src="libraryLogo || '/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" >
@ -37,12 +40,17 @@
</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
v-if="bannerList.length"
class="banner-swiper"
interval="3000"
circular
:vertical="false"
:indicator-dots="true"
:autoplay="true"
>
<swiper-item v-for="(item, idx) in bannerList" :key="idx">
<image :src="item.imgUrl" mode="aspectFill"></image>
</swiper-item>
</swiper>
@ -108,6 +116,8 @@
</swiper-item>
</swiper>
<!-- 已有绑定滑动切换多个借阅证 -->
<view v-if="isBindLibraryCard" class="library-card-has">
<view class="section-title">我的借阅证</view>
@ -135,6 +145,8 @@
</swiper>
</view>
<!-- 未绑定借阅证 -->
<view class="library-card-section" @click="toCheckLogin" v-else>
<view class="section-title">借阅证</view>
@ -143,6 +155,8 @@
<button class="bind-btn">立即绑定</button>
</view>
<root-portal>
<uni-popup
ref="popup"
@ -164,6 +178,8 @@
</view>
</uni-popup>
<uni-popup
ref="erweimapopup"
type="center"
@ -186,6 +202,8 @@
</root-portal>
<view class="recommendation-section">
<view class="section-title">
<text class="left-txt">图书推荐</text>
@ -215,12 +233,16 @@
</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 {
@ -232,7 +254,9 @@ export default {
baseUrl: config.baseUrl,
qrcodeText: '', //
popupFixedStyle: 'position:fixed;top:0;left:0;right:0;bottom:0;',
wecharQRCode: null
wecharQRCode: null,
libraryLogo: null, // logo
bannerList: [] // banner
};
},
onLoad() {
@ -246,18 +270,42 @@ export default {
async getScreenSetting() {
const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE });
//
if (res.data.wechat_qr_code && res.data.wechat_qr_code.context) {
// const imageUrl = this.baseUrl + '/api/fileRelevant/getImg?imgType=1&imgId=' + res.data.wechat_qr_code.context;
const imageUrl = this.baseUrl + '/files/' + res.data.wechat_qr_code.context;
try {
const base64 = await this.urlToBase64(imageUrl);
this.wecharQRCode = base64;
this.wecharQRCode = imageUrl;
} catch (err) {
this.wecharQRCode = null;
}
} else {
this.wecharQRCode = null;
}
// logo
if(res.data.library_logo && res.data.library_logo.context){
this.libraryLogo = this.baseUrl + '/files/' + res.data.library_logo.context;
}else{
this.libraryLogo = null;
}
// ========== vx_banner1 ~ vx_banner5 5 ==========
const banners = []
for(let i = 1; i <=5; i++){
const key = `vx_banner${i}`
const bannerItem = res.data[key]
if(bannerItem && bannerItem.context){
banners.push({
id: bannerItem.id,
code: bannerItem.code,
imgUrl: this.baseUrl + '/files/' + bannerItem.context
})
}
}
this.bannerList = banners
},
//
showTopImgPopup() {
@ -268,12 +316,16 @@ export default {
this.$refs.erweimapopup.open()
},
//
formatCardNo(cardNo) {
if (!cardNo) return '';
const str = String(cardNo);
const len = str.length;
if (len > 8) {
// 2 + * + 2
const front = str.substring(0, 2);
@ -303,31 +355,43 @@ export default {
});
});
if (!loginRes.code) {
uni.showToast({ title: '授权失败', icon: 'none' });
return;
}
// 3. openId
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);
}
// 4. openId
const res = await FetchFindAllReaderBindByOpenId({
libcode: config.LIB_CODE,
openId: openId
});
if (res.code === 200 && res.data.length > 0) {
this.isBindLibraryCard = true;
//
@ -345,6 +409,8 @@ export default {
uni.setStorageSync(STORAGE_KEYS.CURRENT_READER_CARD, null);
}
} catch (err) {
console.error('初始化失败:', err);
const list = uni.getStorageSync(STORAGE_KEYS.READER_CARD_LIST) || [];
@ -353,6 +419,8 @@ export default {
const otherCards = list.filter(item => !item.bindDefault);
this.readerCardList = defaultCard ? [defaultCard, ...otherCards] : list;
this.isBindLibraryCard = list.length > 0;
}
},
@ -362,6 +430,8 @@ export default {
const res = await FetchInitScreenBookRecommend({ libcode: config.LIB_CODE });
let books = res.data || [];
// 3setData
const limit = 3;
const displayBooks = books.slice(0, limit);
@ -384,6 +454,8 @@ export default {
}
}
// 3setData
this.recommendedBooks = displayBooks;
this.isLoading = false;
@ -548,7 +620,6 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.top-bar{
.erweima-top{
@ -567,7 +638,6 @@ export default {
}
}
}
.status-cards {
display: flex;
background-color: #fff;
@ -621,7 +691,6 @@ swiper.menu-swiper{
margin-top: 10px;
background-color: #fff;
}
.menu-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
@ -716,10 +785,8 @@ swiper.menu-swiper{
font-size: 11px;
}
}
}
.library-card-has {
width: 100%;
padding: 20px 10px;
@ -735,12 +802,10 @@ swiper.menu-swiper{
margin-bottom: 10px;
padding-left: 5px;
}
.card-list {
width: 100%;
}
}
.card-swiper {
height: 106px;
.card-item{
@ -782,6 +847,8 @@ swiper.menu-swiper{
}
}
.default-tag {
position: absolute;
right: 12px;
@ -795,6 +862,8 @@ swiper.menu-swiper{
}
}
.erweima-style{
position: absolute;
right: 12px;
@ -805,17 +874,6 @@ swiper.menu-swiper{
}
}
// .qrcode-popup {
// padding: 20px;
// border-radius: 12px;
// background: #fff;
// .qrcode-tip {
// text-align: center;
// font-size: 12px;
// color: #999;
// margin-top: 10px;
// }
// }
</style>

38
subpkg/pages/activity-record/activity-record.vue

@ -41,11 +41,11 @@
</view>
<view class="item-info">
<text class="label">开始时间</text>
<text class="value">{{ formatTime(item.start_time) }}</text>
<text class="value">{{ formatShowDateTime(item.start_time) }}</text>
</view>
<view class="item-info">
<text class="label">结束时间</text>
<text class="value">{{ formatTime(item.end_time) }}</text>
<text class="value">{{ formatShowDateTime(item.end_time) }}</text>
</view>
<view class="item-info">
<text class="label">预约人</text>
@ -75,14 +75,13 @@
</uni-swipe-action-item>
</uni-swipe-action>
<!-- 非loading有数据是最后一页哪怕仅1条也展示没有更多 -->
<view v-if="!loading && noMore && activityList.length > 0" class="nomore-box">
<text class="nomore-text">没有更多数据了</text>
</view>
<view class="empty-box" v-if="!loading && activityList.length === 0">
<uni-icons type="empty" size="80" color="#ccc"></uni-icons>
<text class="empty-text">暂无预约活动~</text>
<text class="empty-text">暂无相关活动~</text>
</view>
</scroll-view>
</view>
@ -140,6 +139,37 @@ export default {
this.activityList = []
this.getActivityList(true)
},
// // HH:mm
formatShowDateTime(timestamp) {
if (!timestamp) return '';
const d = new Date(timestamp);
const targetY = d.getFullYear();
const targetM = d.getMonth();
const targetD = d.getDate();
const hh = String(d.getHours()).padStart(2, '0');
const mm = String(d.getMinutes()).padStart(2, '0');
const timeStr = `${hh}:${mm}`;
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const targetDayTs = new Date(targetY, targetM, targetD).getTime();
const oneDay = 24 * 60 * 60 * 1000;
const diff = Math.round((targetDayTs - today.getTime()) / oneDay);
let dateText = '';
if (diff === 0) {
dateText = '今天';
} else if (diff === -1) {
dateText = '昨天';
} else if (diff === 1) {
dateText = '明天';
} else {
const m = String(targetM + 1).padStart(2, '0');
const day = String(targetD).padStart(2, '0');
dateText = `${targetY}-${m}-${day}`;
}
return `${dateText} ${timeStr}`;
},
formatTime(timestamp) {
if (!timestamp) return '';

113
subpkg/pages/book-detail/book-detail.vue

@ -68,9 +68,9 @@
<view class="tab-item" :class="{active: currentTab === 0}" @click="currentTab = 0">
内容简介
</view>
<view class="tab-item" :class="{active: currentTab === 1}" @click="currentTab = 1">
<!-- <view class="tab-item" :class="{active: currentTab === 1}" @click="currentTab = 1">
作者简介
</view>
</view> -->
</view>
<!-- TAB 内容 -->
@ -119,7 +119,10 @@ export default {
};
},
onLoad(options) {
// 1. / bookData
console.log('options',options)
const fromShare = options.fromShare === 'true'
// 1. / bookData
if (options.bookData) {
const bookData = JSON.parse(decodeURIComponent(options.bookData));
this.bookInfo = bookData;
@ -127,26 +130,40 @@ export default {
this.fromRecommend = options.fromRecommend === 'true';
this.holdingsData = [];
this.checkCollectStatus();
// bookrecno
if(fromShare && this.bookrecno){
this.getOpacUrl();
}
return;
}
console.log('options',options)
// 2. bookrecno
// 2. bookrecno
if(options.bookrecno){
this.bookrecno = options.bookrecno
this.fromRecommend = false
this.bookInfo = {}
this.getOpacUrl();
return;
}
// 3. searchData
if(options.searchData){
const bookData = JSON.parse(decodeURIComponent(options.searchData));
this.searchListInfo = bookData;
this.bookrecno = bookData.bookrecno || "";
this.bookInfo = bookData;
}
// 3.
// 4.
if (options.isCollected === 'true') {
this.isCollected = true;
}
this.fromRecommend = false;
// bookrecnogetOpacUrl
if(this.bookrecno){
this.getOpacUrl();
this.getDictionaryTree();
}
},
computed: {
//
@ -219,6 +236,7 @@ export default {
try {
const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE });
this.opacUrl = res.data.opac_url?.context || '';
this.getDictionaryTree();
this.getBookDetail();
} catch (err) {}
},
@ -234,13 +252,20 @@ export default {
bookrecno: this.bookrecno
};
const res = await FetchFindbookByQuery(params);
// console.log('bookrecno',res);
const apiData = res.data || {};
this.bookInfo = apiData.biblios || {};
// console.log('bookrecno-bookInfo',this.bookInfo);
this.holdingsData = apiData.holdings || [];
// console.log('bookrecno-holdingsData',this.holdingsData);
// searchListInfo
if(!this.searchListInfo || !this.searchListInfo.bookrecno){
this.searchListInfo = {
bookrecno: this.bookInfo.bookrecno,
title: this.bookInfo.title,
author: this.bookInfo.author,
isbn: this.bookInfo.isbn
}
}
//
await this.loadBookCover();
@ -297,10 +322,14 @@ export default {
uni.showToast({ title: '获取用户信息失败', icon: 'none' });
return;
}
// searchListInfo
if(!this.searchListInfo || !this.searchListInfo.bookrecno){
uni.showToast({title:'数据未加载完成,请稍候',icon:'none'})
return
}
if (this.isCollected) {
try {
console.log(' this.searchListInfo.id',this.searchListInfo.id);
const res = await FetchCancelCollectionBook({id: this.searchListInfo.id});
if (res.code === 200) {
this.isCollected = false;
@ -345,11 +374,46 @@ export default {
}
},
onShareAppMessage() {
const title = this.bookInfo.title || this.bookInfo.name || '图书详情';
let path = '';
let imageUrl = '';
const cover = this.bookInfo.cover || this.bookInfo.base64Cover;
// base64
if(cover && !cover.startsWith('data:image')){
imageUrl = cover;
}
if(this.bookrecno){
//bookrecnourl
path = `/subpkg/pages/book-detail/book-detail?bookrecno=${encodeURIComponent(this.bookrecno)}&fromShare=true`
}else{
path = "/subpkg/pages/book-detail/book-detail?bookData=" + encodeURIComponent(JSON.stringify(this.bookInfo)) + "&fromShare=true"
}
return {
title: this.bookInfo.title || '图书详情',
path: '/subpkg/pages/book-detail/book-detail?bookrecno=' + this.bookrecno,
imageUrl: this.bookInfo.cover
title,
path,
imageUrl
};
},
//
onShareTimeline(){
const title = this.bookInfo.title || this.bookInfo.name || '图书详情';
let query = ''
if(this.bookrecno){
query = `bookrecno=${encodeURIComponent(this.bookrecno)}&fromShare=true`
}else{
query = `bookData=${encodeURIComponent(JSON.stringify(this.bookInfo))}&fromShare=true`
}
let imageUrl = ''
const cover = this.bookInfo.cover
if(cover && !cover.startsWith('data:image')){
imageUrl = cover
}
return {
title,
query,
imageUrl
}
}
};
</script>
@ -490,8 +554,25 @@ export default {
line-height: 1.6;
}
.detail-bottom{
position: fixed;
bottom:0;
left:0;
right:0;
height:60px;
background:#fff;
display:flex;
justify-content: space-around;
padding: 0 15px;
align-items:center;
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
}
.handle-btn{
display:flex;
align-items:center;
background:#fff;
border:none;
}
.share-text{
margin-left:4px;
font-size:14px;
}
</style>

25
subpkg/pages/seat-record/seat-record.vue

@ -45,7 +45,7 @@
</view>
<view class="item-info">
<text class="label">入馆日期</text>
<text class="value">{{ item.visitDate }}</text>
<text class="value">{{ formatShowDate(item.visitDate) }}</text>
</view>
<view class="item-info">
<text class="label">入馆时间</text>
@ -107,6 +107,29 @@ export default {
})
},
methods: {
formatShowDate(dateStr) {
if(!dateStr) return ''
// dateStr yyyy-MM-dd
const now = new Date()
// 0
const todayTs = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()
const oneDay = 24 * 60 * 60 * 1000
const target = new Date(dateStr)
const targetTs = new Date(target.getFullYear(), target.getMonth(), target.getDate()).getTime()
const diffDay = Math.round((targetTs - todayTs) / oneDay)
if(diffDay === 0){
return '今天'
}else if(diffDay === -1){
return '昨天'
}else if(diffDay === 1){
return '明天'
}else{
return dateStr
}
},
formatTsToDate(ts) {
const d = new Date(ts);
const y = d.getFullYear();

32
subpkg/pages/user-info/user-info.vue

@ -1,11 +1,11 @@
<template>
<view class="user-info-page">
<view v-if="pageReady">
<view class="user-info-section">
<!-- 点击获取头像 -->
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar" class="avatar-btn">
<image v-if="avatarUrl" :src="avatarUrl" class="avatar-img"></image>
<image v-else src="@/static/images/logo.jpg" class="avatar-img"></image>
<image v-show="avatarUrl" :src="avatarUrl" class="avatar-img"></image>
<image v-show="!avatarUrl" src="@/static/images/logo.jpg" class="avatar-img"></image>
<text class="tip-text">点击更换头像</text>
</button>
</view>
@ -27,6 +27,7 @@
<button class="save-btn" @click="saveUserInfo">保存修改</button>
</view>
</view>
</view>
</template>
<script>
@ -38,13 +39,16 @@ const USER_KEY = 'user-info';
export default {
data() {
return {
pageReady: false,
nickname: '',
avatarUrl: '', // base64
imgId: '', //
saving: false //
};
},
onLoad() {
onReady() {
//chooseAvatar
this.pageReady = true;
this.loadUserInfo();
},
methods:{
@ -57,9 +61,7 @@ export default {
if (avatarId) {
try {
uni.showLoading({ title: '加载头像中...' });
// const url = `${config.baseUrl}/api/fileRelevant/getImg?imgType=5&imgId=${avatarId}`;
// this.avatarUrl = await this.urlToBase64(url);
console.log(avatarId)
this.imgId = avatarId;
const url = `${config.baseUrl}/files/${avatarId}`;
console.log(url)
this.avatarUrl = url
@ -71,9 +73,11 @@ export default {
}
} else {
this.avatarUrl = '';
this.imgId = '';
}
},
// + + base64
async onChooseAvatar(e) {
const tempFilePath = e.detail.avatarUrl;
@ -130,7 +134,6 @@ export default {
});
});
},
// +
async saveUserInfo() {
if (this.saving) return;
@ -151,7 +154,12 @@ export default {
openid: openId
};
await FetchBindRead(params);
const res = await FetchBindRead(params);
console.log('FetchBindRead',res)
if(res.code !== 200){
uni.showToast({title: res.message || '保存失败',icon:'none'})
return
}
//
uni.setStorageSync(USER_KEY, {
@ -172,6 +180,7 @@ export default {
this.saving = false;
}
}
}
};
</script>
@ -196,15 +205,16 @@ export default {
.avatar-btn {
background: transparent;
pointer-events: auto !important;
display: flex;
flex-direction: column;
align-items: center;
&::after {
border: none;
border: none !important;
}
}
.avatar-img {
width: 120rpx;
height: 120rpx;

Loading…
Cancel
Save