webview.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <view class="webview-page">
  3. <web-view
  4. :src="webviewUrl"
  5. @load="handleLoad"
  6. @error="handleError"
  7. class="webview-container"
  8. ></web-view>
  9. <!-- 加载状态 -->
  10. <view v-if="loading" class="loading-overlay">
  11. <view class="loading-content">
  12. <view class="loading-spinner"></view>
  13. <text class="loading-text">加载中...</text>
  14. </view>
  15. </view>
  16. </view>
  17. </template>
  18. <script setup>
  19. import { ref } from 'vue'
  20. import { onLoad } from '@dcloudio/uni-app'
  21. // 响应式数据
  22. const loading = ref(true)
  23. const webviewUrl = ref('')
  24. /**
  25. * 构建 webview URL
  26. */
  27. const buildWebviewUrl = (params) => {
  28. // 基础 H5 域名 - 同域部署
  29. // const baseUrl = 'http://127.0.0.1:5501/page/'
  30. // const baseUrl = 'https://yx.newfeifan.cn/page/'
  31. const baseUrl = 'https://m.hfdcschool.com/page'
  32. // 根据 dest 映射到对应的 HTML 文件
  33. const dest = params.dest || 'home'
  34. console.log(dest)
  35. let url = `${baseUrl}/${dest}.html`
  36. // 添加查询参数
  37. const queryParts = []
  38. // 传递所有参数给 H5
  39. Object.keys(params).forEach(key => {
  40. if (params[key] !== undefined && params[key] !== null) {
  41. // result参数已经是编码过的,不需要再次编码
  42. if (key === 'result') {
  43. queryParts.push(`${encodeURIComponent(key)}=${params[key]}`)
  44. } else {
  45. queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
  46. }
  47. }
  48. })
  49. // 添加小程序标识
  50. queryParts.push('from=miniprogram')
  51. queryParts.push(`timestamp=${Date.now()}`)
  52. // 添加认证信息 - JSESSIONID
  53. const jsessionId = uni.getStorageSync('JSESSIONID')
  54. if (jsessionId) {
  55. queryParts.push(`JSESSIONID=${encodeURIComponent(jsessionId)}`)
  56. }
  57. // 添加设备信息
  58. const deviceInfo = uni.getStorageSync("deviceInfo") || {}
  59. const devId = deviceInfo.deviceId || ''
  60. const sbmc = deviceInfo.model || ''
  61. if (devId) {
  62. queryParts.push(`devId=${encodeURIComponent(devId)}`)
  63. }
  64. if (sbmc) {
  65. queryParts.push(`sbmc=${encodeURIComponent(sbmc)}`)
  66. }
  67. if (queryParts.length > 0) {
  68. url += '?' + queryParts.join('&')
  69. }
  70. console.log('构建的 webview URL:', url)
  71. webviewUrl.value = url
  72. loading.value = false
  73. }
  74. /**
  75. * WebView 加载完成 - 监听 URL 参数
  76. */
  77. const handleLoad = (e) => {
  78. console.log('WebView 加载完成',e)
  79. loading.value = false
  80. // 获取当前 WebView 的 URL
  81. const currentUrl = e.detail.src || webviewUrl.value
  82. console.log('当前 WebView URL:', currentUrl+"."+e.detail.src)
  83. }
  84. /**
  85. * WebView 加载错误
  86. */
  87. const handleError = (e) => {
  88. console.error('WebView 加载错误:', e)
  89. loading.value = false
  90. }
  91. // 页面生命周期
  92. onLoad((options) => {
  93. console.log('webview 页面 onLoad:', options)
  94. buildWebviewUrl(options || {})
  95. })
  96. </script>
  97. <style scoped lang="scss">
  98. .webview-page {
  99. height: 100vh;
  100. background: #fff;
  101. }
  102. .webview-container {
  103. width: 100%;
  104. height: 100vh;
  105. }
  106. .loading-overlay {
  107. position: absolute;
  108. top: 0;
  109. left: 0;
  110. right: 0;
  111. bottom: 0;
  112. background: #fff;
  113. display: flex;
  114. align-items: center;
  115. justify-content: center;
  116. z-index: 999;
  117. }
  118. .loading-content {
  119. display: flex;
  120. flex-direction: column;
  121. align-items: center;
  122. }
  123. .loading-spinner {
  124. width: 60rpx;
  125. height: 60rpx;
  126. border: 4rpx solid #f3f3f3;
  127. border-top: 4rpx solid #007AFF;
  128. border-radius: 50%;
  129. animation: spin 1s linear infinite;
  130. }
  131. .loading-text {
  132. margin-top: 32rpx;
  133. font-size: 28rpx;
  134. color: #666;
  135. }
  136. @keyframes spin {
  137. 0% { transform: rotate(0deg); }
  138. 100% { transform: rotate(360deg); }
  139. }
  140. </style>