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.
280 lines
5.9 KiB
280 lines
5.9 KiB
<template>
|
|
<view class="dashboard-webview">
|
|
<!-- 加载状态 -->
|
|
<view v-if="isLoading" class="loading-container">
|
|
<uni-icons type="spinner-cycle" size="32" color="#29d3b4"></uni-icons>
|
|
<text class="loading-text">加载中...</text>
|
|
</view>
|
|
|
|
<!-- WebView容器 -->
|
|
<web-view
|
|
v-else-if="!hasError"
|
|
:src="webViewUrl"
|
|
@message="handleMessage"
|
|
@error="handleError"
|
|
@load="handleLoad"
|
|
class="webview-container"
|
|
></web-view>
|
|
|
|
<!-- 错误提示 -->
|
|
<view v-if="hasError" class="error-container">
|
|
<uni-icons type="close-filled" size="48" color="#ff5722"></uni-icons>
|
|
<text class="error-title">页面加载失败</text>
|
|
<text class="error-desc">{{ errorMessage }}</text>
|
|
<button class="retry-btn" @click="retry">重试</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
pageType: '',
|
|
pageTitle: '',
|
|
isLoading: true,
|
|
hasError: false,
|
|
errorMessage: '',
|
|
baseUrl: 'http://localhost:20080', // 后端基础URL
|
|
userToken: '',
|
|
userInfo: {}
|
|
}
|
|
},
|
|
computed: {
|
|
webViewUrl() {
|
|
if (!this.userToken) {
|
|
return '';
|
|
}
|
|
// 构建WebView URL,包含token和页面类型
|
|
const params = [
|
|
`token=${encodeURIComponent(this.userToken)}`,
|
|
`type=${encodeURIComponent(this.pageType)}`,
|
|
`platform=uniapp`
|
|
];
|
|
return `${this.baseUrl}/api/dashboard/webview?${params.join('&')}`;
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
// 从URL参数获取页面类型
|
|
this.pageType = options.type || 'my_data';
|
|
|
|
// 设置页面标题
|
|
const titleMap = {
|
|
'my_data': '我的数据',
|
|
'dept_data': '部门数据',
|
|
'campus_data': '校区数据'
|
|
};
|
|
this.pageTitle = titleMap[this.pageType] || '数据统计';
|
|
|
|
// 设置导航栏标题
|
|
uni.setNavigationBarTitle({
|
|
title: this.pageTitle
|
|
});
|
|
|
|
// 初始化WebView
|
|
this.initWebView();
|
|
},
|
|
methods: {
|
|
async initWebView() {
|
|
try {
|
|
// 获取用户信息和token
|
|
await this.getUserInfo();
|
|
|
|
// 延迟一下确保URL构建完成
|
|
setTimeout(() => {
|
|
this.isLoading = false;
|
|
}, 500);
|
|
} catch (error) {
|
|
console.error('初始化WebView失败:', error);
|
|
this.showError('初始化失败');
|
|
}
|
|
},
|
|
|
|
getUserInfo() {
|
|
return new Promise((resolve, reject) => {
|
|
try {
|
|
// 从本地存储获取用户信息
|
|
const userInfo = uni.getStorageSync('userInfo');
|
|
const token = uni.getStorageSync('token');
|
|
|
|
if (!token) {
|
|
// 如果没有token,使用测试token
|
|
this.userToken = 'test123';
|
|
this.userInfo = { name: '测试用户' };
|
|
} else {
|
|
this.userInfo = userInfo || {};
|
|
this.userToken = token;
|
|
}
|
|
|
|
resolve();
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
});
|
|
},
|
|
|
|
handleMessage(event) {
|
|
console.log('收到WebView消息:', event.detail.data);
|
|
const data = event.detail.data[0];
|
|
|
|
// 处理来自WebView的消息
|
|
switch (data.type) {
|
|
case 'navigate':
|
|
// 处理页面跳转
|
|
this.handleNavigate(data.url);
|
|
break;
|
|
case 'refresh':
|
|
// 处理刷新请求
|
|
this.refresh();
|
|
break;
|
|
case 'share':
|
|
// 处理分享功能
|
|
this.handleShare(data.content);
|
|
break;
|
|
default:
|
|
console.log('未处理的消息类型:', data.type);
|
|
}
|
|
},
|
|
|
|
handleError(event) {
|
|
console.error('WebView加载错误:', event);
|
|
this.showError('页面加载失败,请检查网络连接');
|
|
},
|
|
|
|
handleLoad(event) {
|
|
console.log('WebView加载完成:', event);
|
|
this.isLoading = false;
|
|
this.hasError = false;
|
|
},
|
|
|
|
handleNavigate(url) {
|
|
// 处理页面跳转,可以是UniApp页面或外部链接
|
|
if (url.startsWith('/pages')) {
|
|
// UniApp内部页面跳转
|
|
uni.navigateTo({
|
|
url: url,
|
|
fail: (err) => {
|
|
console.error('页面跳转失败:', err);
|
|
uni.showToast({
|
|
title: '页面跳转失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
// 外部链接,可以在当前WebView中打开或提示用户
|
|
uni.showModal({
|
|
title: '提示',
|
|
content: '是否在浏览器中打开链接?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.showToast({
|
|
title: '功能开发中',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
handleShare(content) {
|
|
// 处理分享功能
|
|
uni.showToast({
|
|
title: '分享功能开发中',
|
|
icon: 'none'
|
|
});
|
|
},
|
|
|
|
refresh() {
|
|
// 刷新页面
|
|
this.isLoading = true;
|
|
this.hasError = false;
|
|
|
|
// 重新初始化
|
|
setTimeout(() => {
|
|
this.initWebView();
|
|
}, 300);
|
|
},
|
|
|
|
retry() {
|
|
// 重试加载
|
|
this.hasError = false;
|
|
this.isLoading = true;
|
|
this.initWebView();
|
|
},
|
|
|
|
showError(message) {
|
|
this.isLoading = false;
|
|
this.hasError = true;
|
|
this.errorMessage = message;
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.dashboard-webview {
|
|
height: 100vh;
|
|
background-color: #181A20;
|
|
}
|
|
|
|
.loading-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100vh;
|
|
background-color: #181A20;
|
|
}
|
|
|
|
.loading-text {
|
|
margin-top: 16px;
|
|
font-size: 14px;
|
|
color: #29d3b4;
|
|
}
|
|
|
|
.webview-container {
|
|
height: 100vh;
|
|
width: 100%;
|
|
}
|
|
|
|
.error-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100vh;
|
|
background-color: #181A20;
|
|
padding: 40px;
|
|
}
|
|
|
|
.error-title {
|
|
margin-top: 16px;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
color: #fff;
|
|
}
|
|
|
|
.error-desc {
|
|
margin-top: 8px;
|
|
font-size: 14px;
|
|
color: rgba(255, 255, 255, 0.6);
|
|
text-align: center;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.retry-btn {
|
|
margin-top: 24px;
|
|
padding: 12px 24px;
|
|
background-color: #29d3b4;
|
|
color: #fff;
|
|
border-radius: 6px;
|
|
border: none;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.retry-btn:active {
|
|
background-color: #1a9b7c;
|
|
}
|
|
</style>
|