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

423 lines
14 KiB

<?php
namespace app\api\controller;
use core\base\BaseApiController;
use think\facade\Db;
/**
* 市场统计数据API控制器
*/
class MarketStats extends BaseApiController
{
/**
* 获取个人统计数据
*/
public function getPersonalStats()
{
$staffId = $this->request->post('staff_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
if (empty($staffId)) {
return fail('缺少员工ID');
}
try {
$stats = [
'resource_count' => $this->getResourceCount($staffId, $startDate, $endDate),
'converted_count' => $this->getConvertedCount($staffId, $startDate, $endDate),
'performance' => $this->getPerformance($staffId, $startDate, $endDate),
'commission' => $this->getCommission($staffId, $startDate, $endDate),
'bonus' => $this->getBonus($staffId, $startDate, $endDate)
];
return success($stats);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取团队统计数据
*/
public function getTeamStats()
{
$campusId = $this->request->post('campus_id');
$deptId = $this->request->post('dept_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
if (empty($campusId) || empty($deptId)) {
return fail('缺少校区或部门信息');
}
try {
$stats = [
'team_members' => $this->getTeamMembers($campusId, $deptId),
'team_performance' => $this->getTeamPerformance($campusId, $deptId, $startDate, $endDate),
'ranking' => $this->getTeamRanking($campusId, $deptId, $startDate, $endDate)
];
return success($stats);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取渠道分布统计
*/
public function getChannelDistribution()
{
$staffId = $this->request->post('staff_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
try {
$distribution = Db::table('school_customer_resources')
->field('source_channel, COUNT(*) as count')
->where('consultant', $staffId)
->where('deleted_at', 0)
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->group('source_channel')
->select();
return success($distribution);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取来源分布统计
*/
public function getSourceDistribution()
{
$staffId = $this->request->post('staff_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
try {
$distribution = Db::table('school_customer_resources')
->field('source, COUNT(*) as count')
->where('consultant', $staffId)
->where('deleted_at', 0)
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->whereNotNull('source')
->where('source', '<>', '')
->group('source')
->select();
return success($distribution);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取转化漏斗数据
*/
public function getConversionFunnel()
{
$staffId = $this->request->post('staff_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
try {
// 总资源数
$totalResources = Db::table('school_customer_resources')
->where('consultant', $staffId)
->where('deleted_at', 0)
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->count();
// 成交客户数
$convertedResources = Db::table('school_customer_resources r')
->join('school_order_table o', 'r.id = o.resource_id')
->where('r.consultant', $staffId)
->where('r.deleted_at', 0)
->where('o.order_type', '1')
->where('o.order_status', 'paid')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('r.created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('r.created_at', '<=', $endDate);
})
->count();
$funnel = [
'total_resources' => $totalResources,
'converted_resources' => $convertedResources,
'conversion_rate' => $totalResources > 0 ? round($convertedResources * 100 / $totalResources, 1) : 0
];
return success($funnel);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取月度趋势数据
*/
public function getMonthlyTrend()
{
$staffId = $this->request->post('staff_id');
$months = $this->request->post('months', 6);
try {
$results = Db::table('school_customer_resources')
->field("DATE_FORMAT(created_at, '%Y-%m') as month, COUNT(*) as count")
->where('consultant', $staffId)
->where('deleted_at', 0)
->group('month')
->order('month DESC')
->limit($months)
->select();
return success(array_reverse($results));
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取提成明细数据
*/
public function getCommissionBreakdown()
{
$staffId = $this->request->post('staff_id');
$startDate = $this->request->post('start_date');
$endDate = $this->request->post('end_date');
try {
$results = Db::table('school_performance_records')
->field('performance_type, SUM(performance_value) as total_amount, COUNT(*) as count')
->where('staff_id', $staffId)
->whereIn('performance_type', ['sales', 'marketing', 'consultant'])
->where('order_status', 'completed')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->group('performance_type')
->select();
return success($results);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
/**
* 获取奖励历史数据
*/
public function getBonusHistory()
{
$staffId = $this->request->post('staff_id');
$months = $this->request->post('months', 6);
try {
$results = Db::table('school_salary')
->field('salary_month, other_subsidies as amount')
->where('staff_id', $staffId)
->where('other_subsidies', '>', 0)
->order('salary_month DESC')
->limit($months)
->select();
return success($results);
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
// ========== 私有查询方法 ==========
/**
* 获取资源数量
*/
private function getResourceCount($staffId, $startDate = null, $endDate = null)
{
return Db::table('school_customer_resources')
->where('consultant', $staffId)
->where('deleted_at', 0)
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->count();
}
/**
* 获取成交客户数量
*/
private function getConvertedCount($staffId, $startDate = null, $endDate = null)
{
return Db::table('school_customer_resources r')
->join('school_order_table o', 'r.id = o.resource_id')
->where('r.consultant', $staffId)
->where('r.deleted_at', 0)
->where('o.order_type', '1')
->where('o.order_status', 'paid')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('r.created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('r.created_at', '<=', $endDate);
})
->count();
}
/**
* 获取业绩数据
*/
private function getPerformance($staffId, $startDate = null, $endDate = null)
{
$result = Db::table('school_order_table')
->where('staff_id', $staffId)
->where('order_type', '1')
->where('order_status', 'paid')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('payment_time', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('payment_time', '<=', $endDate);
})
->sum('order_amount');
return $result ?: 0;
}
/**
* 获取提成数据
*/
private function getCommission($staffId, $startDate = null, $endDate = null)
{
$result = Db::table('school_performance_records')
->where('staff_id', $staffId)
->whereIn('performance_type', ['sales', 'marketing', 'consultant'])
->where('order_status', 'completed')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('created_at', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('created_at', '<=', $endDate);
})
->sum('performance_value');
return $result ?: 0;
}
/**
* 获取奖励数据
*/
private function getBonus($staffId, $startDate = null, $endDate = null)
{
$result = Db::table('school_salary')
->where('staff_id', $staffId)
->where('other_subsidies', '>', 0)
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('salary_month', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('salary_month', '<=', $endDate);
})
->sum('other_subsidies');
return $result ?: 0;
}
/**
* 获取团队成员
*/
private function getTeamMembers($campusId, $deptId)
{
return Db::table('school_personnel p')
->join('school_campus_person_role cpr', 'p.id = cpr.person_id')
->where('cpr.campus_id', $campusId)
->where('cpr.dept_id', $deptId)
->where('p.status', 1)
->where('p.deleted_at', '0')
->field('p.id, p.name')
->select();
}
/**
* 获取团队业绩
*/
private function getTeamPerformance($campusId, $deptId, $startDate = null, $endDate = null)
{
$members = $this->getTeamMembers($campusId, $deptId);
$memberIds = array_column($members, 'id');
$result = Db::table('school_order_table')
->whereIn('staff_id', $memberIds)
->where('order_type', '1')
->where('order_status', 'paid')
->when($startDate, function($query) use ($startDate) {
return $query->whereTime('payment_time', '>=', $startDate);
})
->when($endDate, function($query) use ($endDate) {
return $query->whereTime('payment_time', '<=', $endDate);
})
->sum('order_amount');
return $result ?: 0;
}
/**
* 获取团队排名
*/
private function getTeamRanking($campusId, $deptId, $startDate = null, $endDate = null)
{
$members = $this->getTeamMembers($campusId, $deptId);
$memberIds = array_column($members, 'id');
$ranking = [];
foreach ($members as $member) {
$performance = $this->getPerformance($member['id'], $startDate, $endDate);
$ranking[] = [
'staff_id' => $member['id'],
'staff_name' => $member['name'],
'performance' => $performance
];
}
// 按业绩排序
usort($ranking, function($a, $b) {
return $b['performance'] <=> $a['performance'];
});
return $ranking;
}
}