修改小程序
This commit is contained in:
296
government-mini-program/pages/statistics/statistics.js
Normal file
296
government-mini-program/pages/statistics/statistics.js
Normal file
@@ -0,0 +1,296 @@
|
||||
// pages/statistics/statistics.js
|
||||
const app = getApp();
|
||||
const apiService = require('../../utils/api.js');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
statusBarHeight: 0,
|
||||
loading: true,
|
||||
|
||||
// 统计数据
|
||||
todayStats: {
|
||||
totalFarmers: 0,
|
||||
activeFarmers: 0,
|
||||
totalAnimals: 0,
|
||||
alertCount: 0
|
||||
},
|
||||
|
||||
// 趋势数据
|
||||
trendData: {
|
||||
farmerGrowth: 0,
|
||||
animalGrowth: 0,
|
||||
alertTrend: 0
|
||||
},
|
||||
|
||||
// 快捷操作
|
||||
quickActions: [
|
||||
{
|
||||
id: 'farmer_manage',
|
||||
title: '养殖户管理',
|
||||
icon: 'farmer',
|
||||
color: '#2c5aa0',
|
||||
path: '/pages/farmer/farmer'
|
||||
},
|
||||
{
|
||||
id: 'device_monitor',
|
||||
title: '设备监控',
|
||||
icon: 'settings',
|
||||
color: '#52c41a',
|
||||
path: '/pages/statistics/statistics'
|
||||
},
|
||||
{
|
||||
id: 'epidemic_control',
|
||||
title: '疫情防控',
|
||||
icon: 'epidemic',
|
||||
color: '#fa8c16',
|
||||
path: '/pages/statistics/statistics'
|
||||
},
|
||||
{
|
||||
id: 'data_analysis',
|
||||
title: '数据分析',
|
||||
icon: 'home',
|
||||
color: '#722ed1',
|
||||
path: '/pages/statistics/statistics'
|
||||
}
|
||||
],
|
||||
|
||||
// 最新动态
|
||||
recentActivities: [],
|
||||
|
||||
// 市场价格
|
||||
marketPrice: {
|
||||
beef: { price: 0, trend: 0 },
|
||||
mutton: { price: 0, trend: 0 },
|
||||
milk: { price: 0, trend: 0 }
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 获取状态栏高度
|
||||
const systemInfo = wx.getSystemInfoSync();
|
||||
this.setData({
|
||||
statusBarHeight: systemInfo.statusBarHeight
|
||||
});
|
||||
|
||||
// 检查登录状态
|
||||
this.checkLoginStatus();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 每次显示页面时刷新数据
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
// 检查登录状态
|
||||
checkLoginStatus() {
|
||||
const token = wx.getStorageSync('token');
|
||||
if (!token) {
|
||||
wx.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
async loadData() {
|
||||
if (!this.checkLoginStatus()) return;
|
||||
|
||||
this.setData({ loading: true });
|
||||
|
||||
try {
|
||||
// 并行加载多个数据
|
||||
const [statsResult, marketResult] = await Promise.allSettled([
|
||||
this.loadStatisticsData(),
|
||||
this.loadMarketPrice()
|
||||
]);
|
||||
|
||||
// 处理统计数据结果
|
||||
if (statsResult.status === 'fulfilled') {
|
||||
console.log('统计数据加载成功');
|
||||
} else {
|
||||
console.error('统计数据加载失败:', statsResult.reason);
|
||||
this.loadMockStatistics();
|
||||
}
|
||||
|
||||
// 处理市场价格结果
|
||||
if (marketResult.status === 'fulfilled') {
|
||||
console.log('市场价格加载成功');
|
||||
} else {
|
||||
console.error('市场价格加载失败:', marketResult.reason);
|
||||
this.loadMockMarketPrice();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('数据加载失败:', error);
|
||||
// 加载模拟数据作为备用
|
||||
this.loadMockData();
|
||||
} finally {
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
// 加载统计数据
|
||||
async loadStatisticsData() {
|
||||
try {
|
||||
const result = await apiService.getDataCenterStats();
|
||||
|
||||
if (result.code === 200 || result.code === 0) {
|
||||
const data = result.data || result;
|
||||
|
||||
this.setData({
|
||||
todayStats: {
|
||||
totalFarmers: data.totalFarmers || 0,
|
||||
activeFarmers: data.activeFarmers || 0,
|
||||
totalAnimals: data.totalAnimals || 0,
|
||||
alertCount: data.alertCount || 0
|
||||
},
|
||||
trendData: {
|
||||
farmerGrowth: data.farmerGrowth || 0,
|
||||
animalGrowth: data.animalGrowth || 0,
|
||||
alertTrend: data.alertTrend || 0
|
||||
}
|
||||
});
|
||||
|
||||
// 如果有最新动态数据
|
||||
if (data.recentActivities) {
|
||||
this.setData({
|
||||
recentActivities: data.recentActivities
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// 加载市场价格
|
||||
async loadMarketPrice() {
|
||||
try {
|
||||
const result = await apiService.getMarketPrice();
|
||||
|
||||
if (result.code === 200 || result.code === 0) {
|
||||
const data = result.data || result;
|
||||
|
||||
this.setData({
|
||||
marketPrice: {
|
||||
beef: data.beef || { price: 0, trend: 0 },
|
||||
mutton: data.mutton || { price: 0, trend: 0 },
|
||||
milk: data.milk || { price: 0, trend: 0 }
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取市场价格失败:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// 加载模拟统计数据
|
||||
loadMockStatistics() {
|
||||
this.setData({
|
||||
todayStats: {
|
||||
totalFarmers: 156,
|
||||
activeFarmers: 142,
|
||||
totalAnimals: 3248,
|
||||
alertCount: 8
|
||||
},
|
||||
trendData: {
|
||||
farmerGrowth: 12,
|
||||
animalGrowth: 156,
|
||||
alertTrend: -3
|
||||
},
|
||||
recentActivities: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'farmer',
|
||||
title: '新增养殖户',
|
||||
content: '张三申请加入养殖户管理',
|
||||
time: '2小时前'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: 'alert',
|
||||
title: '设备告警',
|
||||
content: '智能项圈001离线超过30分钟',
|
||||
time: '3小时前'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
type: 'epidemic',
|
||||
title: '疫情防控',
|
||||
content: '完成第三季度疫苗接种统计',
|
||||
time: '5小时前'
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
|
||||
// 加载模拟市场价格
|
||||
loadMockMarketPrice() {
|
||||
this.setData({
|
||||
marketPrice: {
|
||||
beef: { price: 68.5, trend: 2.3 },
|
||||
mutton: { price: 72.8, trend: -1.2 },
|
||||
milk: { price: 4.2, trend: 0.8 }
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 加载所有模拟数据
|
||||
loadMockData() {
|
||||
this.loadMockStatistics();
|
||||
this.loadMockMarketPrice();
|
||||
},
|
||||
|
||||
// 快捷操作点击
|
||||
onQuickActionTap(e) {
|
||||
const { action } = e.currentTarget.dataset;
|
||||
const actionItem = this.data.quickActions.find(item => item.id === action);
|
||||
|
||||
if (actionItem && actionItem.path) {
|
||||
if (actionItem.path.startsWith('/pages/')) {
|
||||
// 如果是tabBar页面,使用switchTab
|
||||
if (actionItem.path.includes('/farmer/farmer')) {
|
||||
wx.switchTab({
|
||||
url: actionItem.path
|
||||
});
|
||||
} else {
|
||||
wx.navigateTo({
|
||||
url: actionItem.path
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 查看更多动态
|
||||
onViewMoreActivities() {
|
||||
wx.showToast({
|
||||
title: '功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onPullDownRefresh() {
|
||||
this.loadData().finally(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
// 分享页面
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '政府监管端 - 数据统计',
|
||||
path: '/pages/statistics/statistics'
|
||||
};
|
||||
}
|
||||
});
|
||||
6
government-mini-program/pages/statistics/statistics.json
Normal file
6
government-mini-program/pages/statistics/statistics.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"navigationBarTitleText": "数据统计",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundColor": "#f5f5f5",
|
||||
"backgroundTextStyle": "dark"
|
||||
}
|
||||
121
government-mini-program/pages/statistics/statistics.wxml
Normal file
121
government-mini-program/pages/statistics/statistics.wxml
Normal file
@@ -0,0 +1,121 @@
|
||||
<!--pages/statistics/statistics.wxml-->
|
||||
<view class="container">
|
||||
<!-- 状态栏 -->
|
||||
<view class="status-bar">
|
||||
<view class="status-left">
|
||||
<text>{{currentTime || '17:05'}}</text>
|
||||
</view>
|
||||
<view class="status-right">
|
||||
<text>100%</text>
|
||||
<view class="battery-icon"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 顶部导航栏 -->
|
||||
<view class="header">
|
||||
<view class="header-title">数据统计</view>
|
||||
<view class="header-actions">
|
||||
<view class="action-btn" bindtap="onRefresh">
|
||||
<text class="icon-refresh">🔄</text>
|
||||
</view>
|
||||
<view class="action-btn" bindtap="onExport">
|
||||
<text class="icon-export">📊</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 统计卡片区域 -->
|
||||
<view class="stats-cards">
|
||||
<view
|
||||
class="stat-card"
|
||||
wx:for="{{statsData}}"
|
||||
wx:key="id"
|
||||
data-item="{{item}}"
|
||||
bindtap="onStatCardTap"
|
||||
>
|
||||
<view class="card-icon" style="background-color: {{item.color}}">
|
||||
<text class="icon">{{item.icon}}</text>
|
||||
</view>
|
||||
<view class="card-content">
|
||||
<view class="card-title">{{item.title}}</view>
|
||||
<view class="card-value">{{item.value}}</view>
|
||||
<view class="card-trend {{item.trend > 0 ? 'up' : item.trend < 0 ? 'down' : 'stable'}}">
|
||||
<text class="trend-icon">{{item.trend > 0 ? '↗' : item.trend < 0 ? '↘' : '→'}}</text>
|
||||
<text class="trend-text">{{item.trendText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 图表区域 -->
|
||||
<view class="chart-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">监管趋势</text>
|
||||
<view class="time-filter">
|
||||
<view
|
||||
class="filter-item {{selectedPeriod === item ? 'active' : ''}}"
|
||||
wx:for="{{timePeriods}}"
|
||||
wx:key="*this"
|
||||
data-period="{{item}}"
|
||||
bindtap="onPeriodChange"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 模拟图表 -->
|
||||
<view class="chart-container">
|
||||
<view class="chart-placeholder">
|
||||
<text class="chart-text">📈 监管数据趋势图</text>
|
||||
<text class="chart-desc">显示最近{{selectedPeriod}}的监管活动统计</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 详细列表 -->
|
||||
<view class="detail-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">最新监管记录</text>
|
||||
<view class="more-btn" bindtap="onViewMore">
|
||||
查看更多 >
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="record-list">
|
||||
<view
|
||||
class="record-item"
|
||||
wx:for="{{recentRecords}}"
|
||||
wx:key="id"
|
||||
data-item="{{item}}"
|
||||
bindtap="onRecordTap"
|
||||
>
|
||||
<view class="record-icon">
|
||||
<text class="status-dot {{item.status}}"></text>
|
||||
</view>
|
||||
<view class="record-content">
|
||||
<view class="record-title">{{item.title}}</view>
|
||||
<view class="record-desc">{{item.description}}</view>
|
||||
<view class="record-time">{{item.time}}</view>
|
||||
</view>
|
||||
<view class="record-arrow">></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷操作 -->
|
||||
<view class="quick-actions">
|
||||
<view
|
||||
class="action-item"
|
||||
wx:for="{{quickActions}}"
|
||||
wx:key="id"
|
||||
data-item="{{item}}"
|
||||
bindtap="onQuickAction"
|
||||
>
|
||||
<view class="action-icon" style="background-color: {{item.color}}">
|
||||
<text>{{item.icon}}</text>
|
||||
</view>
|
||||
<text class="action-name">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
313
government-mini-program/pages/statistics/statistics.wxss
Normal file
313
government-mini-program/pages/statistics/statistics.wxss
Normal file
@@ -0,0 +1,313 @@
|
||||
/* pages/statistics/statistics.wxss */
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 状态栏样式 */
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.battery-icon {
|
||||
width: 40rpx;
|
||||
height: 20rpx;
|
||||
border: 2rpx solid white;
|
||||
border-radius: 4rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.battery-icon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -6rpx;
|
||||
top: 6rpx;
|
||||
width: 4rpx;
|
||||
height: 8rpx;
|
||||
background-color: white;
|
||||
border-radius: 0 2rpx 2rpx 0;
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 30rpx;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 统计卡片 */
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background-color: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.card-trend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.card-trend.up {
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
.card-trend.down {
|
||||
color: #f44336;
|
||||
}
|
||||
|
||||
.card-trend.stable {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 图表区域 */
|
||||
.chart-section {
|
||||
margin: 20rpx;
|
||||
background-color: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.time-filter {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
background-color: #f5f5f5;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-item.active {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 400rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx dashed #ddd;
|
||||
}
|
||||
|
||||
.chart-text {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.chart-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 详细列表 */
|
||||
.detail-section {
|
||||
margin: 20rpx;
|
||||
background-color: white;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.more-btn {
|
||||
font-size: 28rpx;
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.record-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.record-icon {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.status-dot.success {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
.status-dot.warning {
|
||||
background-color: #ff9800;
|
||||
}
|
||||
|
||||
.status-dot.error {
|
||||
background-color: #f44336;
|
||||
}
|
||||
|
||||
.record-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.record-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.record-desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.record-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.record-arrow {
|
||||
color: #ccc;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 快捷操作 */
|
||||
.quick-actions {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 30rpx 20rpx;
|
||||
background-color: white;
|
||||
margin: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.action-name {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
Reference in New Issue
Block a user