Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
飞
飞鹤小程序
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
FH
飞鹤小程序
Commits
5cbd6d49
Commit
5cbd6d49
authored
Nov 07, 2025
by
spc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gameWebview
parent
da8a3215
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
389 additions
and
0 deletions
+389
-0
webview.vue
pages/gameWebview/webview.vue
+389
-0
No files found.
pages/gameWebview/webview.vue
0 → 100644
View file @
5cbd6d49
<
template
>
<view
class=
"webview-container"
>
<!-- Webview内容 -->
<web-view
:src=
"webviewUrl"
:key=
"webviewUrl"
@
message=
"getMessage"
class=
"webview-content"
></web-view>
</view>
</
template
>
<
script
setup
>
import
{
ref
,
watch
,
nextTick
}
from
'vue'
import
{
useUserStore
}
from
'@/stores/user.js'
import
{
useGlobalStore
}
from
'../../stores/global'
import
{
fetchSyWebviewJSON
}
from
'../../api/sywebview'
import
{
fetchGameActConfigJSON
}
from
'../../api/home'
import
{
onLoad
,
onShow
,
onShareAppMessage
,
onShareTimeline
,
onPageScroll
}
from
"@dcloudio/uni-app"
;
import
{
jump
,
JumpType
}
from
'../../utils'
import
md
from
'../../md'
;
// 响应式数据
const
statusBarHeight
=
ref
(
0
)
const
webviewUrl
=
ref
(
''
)
const
share
=
ref
(
null
)
// 分享数据
const
pageOptions
=
ref
({})
const
registered
=
ref
(
undefined
)
// 获取用户store
const
userStore
=
useUserStore
()
const
globalStore
=
useGlobalStore
()
// 检查用户是否注册
function
getRegistered
()
{
return
!!
(
userStore
.
userInfo
&&
userStore
.
userInfo
?.
memberId
!==
"not_login"
)
}
// 处理返回逻辑
const
handleBack
=
()
=>
{
try
{
uni
.
navigateBack
({
delta
:
1
,
fail
:
()
=>
{
// 如果返回失败,跳转到首页
uni
.
redirectTo
({
url
:
'/pages/index/index'
})
}
})
}
catch
(
error
)
{
console
.
log
(
'返回失败:'
,
error
)
uni
.
redirectTo
({
url
:
'/pages/index/index'
})
}
}
// 登录获取 cuk
const
ensureAutoLogin
=
async
()
=>
{
await
new
Promise
(
resolve
=>
{
userStore
.
syWxAutoLogin
(
resolve
)
})
}
// 接收webview消息
const
getMessage
=
(
e
)
=>
{
console
.
log
(
'=== Webview 消息接收开始 ==='
)
console
.
log
(
'完整事件对象:'
,
e
)
console
.
log
(
'事件详情:'
,
e
.
detail
)
// 尝试多种方式获取数据
let
messageData
=
null
// 方式1:从 e.detail.data 获取
if
(
e
.
detail
&&
e
.
detail
.
data
)
{
messageData
=
e
.
detail
.
data
console
.
log
(
'从 e.detail.data 获取到数据:'
,
messageData
)
}
if
(
messageData
)
{
console
.
log
(
'消息数据类型:'
,
typeof
messageData
)
console
.
log
(
'消息数据是否为数组:'
,
Array
.
isArray
(
messageData
))
share
.
value
=
messageData
[
messageData
.
length
-
1
]
}
}
let
baseUrl
=
''
// 默认URL
// 初始化 webview URL
const
initWebviewUrl
=
async
()
=>
{
const
options
=
pageOptions
.
value
console
.
log
(
'页面参数 options:'
,
options
)
// 如果没有直接传入 URL,则从接口获取游戏配置
if
(
!
baseUrl
)
{
// 从接口获取游戏配置
const
configRes
=
await
fetchGameActConfigJSON
()
console
.
log
(
'游戏配置接口返回:'
,
configRes
)
if
(
configRes
&&
configRes
.
data
)
{
// 从链接参数中获取 gameType,默认为 'lianliankan'
const
gameType
=
options
.
gameType
||
'lianliankan'
baseUrl
=
configRes
.
data
[
gameType
].
url
}
}
if
(
!
baseUrl
)
{
uni
.
redirectTo
({
url
:
'/pages/index/index'
})
return
}
// 如果 baseUrl 已经包含协议,直接使用;否则添加协议
if
(
!
baseUrl
.
startsWith
(
'http://'
)
&&
!
baseUrl
.
startsWith
(
'https://'
))
{
baseUrl
=
'https://'
+
baseUrl
}
const
cuk
=
globalStore
.
cuk
const
openId
=
globalStore
.
openId
const
unionId
=
globalStore
.
unionId
// scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
const
scene
=
options
.
scene
?
decodeURIComponent
(
decodeURIComponent
(
options
.
scene
))
:
null
// 清理不需要传递给 H5 的参数
const
cleanOptions
=
{
...
options
}
delete
cleanOptions
.
scene
delete
cleanOptions
.
url
delete
cleanOptions
.
baseUrl
// gameType 不需要传递给 H5,因为它只是用来选择 baseUrl
delete
cleanOptions
.
gameType
console
.
log
(
"scene 参数:"
,
scene
)
console
.
log
(
"清理后的 options:"
,
cleanOptions
)
console
.
log
(
"原始 options:"
,
options
)
// 将 options 的所有参数原样作为查询参数传给 H5,并补齐 cuk
const
params
=
{
...
cleanOptions
}
if
(
cuk
&&
!
params
.
cuk
)
params
.
cuk
=
cuk
// 添加用户信息参数
if
(
openId
&&
!
params
.
miniopenid
)
params
.
miniopenid
=
openId
if
(
unionId
&&
!
params
.
unionId
)
params
.
unionId
=
unionId
// 获取会员信息(优先从 memberInfo 获取,如果没有则从 userInfo 获取)
const
memberInfo
=
userStore
.
memberInfo
||
userStore
.
userInfo
const
babyInfo
=
userStore
.
babyInfo
// 添加微信昵称(优先使用 babyInfo.babyName,没有则使用默认值)
if
(
babyInfo
?.
babyName
)
{
params
.
wxNickName
=
babyInfo
.
babyName
}
else
{
params
.
wxNickName
=
'暂无昵称'
}
// 添加 memberId(如果已注册)
if
(
memberInfo
?.
memberId
&&
memberInfo
.
memberId
!==
"not_login"
)
{
params
.
crmId
=
memberInfo
.
memberId
// 添加会员ID
params
.
memberid
=
memberInfo
.
memberId
// 添加是否登录(1表示已登录,0表示未登录)
params
.
programLogin
=
'1'
// 添加会员等级(从 gradeList 中根据 grade 获取 gradeName)
if
(
memberInfo
.
grade
!==
undefined
&&
memberInfo
.
grade
!==
null
)
{
// 优先从 gradeList 中查找对应的 gradeName
if
(
memberInfo
.
gradeList
&&
Array
.
isArray
(
memberInfo
.
gradeList
))
{
const
currentGrade
=
String
(
memberInfo
.
grade
)
const
gradeItem
=
memberInfo
.
gradeList
.
find
(
item
=>
String
(
item
.
grade
)
===
currentGrade
)
if
(
gradeItem
&&
gradeItem
.
gradeName
)
{
params
.
memberType
=
gradeItem
.
gradeName
}
else
if
(
memberInfo
.
gradeName
)
{
// 如果 gradeList 中找不到,使用 gradeName
params
.
memberType
=
memberInfo
.
gradeName
}
else
{
// 如果都没有,使用 grade 值
params
.
memberType
=
currentGrade
}
}
else
if
(
memberInfo
.
gradeName
)
{
// 如果没有 gradeList,使用 gradeName
params
.
memberType
=
memberInfo
.
gradeName
}
else
{
// 如果都没有,使用 grade 值
params
.
memberType
=
String
(
memberInfo
.
grade
)
}
}
}
else
{
// 未登录状态
params
.
programLogin
=
'0'
}
const
paramStr
=
Object
.
keys
(
params
)
.
filter
(
key
=>
params
[
key
]
!==
undefined
&&
params
[
key
]
!==
null
&&
params
[
key
]
!==
''
)
.
map
(
key
=>
`
${
key
}
=
${
encodeURIComponent
(
params
[
key
])}
`
)
.
join
(
'&'
)
// p 渠道参数
// openId 用户openid
// unionId 用户unionid
// cuk
// shareToken 分享人token
// pt 分享海报人token
// 示例:
// https://25niansuyuan.feihe.com/projects/Firmus/dev/index?p=xmh&openId=用户openid&unionId=用户unionid&&pt=yzhd123&shareToken=yzhd123&cuk=12121
// 处理 scene 参数
if
(
scene
)
{
// 如果 scene 以 ? 开头,直接拼接
if
(
scene
[
0
]
===
'?'
)
{
baseUrl
+=
scene
}
else
{
// 如果 scene 不以 ? 开头,需要判断 baseUrl 是否已有参数
baseUrl
+=
baseUrl
.
includes
(
'?'
)
?
`&
${
scene
}
`
:
`?
${
scene
}
`
}
}
// 拼接其他参数
if
(
paramStr
)
{
// 判断 baseUrl 是否已包含查询参数
const
separator
=
baseUrl
.
includes
(
'?'
)
?
'&'
:
'?'
webviewUrl
.
value
=
baseUrl
+
separator
+
paramStr
}
else
{
webviewUrl
.
value
=
baseUrl
}
console
.
log
(
'Webview页面加载,URL:'
,
webviewUrl
.
value
)
console
.
log
(
'参数字符串:'
,
paramStr
)
console
.
log
(
'基础URL:'
,
baseUrl
)
}
// 监听注册状态变化,初始化 webview URL
watch
(()
=>
registered
.
value
,
(
newVal
,
oldVal
)
=>
{
if
(
newVal
&&
newVal
!==
oldVal
)
{
nextTick
(()
=>
{
initWebviewUrl
()
})
}
})
// 页面显示时处理授权逻辑
onShow
(
async
()
=>
{
const
oldVal
=
registered
.
value
await
ensureAutoLogin
()
await
userStore
.
loadUserInfo
()
// 加载会员信息以获取 grade 等详细信息
await
userStore
.
loadMemberInfo
()
registered
.
value
=
getRegistered
()
if
(
oldVal
===
undefined
)
{
// 首次加载
// 不需要登录,直接初始化 URL
if
(
!
webviewUrl
.
value
)
{
await
initWebviewUrl
()
}
}
else
{
// 授权状态变化:如果从已注册变为未注册(授权失败),显示提示并返回
if
(
registered
.
value
===
false
)
{
uni
.
showToast
({
title
:
"授权失败,即将返回"
,
icon
:
"none"
,
});
setTimeout
(()
=>
{
handleBack
()
},
1000
)
}
}
})
// 页面参数接收
onLoad
(
async
(
options
)
=>
{
pageOptions
.
value
=
options
console
.
log
(
'页面参数:'
,
options
)
// 设置页面导航栏样式为自定义(去掉默认导航栏)
// #ifdef MP-WEIXIN
wx
.
setPageStyle
({
style
:
{
navigationStyle
:
'custom'
}
})
// #endif
wx
.
showShareMenu
({
withShareTicket
:
true
,
menus
:
[
'shareAppMessage'
,
'shareTimeline'
]
// shareAppMessage表示"发送给朋友"按钮,shareTimeline表示"分享到朋友圈"按钮
})
console
.
warn
(
"wx"
,
wx
.
showShareMenu
)
// 获取状态栏高度
const
systemInfo
=
uni
.
getSystemInfoSync
()
statusBarHeight
.
value
=
systemInfo
.
statusBarHeight
||
0
})
// 分享功能
onShareAppMessage
((
options
)
=>
{
console
.
log
(
'分享数据:'
,
share
.
value
)
console
.
log
(
'分享选项:'
,
options
)
md
.
sensorLogTake
({
xcxClick
:
"suyuan202508H5Click"
,
pageName
:
"星妈会分享页"
,
buttonName
:
"星妈会分享出"
,
});
if
(
share
.
value
)
{
const
shareurl
=
share
.
value
.
shareUrl
const
title
=
share
.
value
.
shareTitle
const
imageUrl
=
share
.
value
.
shareImageUrl
console
.
log
(
'使用分享数据:1'
,
{
title
,
shareurl
,
imageUrl
})
return
{
title
:
title
,
path
:
shareurl
||
'/pages/index/index'
,
imageUrl
:
imageUrl
||
''
,
success
:
function
(
res
)
{
console
.
log
(
'分享成功:'
,
res
)
//星妈会埋点方法,用户分享成功后触发事件
},
fail
:
function
(
res
)
{
console
.
log
(
'分享失败:'
,
res
)
},
complete
:
function
(
res
)
{
console
.
log
(
'分享完成:'
,
res
)
}
}
}
// 如果没有分享数据,返回默认分享
return
{
path
:
'/pages/index/index'
}
})
onShareTimeline
((
options
)
=>
{
console
.
log
(
'分享朋友圈数据:'
,
share
.
value
)
md
.
sensorLogTake
({
xcxClick
:
"suyuan202508H5Click"
,
pageName
:
"星妈会分享页"
,
buttonName
:
"星妈会分享出"
,
});
if
(
share
.
value
)
{
const
shareurl
=
share
.
value
.
shareUrl
const
title
=
share
.
value
.
shareTitle
const
imageUrl
=
share
.
value
.
shareImageUrl
console
.
log
(
'使用分享数据:'
,
{
title
,
shareurl
,
imageUrl
})
return
{
title
:
title
||
'分享'
,
path
:
shareurl
||
'/pages/gameWebview/webview'
,
imageUrl
:
imageUrl
||
''
,
success
:
function
(
res
)
{
//星妈会埋点方法,用户分享成功后触发事件
console
.
log
(
'分享成功:'
,
res
)
},
fail
:
function
(
res
)
{
console
.
log
(
'分享失败:'
,
res
)
},
complete
:
function
(
res
)
{
console
.
log
(
'分享完成:'
,
res
)
}
}
}
// 如果没有分享数据,返回默认分享
return
{
path
:
'/pages/index/index'
}
})
</
script
>
<
style
lang=
"less"
scoped
>
.webview-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #fff;
}
.webview-content {
flex: 1;
width: 100%;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment