智慧教务系统
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

<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>