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

318 lines
6.7 KiB

<template>
<view class="dashboard-webview">
<uni-nav-bar
:statusBar="true"
backgroundColor="#181A20"
color="#fff"
:title="pageTitle"
leftIcon="back"
@clickLeft="goBack"
/>
<!-- 加载状态 -->
<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
: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 {
name: 'DashboardWebView',
props: {
// WebView页面类型:my_data, dept_data, campus_data
pageType: {
type: String,
required: true
},
// 页面标题
title: {
type: String,
default: '数据统计'
}
},
data() {
return {
isLoading: true,
hasError: false,
errorMessage: '',
baseUrl: 'http://localhost:20080', // 后端基础URL
userToken: '',
userInfo: {}
}
},
computed: {
pageTitle() {
const titleMap = {
'my_data': '我的数据',
'dept_data': '部门数据',
'campus_data': '校区数据'
};
return titleMap[this.pageType] || this.title;
},
webViewUrl() {
if (!this.userToken) {
return '';
}
// 构建WebView URL,包含token和页面类型
const params = new URLSearchParams({
token: this.userToken,
type: this.pageType,
platform: 'uniapp'
});
return `${this.baseUrl}/api/dashboard/webview?${params.toString()}`;
}
},
onLoad() {
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 (!userInfo || !token) {
throw new Error('用户信息或token不存在');
}
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.share({
provider: "weixin",
scene: "WXSceneSession",
type: 0,
href: content.url || '',
title: content.title || this.pageTitle,
summary: content.summary || '数据统计分享',
imageUrl: content.image || '',
success: (res) => {
console.log('分享成功:', res);
uni.showToast({
title: '分享成功',
icon: 'success'
});
},
fail: (err) => {
console.error('分享失败:', err);
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;
},
goBack() {
uni.navigateBack({
delta: 1,
fail: () => {
// 如果无法返回,则跳转到首页
uni.reLaunch({
url: '/pages/common/home/index'
});
}
});
}
}
}
</script>
<style scoped>
.dashboard-webview {
height: 100vh;
background-color: #181A20;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: calc(100vh - 44px - var(--status-bar-height));
background-color: #181A20;
}
.loading-text {
margin-top: 16px;
font-size: 14px;
color: #29d3b4;
}
.webview-container {
height: calc(100vh - 44px - var(--status-bar-height));
}
.error-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: calc(100vh - 44px - var(--status-bar-height));
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>