图书馆小程序
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.

820 lines
24 KiB

5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
4 weeks ago
4 months ago
4 weeks ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
3 weeks ago
4 months ago
4 months ago
4 weeks ago
4 months ago
4 months ago
4 months ago
4 months ago
1 month ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
3 weeks ago
3 weeks ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 weeks ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
  1. <template>
  2. <view style="padding-bottom: 20px;">
  3. <view class="top-bar">
  4. <uni-icons class="erweima-top" custom-prefix="iconfont" type="icon-erweima" size="22" color="#fff" @click="showTopImgPopup"></uni-icons>
  5. <image class="top-bar-bg" src="@/static/images/mingqi-beij@2x.png" mode="aspectFill"></image>
  6. <view class="library-info">
  7. <image class="avatar" src="@/static/images/logo.jpg" mode="aspectFill"></image>
  8. <view class="library-name">葛店经济技术开发区图书馆</view>
  9. </view>
  10. <uni-icons class="search-icon" type="search" size="24" @click="onToSearch"></uni-icons>
  11. </view>
  12. <view class="status-cards">
  13. <view class="status-card" @click="toBorrowPage(0)">
  14. <view class="status-icon icon-color1" >
  15. <uni-icons custom-prefix="iconfont" type="icon-daiban02" size="22"></uni-icons>
  16. </view>
  17. <view class="status-label">在借中</view>
  18. </view>
  19. <!-- <view class="status-card" @click="toBorrowPage(2)">
  20. <view class="status-icon icon-color2" >
  21. <uni-icons custom-prefix="iconfont" type="icon-zuofei05" size="22"></uni-icons>
  22. </view>
  23. <view class="status-label">将过期</view>
  24. </view>
  25. <view class="status-card" @click="toBorrowPage(3)">
  26. <view class="status-icon icon-color3" >
  27. <uni-icons custom-prefix="iconfont" type="icon-yuqi04" size="22"></uni-icons>
  28. </view>
  29. <view class="status-label">已过期</view>
  30. </view> -->
  31. <view class="status-card" @click="toBorrowPage(1)">
  32. <view class="status-icon icon-color4" >
  33. <uni-icons custom-prefix="iconfont" type="icon-a-zhidu4" size="22"></uni-icons>
  34. </view>
  35. <view class="status-label">历史借阅</view>
  36. </view>
  37. </view>
  38. <swiper class="banner-swiper" interval="3000" circular :vertical="false" :indicator-dots="true" :autoplay="true">
  39. <swiper-item>
  40. <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>
  41. </swiper-item>
  42. <swiper-item>
  43. <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>
  44. </swiper-item>
  45. </swiper>
  46. <!-- :indicator-dots="true" -->
  47. <swiper class="menu-swiper" interval="6000" :vertical="false" :autoplay="false">
  48. <swiper-item>
  49. <view class="menu-grid">
  50. <view class="menu-item" @click="onToSearch">
  51. <view class="menu-icon">
  52. <uni-icons custom-prefix="iconfont" type="icon-ziyuan" size="22"></uni-icons>
  53. </view>
  54. <view class="menu-label">书目检索</view>
  55. </view>
  56. <view class="menu-item" @click="onToLendCar">
  57. <view class="menu-icon">
  58. <uni-icons custom-prefix="iconfont" type="icon-z_renew_normal" size="24"></uni-icons>
  59. </view>
  60. <view class="menu-label">图书续借</view>
  61. </view>
  62. <!-- <view class="menu-item" >
  63. <view class="menu-icon">
  64. <uni-icons custom-prefix="iconfont" type="icon-guanwaizhuanjie1" size="26"></uni-icons>
  65. </view>
  66. <view class="menu-label">图书转借</view>
  67. </view> -->
  68. <view class="menu-item" @click="toLibraryCard">
  69. <view class="menu-icon">
  70. <uni-icons custom-prefix="iconfont" type="icon-duzhezheng" size="26"></uni-icons>
  71. </view>
  72. <view class="menu-label">电子证</view>
  73. </view>
  74. <view class="menu-item" @click="toRanking">
  75. <view class="menu-icon">
  76. <uni-icons custom-prefix="iconfont" type="icon-paihangbang" size="22"></uni-icons>
  77. </view>
  78. <view class="menu-label">借阅排行</view>
  79. </view>
  80. <view class="menu-item" @click="toActivityList">
  81. <view class="menu-icon">
  82. <uni-icons custom-prefix="iconfont" type="icon-remenhuodong" size="26"></uni-icons>
  83. </view>
  84. <view class="menu-label">活动报名</view>
  85. </view>
  86. <view class="menu-item" @click="toFeedback">
  87. <view class="menu-icon">
  88. <uni-icons custom-prefix="iconfont" type="icon-ruguanyuyue" size="26"></uni-icons>
  89. </view>
  90. <view class="menu-label">预约入馆</view>
  91. </view>
  92. <view class="menu-item" @click="onToUser">
  93. <view class="menu-icon">
  94. <uni-icons custom-prefix="iconfont" type="icon-yonghuxinxi-gerenxinxi" size="20"></uni-icons>
  95. </view>
  96. <view class="menu-label">个人中心</view>
  97. </view>
  98. <view class="menu-item" @click="goRegister">
  99. <view class="menu-icon">
  100. <uni-icons custom-prefix="iconfont" type="icon-daohang-banzhengxuzhi" size="25"></uni-icons>
  101. </view>
  102. <view class="menu-label">在线办证</view>
  103. </view>
  104. </view>
  105. </swiper-item>
  106. </swiper>
  107. <!-- 已有绑定滑动切换多个借阅证 -->
  108. <view v-if="isBindLibraryCard" class="library-card-has">
  109. <view class="section-title">我的借阅证</view>
  110. <!-- 左右滑动切换证件 -->
  111. <!-- :indicator-dots="readerCardList.length > 1"
  112. indicator-color="#d1d1d1"
  113. indicator-active-color="#01a4fe" -->
  114. <swiper
  115. class="card-swiper"
  116. :circular="false"
  117. >
  118. <swiper-item v-for="item in readerCardList" :key="item.id">
  119. <!-- :class="{'active': item.bindDefault}" -->
  120. <view class="card-item" @click.stop="showQrcode(item.bindValue)">
  121. <image class="card-left-img" src="@/static/images/card-img2.png" mode="widthFix" />
  122. <view class="card-right-info">
  123. <text class="info-title">读者证号</text>
  124. <text class="info-num">{{ formatCardNo(item.bindValue) }}</text>
  125. </view>
  126. <view class="default-tag" v-if="item.bindDefault">默认证</view>
  127. <uni-icons class="erweima-style" custom-prefix="iconfont" type="icon-erweima" size="28"></uni-icons>
  128. </view>
  129. </swiper-item>
  130. </swiper>
  131. </view>
  132. <!-- 未绑定借阅证 -->
  133. <view class="library-card-section" @click="toCheckLogin" v-else>
  134. <view class="section-title">借阅证</view>
  135. <image class="card-icon" src="@/static/images/card-img2.png"></image>
  136. <view class="card-tip">您还没有绑定读者证哦</view>
  137. <button class="bind-btn">立即绑定</button>
  138. </view>
  139. <root-portal>
  140. <uni-popup
  141. ref="popup"
  142. type="center"
  143. :mask-click="true"
  144. @maskClick="closeAllPopup"
  145. >
  146. <view class="qrcode-popup">
  147. <view class="qrcode-title">读者证二维码</view>
  148. <w-qrcode
  149. v-if="qrcodeText"
  150. :value="qrcodeText"
  151. :size="160"
  152. foreground="#333"
  153. background="#ffffff"
  154. />
  155. <view class="qrcode-num" v-if="qrcodeText">{{ qrcodeText }}</view>
  156. <!-- <view class="close-btn" @click="closeAllPopup" style="margin-top:15px;">关闭</view> -->
  157. </view>
  158. </uni-popup>
  159. <uni-popup
  160. ref="erweimapopup"
  161. type="center"
  162. :mask-click="true"
  163. @maskClick="closeErweiPopup"
  164. :custom-style="popupFixedStyle"
  165. >
  166. <view class="qrcode-popup" style="width: auto !important;">
  167. <image
  168. v-if="wecharQRCode"
  169. :src="wecharQRCode"
  170. style="width:200px;height:200px;"
  171. mode="aspectFit"
  172. :show-menu-by-longpress="true"
  173. @longpress="onQRCodeLongPress"
  174. ></image>
  175. <!-- <view class="qrcode-tip">长按二维码可识别</view> -->
  176. </view>
  177. </uni-popup>
  178. </root-portal>
  179. <view class="recommendation-section">
  180. <view class="section-title">
  181. <text class="left-txt">图书推荐</text>
  182. <view class="more-link" @click="getMoreBoook" v-if="!(recommendedBooks.length === 0 && !isLoading)">
  183. <text style="margin-right: 5px;">查看更多</text>
  184. <uni-icons custom-prefix="iconfont" type="icon-gengduo" size="12"></uni-icons>
  185. </view>
  186. </view>
  187. <view class="recommendation-list">
  188. <uni-load-more status="loading" v-if="isLoading"></uni-load-more>
  189. <view v-else class="book-item" v-for="(item,index) in recommendedBooks.slice(0,3)" @click="goToBookDetail(item)" :key="index" >
  190. <!-- :src="item.base64Cover || '/static/images/default-book.jpg'" -->
  191. <image
  192. class="book-cover"
  193. :src="item.base64Cover || '/static/images/default-book.jpg'"
  194. @error="onImgError"
  195. ></image>
  196. <view class="book-title">{{item.name}}</view>
  197. </view>
  198. </view>
  199. <view class="empty" v-if="recommendedBooks.length === 0 && !isLoading">
  200. <uni-icons custom-prefix="iconfont" type="icon-kongshuju" size="80"></uni-icons>
  201. <text style="margin-top: 20px;">暂无推荐书籍~</text>
  202. </view>
  203. </view>
  204. </view>
  205. </template>
  206. <script>
  207. import { FetchInitScreenSetting, FetchOpenId, FetchFindAllReaderBindByOpenId} from '@/api/user';
  208. import { FetchInitScreenBookRecommend } from '@/api/book';
  209. import config from '@/utils/config';
  210. import { STORAGE_KEYS } from '@/utils/storage';
  211. export default {
  212. data() {
  213. return {
  214. isLoading: true,
  215. recommendedBooks: [],
  216. userInfo: {},
  217. isBindLibraryCard: false,
  218. readerCardList: [], // 多个借阅证
  219. baseUrl: config.baseUrl,
  220. qrcodeText: '', // 二维码内容
  221. popupFixedStyle: 'position:fixed;top:0;left:0;right:0;bottom:0;',
  222. wecharQRCode: null
  223. };
  224. },
  225. onLoad() {
  226. this.getRecommendBooks();
  227. this.getScreenSetting()
  228. },
  229. onShow() {
  230. this.initUserAndCheckBind();
  231. },
  232. methods:{
  233. async getScreenSetting() {
  234. const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE });
  235. if (res.data.wechat_qr_code && res.data.wechat_qr_code.context) {
  236. // const imageUrl = this.baseUrl + '/api/fileRelevant/getImg?imgType=1&imgId=' + res.data.wechat_qr_code.context;
  237. const imageUrl = this.baseUrl + '/files/' + res.data.wechat_qr_code.context;
  238. try {
  239. const base64 = await this.urlToBase64(imageUrl);
  240. this.wecharQRCode = base64;
  241. } catch (err) {
  242. this.wecharQRCode = null;
  243. }
  244. } else {
  245. this.wecharQRCode = null;
  246. }
  247. },
  248. // 显示顶部微信二维码弹窗
  249. showTopImgPopup() {
  250. if (!this.wecharQRCode) {
  251. uni.showToast({ title: '暂无图片', icon: 'none' })
  252. return
  253. }
  254. this.$refs.erweimapopup.open()
  255. },
  256. // 格式化读者证号
  257. formatCardNo(cardNo) {
  258. if (!cardNo) return '';
  259. const str = String(cardNo);
  260. const len = str.length;
  261. if (len > 8) {
  262. // 前2位 + 中间全部* + 后2位
  263. const front = str.substring(0, 2);
  264. const end = str.substring(len - 2);
  265. const star = '*'.repeat(len - 4); // 中间全部隐藏
  266. return front + star + end;
  267. } else {
  268. // 小于等于8:*** + 后2位
  269. return '***' + str.substring(len - 2);
  270. }
  271. },
  272. onImgError(e) {
  273. e.target.src = "/static/images/default-book.jpg";
  274. },
  275. // 初始化:登录 → 获取openid → 查是否绑定
  276. async initUserAndCheckBind() {
  277. try {
  278. // 1. 先看缓存有没有 openId
  279. let openId = uni.getStorageSync('wx_login_code');
  280. // 2. 没有 → 走微信登录流程
  281. if (!openId) {
  282. const loginRes = await new Promise((resolve, reject) => {
  283. uni.login({
  284. success: resolve,
  285. fail: reject
  286. });
  287. });
  288. if (!loginRes.code) {
  289. uni.showToast({ title: '授权失败', icon: 'none' });
  290. return;
  291. }
  292. // 3. 获取 openId
  293. const openRes = await FetchOpenId({
  294. libcode: config.LIB_CODE,
  295. code: loginRes.code
  296. });
  297. if (openRes.code !== 200 || !openRes.data) {
  298. return;
  299. }
  300. openId = openRes.data;
  301. uni.setStorageSync('wx_login_code', openId);
  302. }
  303. // 4. 有了 openId → 查绑定状态
  304. const res = await FetchFindAllReaderBindByOpenId({
  305. libcode: config.LIB_CODE,
  306. openId: openId
  307. });
  308. if (res.code === 200 && res.data.length > 0) {
  309. this.isBindLibraryCard = true;
  310. // 默认证排第一位
  311. const defaultCard = res.data.find(item => item.bindDefault === true);
  312. const otherCards = res.data.filter(item => !item.bindDefault);
  313. // 合并:默认在前,其他在后
  314. this.readerCardList = defaultCard ? [defaultCard, ...otherCards] : res.data;
  315. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, this.readerCardList);
  316. uni.setStorageSync(STORAGE_KEYS.CURRENT_READER_CARD, defaultCard);
  317. } else {
  318. this.isBindLibraryCard = false;
  319. this.readerCardList = [];
  320. uni.setStorageSync(STORAGE_KEYS.READER_CARD_LIST, []);
  321. uni.setStorageSync(STORAGE_KEYS.CURRENT_READER_CARD, null);
  322. }
  323. } catch (err) {
  324. console.error('初始化失败:', err);
  325. const list = uni.getStorageSync(STORAGE_KEYS.READER_CARD_LIST) || [];
  326. // 同样默认排第一
  327. const defaultCard = list.find(item => item.bindDefault === true);
  328. const otherCards = list.filter(item => !item.bindDefault);
  329. this.readerCardList = defaultCard ? [defaultCard, ...otherCards] : list;
  330. this.isBindLibraryCard = list.length > 0;
  331. }
  332. },
  333. // 获取图书推荐 + 封面转 base64
  334. async getRecommendBooks() {
  335. try {
  336. const res = await FetchInitScreenBookRecommend({ libcode: config.LIB_CODE });
  337. let books = res.data || [];
  338. // 只处理并展示前3条,避免setData数据过大
  339. const limit = 3;
  340. const displayBooks = books.slice(0, limit);
  341. for (let i = 0; i < displayBooks.length; i++) {
  342. let item = displayBooks[i];
  343. if (item.imgVxPath) {
  344. // const imageUrl = this.baseUrl + '/api/fileRelevant/getImg?imgType=2&imgId=' + item.imgPath;
  345. const imageUrl = this.baseUrl + '/files/' + item.imgVxPath;
  346. console.log('imageUrl:', imageUrl);
  347. item.base64Cover = imageUrl;
  348. // try {
  349. // const base64 = await this.urlToBase64(imageUrl);
  350. // item.base64Cover = base64;
  351. // } catch (err) {
  352. // item.base64Cover = '';
  353. // }
  354. } else {
  355. item.base64Cover = '';
  356. }
  357. }
  358. // 只将展示所需的前3条数据放入响应式,减少setData传输量
  359. this.recommendedBooks = displayBooks;
  360. this.isLoading = false;
  361. } catch (err) {
  362. console.error('获取图书推荐失败:', err);
  363. this.isLoading = false;
  364. }
  365. },
  366. goToBookDetail(item) {
  367. // 把整个图书对象 转成字符串 带过去
  368. uni.navigateTo({
  369. url: "/subpkg/pages/book-detail/book-detail?bookData=" + encodeURIComponent(JSON.stringify(item)) + "&fromRecommend=true"
  370. })
  371. },
  372. // 查看更多 → 进入图书列表页
  373. getMoreBoook(){
  374. uni.navigateTo({
  375. url: "/subpkg/pages/book-list/book-list"
  376. })
  377. },
  378. // 去图书检索页
  379. onToSearch() {
  380. uni.switchTab({
  381. url: "/pages/search/search"
  382. });
  383. },
  384. // 去图书借阅车页
  385. onToLendCar() {
  386. this.checkBindAndNavigate("/pages/lendCar/lendCar", "请您绑定读者证", true);
  387. },
  388. // 点击未绑定借阅证区域 触发跳转
  389. toCheckLogin() {
  390. uni.navigateTo({
  391. url: "/pages/login/login"
  392. });
  393. },
  394. toRanking(){
  395. uni.navigateTo({
  396. url: "/subpkg/pages/ranking/ranking"
  397. })
  398. },
  399. toActivityList(){
  400. this.checkBindAndNavigate("/subpkg/pages/activity-list/activity-list", "请您绑定读者证");
  401. },
  402. toBorrowPage(index) {
  403. if (this.isBindLibraryCard) {
  404. uni.setStorageSync('switch_tab_index', index);
  405. uni.navigateTo({
  406. url: '/subpkg/pages/myLending/myLending'
  407. });
  408. } else {
  409. uni.showModal({
  410. title: '提示',
  411. content: '请您绑定读者证',
  412. confirmText: '去绑定',
  413. cancelText: '取消',
  414. success: (res) => {
  415. if (res.confirm) {
  416. uni.navigateTo({ url: "/pages/login/login" });
  417. }
  418. }
  419. });
  420. }
  421. },
  422. toBorrowCar() {
  423. uni.switchTab({
  424. url: '/pages/lendCar/lendCar'
  425. });
  426. },
  427. toFeedback() {
  428. uni.navigateTo({
  429. url: '/subpkg/pages/seat-booking/seat-booking'
  430. });
  431. },
  432. // 去借阅证列表页
  433. toLibraryCard() {
  434. // 已绑定 → 进列表
  435. if (this.isBindLibraryCard) {
  436. uni.navigateTo({ url: '/subpkg/pages/reader-card/reader-card' });
  437. }
  438. // 未绑定 → 进绑定页
  439. else {
  440. uni.navigateTo({ url: "/pages/login/login" });
  441. }
  442. },
  443. // 去个人中心页
  444. onToUser() {
  445. this.checkBindAndNavigate("/pages/user/user", "请您绑定读者证", true);
  446. },
  447. checkBindAndNavigate(url, message, isSwitchTab = false) {
  448. if (this.isBindLibraryCard) {
  449. if (isSwitchTab) {
  450. uni.switchTab({ url });
  451. } else {
  452. uni.navigateTo({ url });
  453. }
  454. } else {
  455. uni.showModal({
  456. title: '提示',
  457. content: message,
  458. confirmText: '去绑定',
  459. cancelText: '取消',
  460. success: (res) => {
  461. if (res.confirm) {
  462. uni.navigateTo({ url: "/pages/login/login" });
  463. }
  464. }
  465. });
  466. }
  467. },
  468. showQrcode(bindValue) {
  469. this.qrcodeText = bindValue;
  470. this.$refs.popup.open();
  471. },
  472. closeAllPopup() {
  473. this.qrcodeText = '';
  474. this.$refs.popup.close();
  475. },
  476. closeErweiPopup() {
  477. this.$refs.erweimapopup.close()
  478. },
  479. /**
  480. * 二维码长按事件
  481. */
  482. onQRCodeLongPress() {
  483. // uni.showToast({
  484. // title: '长按识别二维码',
  485. // icon: 'none',
  486. // duration: 1500
  487. // });
  488. },
  489. urlToBase64(url) {
  490. return new Promise((resolve, reject) => {
  491. uni.request({
  492. url,
  493. method: 'GET',
  494. responseType: 'arraybuffer',
  495. success: (res) => {
  496. try {
  497. const buffer = new Uint8Array(res.data);
  498. let binary = '';
  499. for (let i = 0; i < buffer.length; i++) {
  500. binary += String.fromCharCode(buffer[i]);
  501. }
  502. const base64 = uni.arrayBufferToBase64(res.data);
  503. const dataUri = 'data:image/jpeg;base64,' + base64;
  504. resolve(dataUri);
  505. } catch (e) {
  506. reject(e);
  507. }
  508. },
  509. fail: reject
  510. });
  511. });
  512. },
  513. goRegister() {
  514. uni.navigateTo({
  515. url: '/subpkg/pages/register/register'
  516. });
  517. }
  518. }
  519. }
  520. </script>
  521. <style lang="scss" scoped>
  522. .top-bar{
  523. .erweima-top{
  524. position: absolute;
  525. left: 16px;
  526. top: 15px;
  527. z-index: 999;
  528. }
  529. .search-icon{
  530. position: absolute;
  531. right: 16px;
  532. top: 15px;
  533. z-index: 22;
  534. ::v-deep .uni-icons{
  535. color: #fff !important;
  536. }
  537. }
  538. }
  539. .status-cards {
  540. display: flex;
  541. background-color: #fff;
  542. margin: 10px;
  543. border-radius: 8px;
  544. padding: 20px 10px;
  545. box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
  546. .status-card {
  547. flex: 1;
  548. display: flex;
  549. flex-direction: column;
  550. align-items: center;
  551. }
  552. .status-icon {
  553. display: flex;
  554. justify-content: center;
  555. align-items: center;
  556. width: 40px;
  557. height: 40px;
  558. margin-bottom: 6px;
  559. border-radius: 50%;
  560. }
  561. .icon-color1{
  562. background-color: #e4f2ff;
  563. }
  564. .icon-color2{
  565. background-color: #ffeff0;
  566. }
  567. .icon-color3{
  568. background-color: #e4fff4;
  569. }
  570. .icon-color4{
  571. background-color: #fef8e2;
  572. }
  573. .status-label {
  574. font-size: 12px;
  575. color: #333;
  576. }
  577. }
  578. swiper.banner-swiper{
  579. width: 100%;
  580. height: 130px;
  581. }
  582. swiper.banner-swiper image{
  583. width: 100%;
  584. height: 130px;
  585. }
  586. swiper.menu-swiper{
  587. width:100%;
  588. margin-top: 10px;
  589. background-color: #fff;
  590. }
  591. .menu-grid {
  592. display: grid;
  593. grid-template-columns: repeat(4, 1fr);
  594. .menu-item {
  595. flex: 1;
  596. display: flex;
  597. flex-direction: column;
  598. align-items: center;
  599. padding: 10px 0;
  600. .menu-icon{
  601. display: flex;
  602. flex-direction: column;
  603. justify-content: center;
  604. height: 30px;
  605. ::v-deep .uni-icons{
  606. color: #01a4fe !important;
  607. }
  608. }
  609. .menu-label {
  610. font-size: 12px;
  611. color: #333;
  612. text-align: center;
  613. }
  614. }
  615. }
  616. .library-card-section {
  617. display: flex;
  618. flex-direction: column;
  619. justify-content: space-between;
  620. align-items: center;
  621. width: 100%;
  622. padding: 20px 0;
  623. .section-title {
  624. font-size: 22px;
  625. font-weight: bold;
  626. background: linear-gradient(140deg, #01a4ff, #2ec8fe);
  627. -webkit-background-clip: text;
  628. color: transparent;
  629. letter-spacing: 0.1em;
  630. margin-bottom: 5px;
  631. }
  632. .card-icon {
  633. width: 80px;
  634. height: 80px;
  635. }
  636. .card-tip {
  637. font-size: 12px;
  638. color: #999;
  639. margin: 5px 0;
  640. }
  641. .bind-btn {
  642. display: flex;
  643. flex-direction: row;
  644. align-items: center;
  645. justify-content: center;
  646. border: 1px solid #06a8ff ;
  647. width: 128px !important;
  648. height: 28px;
  649. border-radius: 28px;
  650. background: linear-gradient(140deg, #01a4ff, #2ec8fe);
  651. font-size: 14px;
  652. color: #fff;
  653. line-height: 28px;
  654. }
  655. }
  656. .recommendation-section {
  657. background-color: #fff;
  658. margin: 10px;
  659. border-radius: 8px;
  660. padding: 0 0 10px 0;
  661. box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
  662. .section-title{
  663. display: flex;
  664. flex-direction: row;
  665. justify-content: space-between;
  666. align-items: center;
  667. height: 40px;
  668. padding: 0 10px;
  669. .left-txt{
  670. color: #343434;
  671. font-size: 15px;
  672. font-weight: 700;
  673. }
  674. .more-link{
  675. display: flex;
  676. flex-direction: row;
  677. justify-content: flex-start;
  678. align-items: center;
  679. color: #999;
  680. font-size: 11px;
  681. }
  682. }
  683. }
  684. .library-card-has {
  685. width: 100%;
  686. padding: 20px 10px;
  687. box-sizing: border-box;
  688. .section-title {
  689. font-size: 22px;
  690. font-weight: bold;
  691. background: linear-gradient(140deg, #01a4ff, #2ec8fe);
  692. -webkit-background-clip: text;
  693. color: transparent;
  694. letter-spacing: 0.1em;
  695. margin-bottom: 10px;
  696. padding-left: 5px;
  697. }
  698. .card-list {
  699. width: 100%;
  700. }
  701. }
  702. .card-swiper {
  703. height: 106px;
  704. .card-item{
  705. display: flex;
  706. justify-content: space-between;
  707. align-items: center;
  708. padding: 10px;
  709. border: 2px solid #C6C6E2;
  710. border-radius: 8px;
  711. background: rgba(241,241,249,0.4);
  712. cursor: pointer;
  713. &.active{
  714. border-color: #01a4fe;
  715. background: rgba(1, 164, 254, 0.1);
  716. }
  717. .card-left-img{
  718. width: 80px;
  719. margin-right: 12px;
  720. display: block;
  721. }
  722. .card-right-info{
  723. flex: 1;
  724. display: flex;
  725. flex-direction: column;
  726. .info-title{
  727. font-size: 16px;
  728. color: #333;
  729. font-weight: bold;
  730. padding-bottom: 12px;
  731. }
  732. .info-num{
  733. font-size: 14px;
  734. color: #999;
  735. }
  736. }
  737. .default-tag {
  738. position: absolute;
  739. right: 12px;
  740. top: 12px;
  741. font-size: 11px;
  742. color: #01a4fe;
  743. border: 1px solid #01a4fe;
  744. border-radius: 4px;
  745. padding: 2px 6px;
  746. }
  747. }
  748. }
  749. .erweima-style{
  750. position: absolute;
  751. right: 12px;
  752. bottom: 22px;
  753. ::v-deep .icon-erweima{
  754. // font-weight: bold;
  755. color: #999 !important;
  756. }
  757. }
  758. // .qrcode-popup {
  759. // padding: 20px;
  760. // border-radius: 12px;
  761. // background: #fff;
  762. // .qrcode-tip {
  763. // text-align: center;
  764. // font-size: 12px;
  765. // color: #999;
  766. // margin-top: 10px;
  767. // }
  768. // }
  769. </style>