webview.vue 3.6 KB

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