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

879 lines
24 KiB

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