index-share.vue 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. <template>
  2. <div class="creation">
  3. <div class="playSection">
  4. <videoTcplayer v-if="playType === 'Video'" :src="musicDetail.videoUrl" :poster="musicDetail.videoImg || videoBg" />
  5. <div class="audioSection" v-if="playType === 'Audio'">
  6. <div class="audioContainer">
  7. <div class="waveActive" :style="{ width: audioWidth + '%' }"></div>
  8. <div class="waveDefault"></div>
  9. </div>
  10. <div class="audioBox">
  11. <div :class="['audioPan', paused ? 'imgRotate' : '']">
  12. <van-image class="audioImg" :src="musicDetail.img || musicBg" />
  13. </div>
  14. <i class="audioPoint"></i>
  15. <i :class="['audioZhen', paused && 'active']"></i>
  16. </div>
  17. <div class="controls" @click="onControls">
  18. <div class="actions">
  19. <div class="actionBtn" @click="onToggleAudio">
  20. <img v-if="paused" src="./img/icon-play.png" />
  21. <img v-else src="./img/icon-pause.png" />
  22. </div>
  23. </div>
  24. <div class="slider">
  25. <van-slider :step="0.01" class="timeProgress" v-model="currentTime" :max="duration" @input="handleChangeTime" @drag-start="dragStatus = true" @drag-end="dragStatus = false" />
  26. </div>
  27. <div class="time">
  28. <div>{{ getSecondRPM(currentTime) }}</div>
  29. <span>/</span>
  30. <div>{{ getSecondRPM(duration) }}</div>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. <van-cell class="userSection" center :border="false">
  36. <template #icon>
  37. <van-image class="userLogo" :src="musicDetail.avatar" />
  38. </template>
  39. <template #title>
  40. <div class="userInfo">
  41. <p class="name">
  42. <span>{{ musicDetail.username }}</span>
  43. <img v-if="musicDetail.vipFlag" src="./img/icon-member.png" class="iconMember" />
  44. </p>
  45. <p class="sub">
  46. {{ musicDetail.subjectName }}
  47. {{ getGradeCh(musicDetail.currentGradeNum - 1) }}
  48. </p>
  49. </div>
  50. </template>
  51. <template #default>
  52. <div :class="['zan', musicDetail.starFlag && 'zanActive']" @click="onStarChange">
  53. <img src="./img/icon-zan-active.png" v-if="musicDetail.starFlag" class="iconZan" />
  54. <img src="./img/icon-zan.png" v-else class="iconZan" />
  55. {{ musicDetail.likeNum }}
  56. </div>
  57. </template>
  58. </van-cell>
  59. <div class="musicSection">
  60. <div class="musicName">
  61. <span class="musicTag">曲目名称</span>
  62. {{ musicDetail.musicSheetName }}
  63. </div>
  64. <div class="musicDesc">{{ musicDetail.desc }}</div>
  65. </div>
  66. <div class="likeSection">
  67. <div class="likeTitle">推荐作品</div>
  68. <van-list v-if="listState.dataShow" class="container containerInformation" :finished="listState.finished" finished-text=" " :immediate-check="false" @load="getStarList()">
  69. <div class="cellGroup">
  70. <div v-for="(item, index) in list" :key="index" class="cell" @click="onDetail(item)">
  71. <div class="cellImg">
  72. <van-image class="cellImage" :src="item.img || musicBg" fit="cover" />
  73. <div class="iconZan">{{ item.likeNum }}</div>
  74. </div>
  75. <div class="cellTitle van-ellipsis">
  76. {{ item.musicSheetName }}
  77. </div>
  78. <div class="users">
  79. <van-image :src="item.avatar" class="userImg" />
  80. <span class="name">{{ item.username }}</span>
  81. </div>
  82. </div>
  83. </div>
  84. </van-list>
  85. <MEmpty v-else msg="暂无数据" />
  86. </div>
  87. <van-popup v-model="loginStatus" style="background: transparent;overflow: inherit ">
  88. <LoginModel @close="() => (this.loginStatus = false)" @confirm="onConfirm" />
  89. </van-popup>
  90. <van-popup v-model="messageStatus" class="wxPopupDialog">
  91. <div class="popupContainer">
  92. <p class="title1">温馨提示</p>
  93. <p class="popupTips">{{ message }}</p>
  94. </div>
  95. </van-popup>
  96. </div>
  97. </template>
  98. <script>
  99. import dayjs from "dayjs";
  100. import { getSecondRPM, browser, getGradeCh } from "@/common/common";
  101. import videoTcplayer from "@/components/video-tcplayer";
  102. import MEmpty from "@/components/MEmpty";
  103. import { postMessage } from "@/helpers/native-message";
  104. import { api_userMusicRemove, api_openUserMusicPage, api_userMusicStar, api_openUserMusicDetail } from "./api";
  105. import LoginModel from "./login-model";
  106. const audioDom = new Audio();
  107. audioDom.controls = true;
  108. audioDom.style.width = "100%";
  109. audioDom.className = "audio";
  110. export default {
  111. components: { videoTcplayer, MEmpty, LoginModel },
  112. data() {
  113. return {
  114. videoBg: require("./img/video-bg.png"),
  115. musicBg: require("./img/music_bg.png"),
  116. id: this.$route.query.id,
  117. loginTag: false, // 是否登录标识
  118. loginStatus: false,
  119. playType: "", // 播放类型
  120. musicDetail: {},
  121. timer: null,
  122. paused: true,
  123. audioWidth: 0,
  124. currentTime: 0,
  125. duration: 0.1,
  126. loop: false,
  127. dragStatus: false, // 是否开始拖动
  128. isClick: false,
  129. list: [],
  130. listState: {
  131. dataShow: true, // 判断是否有数据
  132. loading: false,
  133. finished: false,
  134. },
  135. params: {
  136. page: 1,
  137. rows: 20,
  138. },
  139. messageStatus: false,
  140. message: "",
  141. };
  142. },
  143. async mounted() {
  144. document.title = "作品详情";
  145. try {
  146. const res = await api_openUserMusicDetail(this.id);
  147. this.musicDetail = res.data || {};
  148. this.getStarList();
  149. // 判断是视频还是音频
  150. if (res.data.videoUrl.lastIndexOf("mp4") !== -1) {
  151. this.playType = "Video";
  152. } else {
  153. this.playType = "Audio";
  154. // 初始化
  155. this.$nextTick(() => {
  156. this.initAudio();
  157. });
  158. }
  159. } catch (e) {
  160. //
  161. if (e.code === 999) {
  162. this.messageStatus = true;
  163. this.message = e.msg;
  164. // this.$dialog
  165. // .alert({
  166. // message: e.msg,
  167. // theme: "round-button",
  168. // confirmButtonColor: "#2DC7AA",
  169. // })
  170. // .then(() => {
  171. // if (browser().isApp) {
  172. // postMessage({
  173. // api: "goBack",
  174. // });
  175. // } else {
  176. // this.$router.back();
  177. // }
  178. // });
  179. // return;
  180. }
  181. }
  182. // window.onpagehide = function() {
  183. // if (audioDom) {
  184. // audioDom.pause();
  185. // this.paused = audioDom.paused;
  186. // }
  187. // };
  188. // 设置隐藏属性和改变可见属性的事件的名称
  189. var hidden, visibilityChange;
  190. if (typeof document.hidden !== "undefined") {
  191. // Opera 12.10 and Firefox 18 and later support
  192. hidden = "hidden";
  193. visibilityChange = "visibilitychange";
  194. } else if (typeof document.msHidden !== "undefined") {
  195. hidden = "msHidden";
  196. visibilityChange = "msvisibilitychange";
  197. } else if (typeof document.webkitHidden !== "undefined") {
  198. hidden = "webkitHidden";
  199. visibilityChange = "webkitvisibilitychange";
  200. }
  201. // 如果页面是隐藏状态,则暂停视频
  202. // 如果页面是展示状态,则播放视频
  203. const that = this;
  204. function handleVisibilityChange() {
  205. if (document[hidden]) {
  206. if (audioDom) {
  207. audioDom.pause();
  208. that.paused = audioDom.paused;
  209. }
  210. }
  211. }
  212. // 如果浏览器不支持addEventListener 或 Page Visibility API 给出警告
  213. if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
  214. console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
  215. } else {
  216. // 处理页面可见属性的改变
  217. document.addEventListener(visibilityChange, handleVisibilityChange, false);
  218. }
  219. },
  220. methods: {
  221. onDetail(item) {
  222. if (audioDom) {
  223. audioDom.currentTime = 0;
  224. audioDom.pause();
  225. this.paused = audioDom.paused;
  226. }
  227. this.$router.push({
  228. path: "/shareCreation",
  229. query: {
  230. id: item.id,
  231. },
  232. });
  233. },
  234. /** 改变播放时间 */
  235. handleChangeTime(val) {
  236. this.currentTime = val;
  237. clearTimeout(this.timer);
  238. this.timer = setTimeout(() => {
  239. // audioRef.value.currentTime = val;
  240. audioDom.currentTime = val;
  241. this.timer = null;
  242. }, 60);
  243. },
  244. // 切换音频播放
  245. onToggleAudio(e) {
  246. e.stopPropagation();
  247. if (audioDom.paused) {
  248. audioDom.play();
  249. } else {
  250. audioDom.pause();
  251. }
  252. this.paused = audioDom.paused;
  253. },
  254. async onStarChange() {
  255. try {
  256. await api_userMusicStar({
  257. userMusicId: this.id,
  258. star: !this.musicDetail.starFlag,
  259. });
  260. this.musicDetail.starFlag = !this.musicDetail.starFlag;
  261. if (this.musicDetail.starFlag) {
  262. this.musicDetail.likeNum += 1;
  263. } else {
  264. this.musicDetail.likeNum -= 1;
  265. }
  266. } catch (e) {
  267. //
  268. if (e.code === 403) {
  269. this.loginStatus = true;
  270. }
  271. }
  272. },
  273. // 获取列表
  274. async getStarList() {
  275. try {
  276. if (this.isClick) return;
  277. this.isClick = true;
  278. const res = await api_openUserMusicPage({
  279. type: "FORMAL",
  280. exclusionId: this.id,
  281. sort: 1,
  282. ...this.params,
  283. });
  284. this.listState.loading = false;
  285. const result = res.data || {};
  286. // 处理重复请求数据
  287. if (this.list.length > 0 && result.current === 1) {
  288. return;
  289. }
  290. this.list = this.list.concat(result.rows || []);
  291. this.listState.finished = result.current >= result.pages;
  292. this.params.page = result.current + 1;
  293. this.listState.dataShow = this.list.length > 0;
  294. this.isClick = false;
  295. } catch {
  296. this.listState.dataShow = false;
  297. this.listState.finished = true;
  298. this.isClick = false;
  299. }
  300. },
  301. initAudio() {
  302. audioDom.src = this.musicDetail.videoUrl;
  303. audioDom.load();
  304. audioDom.oncanplaythrough = () => {
  305. this.paused = audioDom.paused;
  306. this.duration = audioDom.duration;
  307. };
  308. // 播放时监听
  309. audioDom.addEventListener("timeupdate", () => {
  310. this.duration = audioDom.duration;
  311. this.currentTime = audioDom.currentTime;
  312. const rate = (this.currentTime / this.duration) * 100;
  313. this.audioWidth = rate > 100 ? 100 : rate;
  314. });
  315. audioDom.addEventListener("ended", () => {
  316. this.paused = audioDom.paused;
  317. });
  318. },
  319. async onConfirm(val) {
  320. this.loginTag = val;
  321. this.loginStatus = false;
  322. const { data } = await api_openUserMusicDetail(this.id);
  323. this.musicDetail = data;
  324. },
  325. // 删除作品
  326. async onDelete() {
  327. try {
  328. await api_userMusicRemove({ id: this.id });
  329. setTimeout(() => {
  330. this.deleteStatus = false;
  331. this.$toast("删除成功");
  332. }, 100);
  333. setTimeout(() => {
  334. if (browser().isApp) {
  335. postMessage({
  336. api: "goBack",
  337. });
  338. } else {
  339. this.$router.back();
  340. }
  341. }, 1200);
  342. } catch {
  343. //
  344. }
  345. },
  346. // 下载
  347. async onDownload() {
  348. postMessage({
  349. api: "saveFile",
  350. content: {
  351. url: this.musicDetail.videoUrl,
  352. },
  353. });
  354. },
  355. onDayjs(time) {
  356. return dayjs(time).format("YYYY-MM-DD HH:mm");
  357. },
  358. getGradeCh,
  359. getSecondRPM,
  360. onControls(e) {
  361. e.stopPropagation();
  362. },
  363. },
  364. destory() {
  365. if (audioDom) {
  366. audioDom.pause();
  367. this.paused = audioDom.paused;
  368. }
  369. },
  370. watch: {
  371. $router(to) {
  372. this.id = to.query.id;
  373. this.playType = "";
  374. this.params.page = 1;
  375. if (audioDom) {
  376. audioDom.currentTime = 0;
  377. audioDom.pause();
  378. this.paused = audioDom.paused;
  379. }
  380. this.list = [];
  381. this.__init();
  382. },
  383. },
  384. };
  385. </script>
  386. <style scoped lang="less">
  387. .creation {
  388. min-height: 100vh;
  389. background-color: #f8f8f8;
  390. }
  391. /deep/ .vjs-poster {
  392. background-size: cover;
  393. }
  394. /deep/ .video-js .vjs-progress-control:hover .vjs-progress-holder {
  395. font-size: inherit !important;
  396. }
  397. /deep/ .video-js .vjs-slider:focus {
  398. box-shadow: none !important;
  399. text-shadow: none !important;
  400. }
  401. .playSection {
  402. min-height: 1.75rem;
  403. /deep/ .vjs-poster {
  404. background-size: cover;
  405. }
  406. /deep/ .video-js .vjs-progress-control:hover .vjs-progress-holder {
  407. font-size: inherit !important;
  408. }
  409. /deep/ .video-js .vjs-slider:focus {
  410. box-shadow: none !important;
  411. text-shadow: none !important;
  412. }
  413. }
  414. @keyframes rotateImg {
  415. 100% {
  416. transform: rotate(360deg);
  417. }
  418. }
  419. .audioSection {
  420. position: relative;
  421. background: url("./img/audio-banner-bg.png") no-repeat top center;
  422. background-size: cover;
  423. height: 1.75rem;
  424. .audioContainer {
  425. position: absolute;
  426. top: 0;
  427. left: 50%;
  428. width: 1.96rem;
  429. height: 0.35rem;
  430. transform: translate(-50%, 0.6rem);
  431. .waveActive,
  432. .waveDefault {
  433. width: 100%;
  434. height: 100%;
  435. }
  436. .waveDefault {
  437. position: absolute;
  438. top: 0;
  439. left: 0;
  440. background: url("./img/wave-1.png") no-repeat center left;
  441. background-size: cover;
  442. }
  443. .waveActive {
  444. position: absolute;
  445. top: 0;
  446. left: 0;
  447. z-index: 1;
  448. background: url("./img/wave-2.png") no-repeat center left;
  449. background-size: cover;
  450. }
  451. }
  452. .audioBox {
  453. position: absolute;
  454. left: 50%;
  455. transform: translate(-50%, 50%);
  456. z-index: 2;
  457. width: 0.74rem;
  458. height: 0.75rem;
  459. background: url("./img/audio-bg.png") no-repeat center;
  460. background-size: contain;
  461. .audioPan {
  462. position: absolute;
  463. left: 0.08rem;
  464. top: 0.06rem;
  465. z-index: 8;
  466. width: 0.59rem;
  467. height: 0.6rem;
  468. background: url("./img/audio-pan.png") no-repeat center;
  469. background-size: contain;
  470. display: flex;
  471. align-items: center;
  472. justify-content: center;
  473. animation: rotateImg 6s linear infinite;
  474. &.imgRotate {
  475. animation-play-state: paused;
  476. }
  477. }
  478. .audioImg {
  479. width: 0.32rem;
  480. height: 0.32rem;
  481. border-radius: 50%;
  482. overflow: hidden;
  483. }
  484. .audioPoint {
  485. position: absolute;
  486. z-index: 9;
  487. left: 50%;
  488. top: 50%;
  489. transform: translate(-50%, -50%);
  490. width: 0.08rem;
  491. height: 0.08rem;
  492. background: url("./img/audio-point.png") no-repeat center;
  493. background-size: contain;
  494. }
  495. .audioZhen {
  496. position: absolute;
  497. z-index: 9;
  498. right: -0.04rem;
  499. top: -0.33rem;
  500. width: 0.26rem;
  501. height: 0.87rem;
  502. background: url("./img/audio-zhen.png") no-repeat center;
  503. background-size: contain;
  504. transition: transform 0.5s ease-in-out;
  505. &.active {
  506. transform: rotate(92deg) translate3d(0, 0, 3px);
  507. transition: transform 0.5s ease-in-out;
  508. }
  509. }
  510. }
  511. }
  512. .controls {
  513. position: absolute;
  514. left: 0;
  515. bottom: 0;
  516. right: 0;
  517. height: 0.44rem;
  518. display: flex;
  519. flex-direction: column;
  520. justify-content: space-between;
  521. flex-direction: row;
  522. transition: all 0.5s;
  523. padding: 0 0.12rem;
  524. & > div {
  525. display: flex;
  526. align-items: center;
  527. }
  528. &.hide {
  529. transform: translateY(100%);
  530. }
  531. .actionBtn {
  532. line-height: 0;
  533. margin-right: 0.04rem;
  534. img {
  535. width: 0.14rem;
  536. height: 0.14rem;
  537. margin-bottom: -0.02rem;
  538. }
  539. }
  540. .time {
  541. display: flex;
  542. justify-content: space-between;
  543. flex: 1;
  544. min-width: 0.86rem;
  545. font-size: 0.12rem;
  546. color: #131415;
  547. line-height: 0.2rem;
  548. span {
  549. font-size: 0.12rem;
  550. padding: 0 0.01rem;
  551. }
  552. }
  553. .slider {
  554. width: 100%;
  555. margin: 0 0.12rem;
  556. // --van-slider-bar-height: 4px;
  557. // --van-slider-button-width: 0.13rem !important;
  558. // --van-slider-button-height: 0.13rem !important;
  559. // --van-slider-inactive-background: #fff;
  560. // --van-slider-inactive-background-color: #fff;
  561. // --van-slider-active-background: #2DC7AA !important;
  562. /deep/ .van-slider {
  563. height: 0.04rem;
  564. }
  565. /deep/ .van-slider__button {
  566. width: 0.13rem;
  567. height: 0.13rem;
  568. }
  569. /deep/ .van-loading {
  570. width: 100%;
  571. height: 100%;
  572. }
  573. }
  574. }
  575. .userSection {
  576. padding: 0.15rem 0.12rem !important;
  577. background-color: transparent !important;
  578. .userLogo {
  579. width: 0.44rem;
  580. height: 0.44rem;
  581. border: 0.01rem solid #ffffff;
  582. margin-right: 0.1rem;
  583. border-radius: 50%;
  584. overflow: hidden;
  585. }
  586. .userInfo {
  587. .name {
  588. display: flex;
  589. align-items: center;
  590. font-size: 0.16rem;
  591. font-weight: 500;
  592. color: #333333;
  593. line-height: 0.22rem;
  594. span {
  595. display: inline-block;
  596. white-space: nowrap;
  597. overflow: hidden;
  598. text-overflow: ellipsis;
  599. max-width: 1rem;
  600. }
  601. }
  602. .sub {
  603. padding-top: 0.01rem;
  604. font-size: 0.12rem;
  605. color: #777777;
  606. line-height: 0.17rem;
  607. }
  608. .iconMember {
  609. margin-left: 0.06rem;
  610. width: 0.14rem;
  611. height: 0.14rem;
  612. }
  613. }
  614. .zan {
  615. background: #ffffff;
  616. border-radius: 0.13rem;
  617. font-size: 0.14rem;
  618. color: #777777;
  619. line-height: 0.2rem;
  620. padding: 0.04rem 0.09rem 0.03rem;
  621. display: inline-flex;
  622. align-items: center;
  623. &.zanActive {
  624. background: #f7eeee;
  625. color: #ff6a6a;
  626. }
  627. .iconZan {
  628. width: 0.18rem;
  629. height: 0.18rem;
  630. margin-right: 0.01rem;
  631. }
  632. }
  633. }
  634. .musicSection {
  635. margin: 0 0.13rem 0.12rem;
  636. padding: 0.14rem 0.12rem;
  637. background: #ffffff;
  638. border-radius: 0.1rem;
  639. .musicName {
  640. font-size: 0.15rem;
  641. font-weight: 500;
  642. color: #333333;
  643. line-height: 0.21rem;
  644. // display: flex;
  645. // align-items: center;
  646. overflow: hidden;
  647. text-overflow: ellipsis;
  648. white-space: nowrap;
  649. max-width: 100%;
  650. .musicTag {
  651. margin-right: 0.06rem;
  652. padding: 0.01rem 0.06rem;
  653. font-size: 0.12rem;
  654. color: #ff7b31;
  655. line-height: 0.17rem;
  656. background: rgba(255, 166, 115, 0.07);
  657. border-radius: 0.09rem;
  658. border: 0.01rem solid #ffbf9a;
  659. font-weight: 400;
  660. vertical-align: text-bottom;
  661. display: inline-block;
  662. }
  663. }
  664. .musicDesc {
  665. padding-top: 0.08rem;
  666. font-size: 0.14rem;
  667. color: #777777;
  668. line-height: 0.2rem;
  669. }
  670. }
  671. .likeSection {
  672. margin: 0 0.13rem 0.12rem;
  673. background: #ffffff;
  674. border-radius: 0.1rem;
  675. padding: 0.1rem 0.12rem;
  676. .likeTitle {
  677. display: flex;
  678. align-items: center;
  679. font-size: 0.17rem;
  680. font-weight: 600;
  681. color: #333333;
  682. line-height: 0.24rem;
  683. padding-bottom: 0.08rem;
  684. &::before {
  685. display: inline-block;
  686. content: "";
  687. width: 0.04rem;
  688. height: 0.14rem;
  689. border-radius: 0.01rem;
  690. background: linear-gradient(to bottom, #59e5d5, #2dc7aa);
  691. margin-right: 0.06rem;
  692. }
  693. }
  694. }
  695. .likeItem {
  696. padding: 0.16rem 0;
  697. .userLogo {
  698. border-radius: 50%;
  699. overflow: hidden;
  700. width: 0.42rem;
  701. height: 0.42rem;
  702. margin-right: 0.07rem;
  703. }
  704. .userInfo {
  705. .name {
  706. font-size: 0.16rem;
  707. font-weight: 500;
  708. color: #333333;
  709. line-height: 0.22rem;
  710. }
  711. .sub {
  712. padding-top: 0.01rem;
  713. font-size: 0.13rem;
  714. color: #777777;
  715. line-height: 0.18rem;
  716. }
  717. }
  718. .time {
  719. font-size: 0.13rem;
  720. color: #777777;
  721. line-height: 0.18rem;
  722. }
  723. }
  724. .bottomSection {
  725. display: flex;
  726. align-items: center;
  727. justify-content: space-between;
  728. background-color: #fff;
  729. padding: 0.15rem 0.12rem calc(0.15rem + env(safe-area-inset-bottom));
  730. .bottomShare {
  731. display: flex;
  732. align-items: center;
  733. p {
  734. padding: 0 0.15rem;
  735. text-align: center;
  736. line-height: 0;
  737. &:first-child {
  738. padding-left: 0.05rem;
  739. }
  740. }
  741. img {
  742. width: 0.18rem;
  743. height: 0.18rem;
  744. }
  745. span {
  746. padding-top: 0.08rem;
  747. font-size: 0.12rem;
  748. color: #333333;
  749. line-height: 0.17rem;
  750. display: block;
  751. }
  752. }
  753. .btnEdit {
  754. font-size: 0.14rem;
  755. font-weight: 500;
  756. background: #2dc7aa;
  757. color: #ffffff;
  758. line-height: 0.22rem;
  759. min-width: 0.8rem;
  760. height: 0.3rem;
  761. border: none;
  762. }
  763. }
  764. .popupContainer {
  765. width: 80%;
  766. .popupContent {
  767. padding: 0.29rem 0 0.25rem;
  768. text-align: center;
  769. font-size: 0.18rem;
  770. font-weight: 500;
  771. color: #333333;
  772. line-height: 0.25rem;
  773. }
  774. .popupBtnGroup {
  775. text-align: center;
  776. margin-bottom: 0.22rem;
  777. .van-button {
  778. height: 0.4rem;
  779. font-size: 0.16rem;
  780. font-weight: 400 !important;
  781. line-height: 0.22rem;
  782. min-width: 1.22rem;
  783. &:last-child {
  784. margin-left: 0.1rem;
  785. background: #2dc7aa;
  786. border: none;
  787. }
  788. }
  789. }
  790. }
  791. .cellGroup {
  792. display: flex;
  793. flex-wrap: wrap;
  794. }
  795. .cell {
  796. // display: flex;
  797. // flex-direction: column;
  798. width: 0.96rem;
  799. margin-right: 0.18rem;
  800. margin-bottom: 0.18rem;
  801. &:nth-child(3n + 3) {
  802. margin-right: 0;
  803. }
  804. .cellImg {
  805. position: relative;
  806. width: 0.88rem;
  807. height: 0.88rem;
  808. &::before {
  809. content: "";
  810. position: absolute;
  811. right: -0.06rem;
  812. top: 0.03rem;
  813. z-index: 8;
  814. width: 0.84rem;
  815. height: 0.84rem;
  816. background: url("./img/audio-pan.png") no-repeat center;
  817. background-size: contain;
  818. display: flex;
  819. align-items: center;
  820. justify-content: center;
  821. }
  822. .iconZan {
  823. position: absolute;
  824. bottom: 0.04rem;
  825. left: 0.04rem;
  826. z-index: 10;
  827. padding: 0.03rem;
  828. background: rgba(67, 67, 67, 0.3);
  829. border-radius: 0.08rem;
  830. backdrop-filter: blur(0.04rem);
  831. font-size: 0.09rem;
  832. font-weight: 500;
  833. color: #ffffff;
  834. line-height: 0.13rem;
  835. display: flex;
  836. align-items: center;
  837. &::before {
  838. content: "";
  839. display: inline-block;
  840. width: 0.12rem;
  841. height: 0.12rem;
  842. background: url("./img/icon-z.png") no-repeat center;
  843. background-size: contain;
  844. }
  845. }
  846. }
  847. .cellImage {
  848. position: relative;
  849. width: 0.88rem;
  850. height: 0.88rem;
  851. border-radius: 0.12rem;
  852. overflow: hidden;
  853. z-index: 9;
  854. img {
  855. border-radius: 0.12rem;
  856. }
  857. }
  858. .cellTitle {
  859. font-size: 0.13rem;
  860. color: #131415;
  861. line-height: 0.18rem;
  862. margin: 0.08rem 0 0.06rem;
  863. }
  864. .users {
  865. display: flex;
  866. align-items: center;
  867. .userImg {
  868. width: 0.2rem;
  869. height: 0.2rem;
  870. border-radius: 50%;
  871. overflow: hidden;
  872. margin-right: 0.04rem;
  873. flex-shrink: 0;
  874. }
  875. .name {
  876. font-size: 0.12rem;
  877. color: #402424;
  878. line-height: 0.14rem;
  879. }
  880. }
  881. }
  882. .sticky-section {
  883. position: fixed;
  884. bottom: 0;
  885. left: 0;
  886. right: 0;
  887. }
  888. .wxPopupDialog {
  889. // position: relative;
  890. overflow: initial;
  891. width: 88%;
  892. background: transparent;
  893. // margin-top: -160px;
  894. &::before {
  895. position: absolute;
  896. content: " ";
  897. top: -0.2rem;
  898. left: 50%;
  899. margin-left: -0.51rem;
  900. display: inline-block;
  901. background: url("./img/wx-no-top.png") no-repeat top center;
  902. background-size: contain;
  903. width: 1.02rem;
  904. height: 0.84rem;
  905. }
  906. }
  907. .popupContainer {
  908. background: url("./img/wx-no-bg.png") no-repeat top center #fff;
  909. background-size: cover;
  910. border-radius: 0.2rem;
  911. overflow: hidden;
  912. padding-bottom: 0.16rem;
  913. text-align: center;
  914. width: 100%;
  915. .title1 {
  916. padding-top: 0.57rem;
  917. text-align: center;
  918. font-size: 0.18rem;
  919. font-weight: 500;
  920. color: #3b2300;
  921. }
  922. .popupTips {
  923. padding-top: 0.16rem;
  924. padding-bottom: 0.16rem;
  925. text-align: center;
  926. font-size: 0.15rem;
  927. color: #777777;
  928. line-height: 0.21rem;
  929. }
  930. .button {
  931. padding: 0 0.32rem;
  932. height: 0.3rem;
  933. font-size: 0.16rem;
  934. font-size: 0.14rem;
  935. color: #777;
  936. border-color: #e7e7e7;
  937. }
  938. }
  939. </style>