四零语境前端代码仓库
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.

307 lines
6.7 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
2 weeks 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
1 month ago
  1. <template>
  2. <view v-if="showSplash" class="splash-screen">
  3. <!-- 富文本內容 -->
  4. <view class="splash-content">
  5. <image
  6. :src="splashContent"
  7. mode="aspectFit"
  8. class="splash-image"
  9. @error="onImageError"
  10. @load="onImageLoad"
  11. />
  12. </view>
  13. <!-- 跳過按鈕 -->
  14. <view class="skip-button" >
  15. <text class="skip-text">跳过 ({{ countdown }}s)</text>
  16. </view>
  17. <!-- 定位英語文字和中文文字到左下角 -->
  18. <view class="text-container">
  19. <text class="english-text">
  20. {{ configParamContent('creen_en') }}
  21. </text>
  22. <text class="chinese-text">
  23. {{ configParamContent('creen_zh') }}
  24. </text>
  25. </view>
  26. </view>
  27. </template>
  28. <script>
  29. // import config from '../../mixins/config.js'
  30. export default {
  31. name: 'SplashScreen',
  32. // mixins: [config],
  33. props: {
  34. // 顯示時長(秒)
  35. duration: {
  36. type: Number,
  37. default: 2
  38. }
  39. },
  40. data() {
  41. return {
  42. showSplash: false,
  43. countdown: 5,
  44. timer: null,
  45. splashContent: ''
  46. }
  47. },
  48. computed: {
  49. image() {
  50. try {
  51. // 優先從配置獲取
  52. const configImage = this.configParamContent && this.configParamContent('creen_image')
  53. if (configImage && configImage !== 'undefined' && configImage !== '') {
  54. return configImage
  55. }
  56. // 備用方案:從本地存儲獲取
  57. const storageImage = uni.getStorageSync('screen_image')
  58. if (storageImage && storageImage !== 'undefined' && storageImage !== '') {
  59. return storageImage
  60. }
  61. return ''
  62. } catch (error) {
  63. console.error('獲取開屏圖片失敗:', error)
  64. return ''
  65. }
  66. }
  67. },
  68. mounted() {
  69. this.initSplash()
  70. if(!this.hasShownSplash()){
  71. uni.hideTabBar()
  72. }
  73. },
  74. beforeDestroy() {
  75. this.clearTimer()
  76. },
  77. methods: {
  78. // 檢查是否為H5环境
  79. isH5() {
  80. // #ifdef H5
  81. return true
  82. // #endif
  83. // #ifndef H5
  84. return false
  85. // #endif
  86. },
  87. // 檢查是否已显示过开屏
  88. hasShownSplash() {
  89. if (this.isH5()) {
  90. try {
  91. return sessionStorage.getItem('splash_shown') === 'true'
  92. } catch (error) {
  93. console.error('读取sessionStorage失败:', error)
  94. return false
  95. }
  96. }
  97. return false
  98. },
  99. // 设置开屏已显示标记
  100. setSplashShown() {
  101. if (this.isH5()) {
  102. try {
  103. sessionStorage.setItem('splash_shown', 'true')
  104. } catch (error) {
  105. console.error('设置sessionStorage失败:', error)
  106. }
  107. }
  108. },
  109. // 初始化开动頁面
  110. async initSplash() {
  111. try {
  112. // 在H5环境下检查是否已显示过开屏
  113. if (this.hasShownSplash()) {
  114. console.log('开屏已显示过,跳过开屏动画')
  115. this.$emit('close')
  116. this.closeSplash()
  117. return
  118. }
  119. // 等待一小段時間確保 store 數據加載完成
  120. await this.$nextTick()
  121. // 獲取圖片URL,優先使用配置,然後使用本地存儲
  122. let imageUrl = ''
  123. // 嘗試從配置獲取
  124. if (this.$store.state.configList && this.$store.state.configList['creen_image']) {
  125. imageUrl = this.configParamContent('creen_image')
  126. }
  127. // 如果配置中沒有,嘗試從本地存儲獲取
  128. if (!imageUrl) {
  129. imageUrl = uni.getStorageSync('screen_image')
  130. }
  131. console.log('開屏圖片URL:', imageUrl)
  132. // 如果有圖片URL才顯示開屏
  133. if (imageUrl && imageUrl !== 'undefined' && imageUrl !== '') {
  134. this.splashContent = imageUrl
  135. this.countdown = this.duration
  136. this.showSplash = true
  137. this.startCountdown()
  138. } else {
  139. console.log('沒有開屏圖片,跳過開屏動畫')
  140. this.$emit('close')
  141. }
  142. } catch (error) {
  143. console.error('獲取開動頁面內容失敗:', error)
  144. // 發生錯誤時直接關閉開屏
  145. this.$emit('close')
  146. }
  147. },
  148. // 開始倒計時
  149. startCountdown() {
  150. this.timer = setInterval(() => {
  151. this.countdown--
  152. if (this.countdown <= 0) {
  153. this.closeSplash()
  154. }
  155. }, 1000)
  156. },
  157. // 關閉開動頁面
  158. closeSplash() {
  159. this.showSplash = false
  160. // 在H5环境下设置开屏已显示标记
  161. this.setSplashShown()
  162. uni.showTabBar({
  163. animation: true
  164. })
  165. this.clearTimer()
  166. this.$emit('close')
  167. },
  168. // 清除計時器
  169. clearTimer() {
  170. if (this.timer) {
  171. clearInterval(this.timer)
  172. this.timer = null
  173. }
  174. },
  175. // 圖片加載成功
  176. onImageLoad() {
  177. console.log('開屏圖片加載成功')
  178. },
  179. // 圖片加載失敗
  180. onImageError(e) {
  181. console.error('開屏圖片加載失敗:', e)
  182. // 圖片加載失敗時直接關閉開屏
  183. this.closeSplash()
  184. }
  185. }
  186. }
  187. </script>
  188. <style lang="scss" scoped>
  189. .splash-screen {
  190. position: fixed;
  191. top: 0;
  192. left: 0;
  193. width: 100vw;
  194. height: 100vh;
  195. background-color: #fff;
  196. z-index: 9999;
  197. display: flex;
  198. flex-direction: column;
  199. .splash-image{
  200. width: 100%;
  201. height: 100%;
  202. }
  203. }
  204. .splash-content {
  205. flex: 1;
  206. width: 100%;
  207. height: 80%;
  208. overflow: hidden;
  209. // 富文本樣式
  210. :deep(rich-text) {
  211. width: 100%;
  212. height: 100%;
  213. display: block;
  214. img{
  215. width: 100%;
  216. height: 100%;
  217. }
  218. }
  219. }
  220. .skip-button {
  221. position: absolute;
  222. top: 40rpx;
  223. left: 40rpx;
  224. background-color: #0000004D;
  225. border-radius: 100rpx;
  226. width: 148rpx ;
  227. height: 60rpx;
  228. text-align: center;
  229. z-index: 10000;
  230. .skip-text {
  231. font-size: 24rpx;
  232. line-height: 60rpx;
  233. color: #fff;
  234. }
  235. }
  236. // 文字容器定位到左下角
  237. .text-container {
  238. // position: absolute;
  239. // bottom: 80rpx;
  240. // left: 40rpx;
  241. // z-index: 10001;
  242. height: 20%;
  243. width: 100%;
  244. padding: 20rpx;
  245. display: flex;
  246. flex-direction: column;
  247. gap: 30rpx;
  248. }
  249. // 英文文字样式
  250. .english-text {
  251. font-family: PingFang SC;
  252. font-weight: 600;
  253. font-size: 32rpx; // 16px转换为rpx
  254. line-height: 48rpx; // 24px转换为rpx
  255. letter-spacing: 0;
  256. color: black;
  257. background: transparent;
  258. }
  259. // 中文文字样式
  260. .chinese-text {
  261. font-family: PingFang SC;
  262. // font-weight: 600;
  263. font-size: 32rpx; // 16px转换为rpx
  264. line-height: 48rpx; // 24px转换为rpx
  265. letter-spacing: 0;
  266. color: black;
  267. background: transparent;
  268. }
  269. // 確保覆蓋 tabbar
  270. .splash-screen {
  271. // 覆蓋所有內容,包括 tabbar
  272. position: fixed !important;
  273. z-index: 9999 !important;
  274. }
  275. </style>