智慧教务系统UniApp前端项目(使用中2025-0517)
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.
 
 
 
 
 

413 lines
8.6 KiB

<!--市场数据统计页面-->
<template>
<view class="main_box">
<!--自定义导航栏-->
<view class="navbar_section">
<view class="filter-item">
<view class="label">统计时间</view>
<picker mode="date" fields="month" :value="currentDate" @change="dateChange">
<view class="picker-value">{{currentDate}}</view>
</picker>
</view>
</view>
<!-- 市场人员资源量统计 -->
<view class="table-section">
<view class="table-title">市场人员资源量统计</view>
<view class="table-container">
<view class="table-header">
<view class="th th-person">人员</view>
<view class="th th-week">周数量</view>
<view class="th th-month">月数量</view>
<view class="th th-year">年数量</view>
</view>
<view class="table-body">
<view class="table-row" v-for="(item, index) in staffData" :key="index">
<view class="td td-person">{{item.name}}</view>
<view class="td td-week">{{item.weekCount}}</view>
<view class="td td-month">{{item.monthCount}}</view>
<view class="td td-year">{{item.yearCount}}</view>
</view>
</view>
</view>
</view>
<!-- 校区人员资源渠道量 -->
<view class="table-section">
<view class="table-title">{{currentMonth}}月 - 年度校区人员资源渠道量</view>
<view class="table-container">
<view class="table-header">
<view class="th th-channel" style="width: 100px;">渠道</view>
<view class="th" v-for="(school, index) in schoolList" :key="index">{{school.name}}</view>
<view class="th th-total">渠道合计</view>
</view>
<view class="table-body">
<view class="table-row" v-for="(channel, index) in channelSchoolData" :key="index">
<view class="td td-channel" style="width: 100px;">{{channel.name}}</view>
<view class="td" v-for="(school, sIndex) in schoolList" :key="sIndex">
{{channel.schools[school.id] || 0}}
</view>
<view class="td td-total">{{channel.total}}</view>
</view>
</view>
</view>
</view>
<!-- 市场人员资源渠道统计 -->
<view class="table-section">
<view class="table-title">{{currentMonth}}月 - 年度市场人员资源渠道统计</view>
<view class="table-container">
<view class="table-header">
<view class="th th-channel" style="width: 100px;">渠道</view>
<view class="th" v-for="(staff, index) in marketStaffList" :key="index">市场{{staff.name}}</view>
<view class="th th-total">资源合计</view>
</view>
<view class="table-body">
<view class="table-row" v-for="(channel, index) in channelStaffData" :key="index">
<view class="td td-channel" style="width: 100px;">{{channel.name}}</view>
<view class="td" v-for="(staff, sIndex) in marketStaffList" :key="sIndex">
{{channel.staffs[staff.id] || 0}}
</view>
<view class="td td-total">{{channel.total}}</view>
</view>
</view>
</view>
</view>
<!-- 底部导航-->
<AQTabber />
</view>
</template>
<script>
import apiRoute from '@/api/apiRoute.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
currentDate: this.formatDate(new Date()),
currentMonth: new Date().getMonth() + 1,
// 市场人员资源量统计
staffData: [{
name: 'A',
weekCount: 0,
monthCount: 0,
yearCount: 0
},
{
name: 'B',
weekCount: 0,
monthCount: 0,
yearCount: 0
},
{
name: 'C',
weekCount: 0,
monthCount: 0,
yearCount: 0
},
{
name: 'D',
weekCount: 0,
monthCount: 0,
yearCount: 0
},
{
name: 'E',
weekCount: 0,
monthCount: 0,
yearCount: 0
}
],
// 校区列表
schoolList: [{
id: 1,
name: '校区1'
},
{
id: 2,
name: '校区2'
},
{
id: 3,
name: '校区3'
},
{
id: 4,
name: '校区4'
},
{
id: 5,
name: '校区5'
}
],
// 渠道列表
channelList: [{
id: 1,
name: '地推'
},
{
id: 2,
name: '转介绍'
},
{
id: 3,
name: '美团/大众'
},
{
id: 4,
name: '抖音'
},
{
id: 5,
name: '小红书'
},
{
id: 6,
name: '其他'
}
],
// 市场人员列表
marketStaffList: [{
id: 'A',
name: 'A'
},
{
id: 'B',
name: 'B'
},
{
id: 'C',
name: 'C'
},
{
id: 'D',
name: 'D'
}
],
// 校区渠道数据
channelSchoolData: [],
// 人员渠道数据
channelStaffData: []
}
},
onLoad() {
this.initData();
},
methods: {
// 格式化日期为 YYYY-MM
formatDate(date) {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
return `${year}-${month}`;
},
// 日期选择器变更
dateChange(e) {
this.currentDate = e.detail.value;
const [year, month] = this.currentDate.split('-');
this.currentMonth = parseInt(month);
this.initData();
},
// 初始化数据
initData() {
// 模拟获取数据,实际项目中应该调用API
this.getStaffStatistics();
this.getChannelSchoolStatistics();
this.getChannelStaffStatistics();
},
// 获取人员资源量统计
getStaffStatistics() {
// 模拟数据,实际项目中应该调用API
// 示例:apiRoute.getStaffStatistics({date: this.currentDate}).then(res => {})
// 模拟随机数据
this.staffData = this.staffData.map(staff => {
const monthCount = Math.floor(Math.random() * 100);
return {
...staff,
weekCount: Math.floor(Math.random() * 30),
monthCount: monthCount,
yearCount: monthCount + Math.floor(Math.random() * 200)
}
});
},
// 获取校区渠道统计
getChannelSchoolStatistics() {
// 模拟数据,实际项目中应该调用API
this.channelSchoolData = this.channelList.map(channel => {
const schools = {};
let total = 0;
this.schoolList.forEach(school => {
const count = Math.floor(Math.random() * 50);
schools[school.id] = count;
total += count;
});
return {
id: channel.id,
name: channel.name,
schools,
total
}
});
},
// 获取人员渠道统计
getChannelStaffStatistics() {
// 模拟数据,实际项目中应该调用API
this.channelStaffData = this.channelList.map(channel => {
const staffs = {};
let total = 0;
this.marketStaffList.forEach(staff => {
const count = Math.floor(Math.random() * 40);
staffs[staff.id] = count;
total += count;
});
return {
id: channel.id,
name: channel.name,
staffs,
total
}
});
}
}
}
</script>
<style lang="scss" scoped>
.main_box {
min-height: 100vh;
background-color: #1a1a1a;
color: #ffffff;
padding-bottom: 30rpx;
}
.navbar_section {
background-color: #1a1a1a;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.title {
font-size: 36rpx;
font-weight: bold;
}
}
.filter-section {
padding: 20rpx;
background-color: #222222;
margin: 20rpx;
border-radius: 10rpx;
.filter-item {
display: flex;
align-items: center;
.label {
font-size: 28rpx;
margin-right: 10rpx;
}
.picker-value {
padding: 10rpx 20rpx;
background-color: #333333;
border-radius: 6rpx;
font-size: 28rpx;
}
}
}
.table-section {
margin: 30rpx 20rpx;
background-color: #222222;
border-radius: 10rpx;
overflow: hidden;
.table-title {
font-size: 32rpx;
font-weight: bold;
padding: 20rpx;
border-bottom: 1px solid #333333;
}
.table-container {
width: 100%;
overflow-x: auto;
}
.table-header {
display: flex;
background-color: #333333;
.th {
padding: 15rpx 10rpx;
font-size: 26rpx;
text-align: center;
flex: 1;
min-width: 100rpx;
font-weight: bold;
}
}
.table-body {
.table-row {
display: flex;
border-bottom: 1px solid #333333;
&:last-child {
border-bottom: none;
}
.td {
padding: 15rpx 10rpx;
font-size: 26rpx;
text-align: center;
flex: 1;
min-width: 100rpx;
}
}
}
.th-person,
.td-person {
min-width: 80rpx;
flex: 0.8;
}
.th-week,
.td-week,
.th-month,
.td-month,
.th-year,
.td-year {
flex: 1;
}
.th-channel,
.td-channel {
flex: 1.2;
text-align: left;
padding-left: 20rpx;
}
.th-total,
.td-total {
flex: 1.2;
font-weight: bold;
}
}
</style>