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

736 lines
22 KiB

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