裂变星小程序-25.03.04
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.

160 lines
3.6 KiB

  1. <template>
  2. <view class="page">
  3. <navbar leftClick @leftClick="$utils.navigateBack" />
  4. <view class="content">
  5. <video class="video"
  6. id="video"
  7. :src="detail.vio"
  8. autoplay
  9. play-btn-position="center"
  10. :controls="!timeIsUp"
  11. :show-fullscreen-btn="false"
  12. :show-center-play-btn="true"
  13. @timeupdate="onTimeupdate"
  14. ></video>
  15. <view class="info">
  16. <view class="author">{{ detail.author }}</view>
  17. <view class="title">{{ detail.headTitle }}</view>
  18. <view class="desc">{{ detail.textDetails }}</view>
  19. </view>
  20. </view>
  21. <uv-overlay :show="timeIsUp" @click="onPlay" zIndex="998">
  22. <popupUnlock ref="popupUnlock" src="../static/sharing/unlock-video.png"></popupUnlock>
  23. <popupQrCode ref="popupQrCode" :src="detail.wxCodeImage"></popupQrCode>
  24. </uv-overlay>
  25. </view>
  26. </template>
  27. <script>
  28. import popupUnlock from '../components/popupUnlock.vue'
  29. import popupQrCode from '../components/popupQrCode.vue'
  30. export default {
  31. components: {
  32. popupUnlock,
  33. popupQrCode,
  34. },
  35. data() {
  36. return {
  37. detail: {
  38. id: null,
  39. headTitle: null,
  40. indexImage: null,
  41. vio: null,
  42. timeNum: 10,
  43. num: 10,
  44. wxCodeImage: null,
  45. textDetails: null,
  46. },
  47. timeIsUp: false,
  48. isLocked: true,
  49. videoContext: null
  50. }
  51. },
  52. async onLoad(option) {
  53. const { id } = option
  54. await this.fetchDetails(id)
  55. this.videoContext = uni.createVideoContext('video');
  56. },
  57. onShareAppMessage(res) {
  58. const {
  59. headTitle,
  60. indexImage,
  61. } = this.detail
  62. let o = {
  63. title : headTitle,
  64. imageUrl: indexImage,
  65. query: `id=${this.id}`,
  66. }
  67. // todo: get times and check is unlocked
  68. this.refreshLockStatus()
  69. return o
  70. },
  71. methods: {
  72. async fetchDetails(id) {
  73. try {
  74. this.detail = await this.$fetch('getVideoShareInfo', { id })
  75. } catch (err) {
  76. }
  77. },
  78. async fetchCheckShare(id) {
  79. try {
  80. return await this.$fetch('checkVideoShare', { id })
  81. } catch (err) {
  82. return {}
  83. }
  84. },
  85. async refreshLockStatus() {
  86. const result = await this.fetchCheckShare()
  87. const { title, open } = result
  88. if (open) {
  89. this.isLocked = false
  90. this.$refs.popupUnlock.close();
  91. this.$refs.popupQrCode.open()
  92. return
  93. }
  94. title && uni.showToast({
  95. title,
  96. icon: 'none'
  97. })
  98. },
  99. async onPlay() {
  100. if (!this.isLocked) {
  101. this.$refs.popupQrCode.open()
  102. return
  103. }
  104. const result = await this.fetchCheckShare()
  105. const { open } = result
  106. if (open) { // 转发已达标
  107. this.isLocked = false
  108. this.$refs.popupQrCode.open()
  109. } else {
  110. this.$refs.popupUnlock.open();
  111. }
  112. },
  113. async onTimeupdate(e) {
  114. const { currentTime } = e.target
  115. // todo: check
  116. if (currentTime >= this.detail.timeNum) {
  117. this.videoContext.pause()
  118. this.timeIsUp = true
  119. this.onPlay()
  120. }
  121. },
  122. },
  123. }
  124. </script>
  125. <style scoped lang="scss">
  126. .video {
  127. width: 100%;
  128. height: calc(100vh - #{$navbar-height} - var(--status-bar-height) - 20rpx);
  129. }
  130. .info {
  131. color: #FFFFFF;
  132. font-size: 28rpx;
  133. position: fixed;
  134. left: 40rpx;
  135. bottom: 100rpx;
  136. .title {
  137. font-size: 32rpx;
  138. margin: 5rpx 0;
  139. }
  140. }
  141. </style>