request->get('type', 'my_data'); // 页面类型 $token = $this->request->get('token', ''); // 用户token $platform = $this->request->get('platform', 'web'); // 平台标识 // 验证token和获取用户信息 if (empty($token)) { return $this->renderErrorPage('缺少用户认证信息'); } try { // 验证token并获取用户信息 $userInfo = $this->getUserInfo($token); // 根据页面类型渲染不同内容 $htmlContent = $this->renderDashboardPage($type, $userInfo, $platform); // 输出HTML内容 return response($htmlContent)->header([ 'Content-Type' => 'text/html; charset=utf-8', 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0' ]); } catch (\Exception $e) { return $this->renderErrorPage('页面加载失败: ' . $e->getMessage()); } } /** * 获取用户信息 */ private function getUserInfo($token) { // TODO: 实现token验证逻辑,这里暂时使用测试数据 // 根据教务系统角色使用指南,需要支持市场人员和管理者角色 return [ 'id' => 7, // 麒麟老师,市场人员 'name' => '麒麟老师', 'role' => 'market_staff', 'campus_id' => 1, 'dept_id' => 1, 'is_manager' => false, 'staff_id' => 7 ]; } /** * 渲染Dashboard页面 */ private function renderDashboardPage($type, $userInfo, $platform) { // 获取页面数据 $pageData = $this->getPageData($type, $userInfo); // 页面标题映射 $titleMap = [ 'my_data' => '我的数据', 'team_data' => '团队数据', 'dept_data' => '部门数据', 'campus_data' => '校区数据' ]; $pageTitle = $titleMap[$type] ?? '数据统计'; // 使用视图模板渲染页面 return View::fetch('dashboard/main', [ 'pageTitle' => $pageTitle, 'pageData' => $pageData, 'platform' => $platform, 'userInfo' => $userInfo ]); } /** * 获取页面数据 */ private function getPageData($type, $userInfo) { switch ($type) { case 'my_data': return $this->getMyData($userInfo); case 'team_data': return $this->getTeamData($userInfo); case 'dept_data': return $this->getDeptData($userInfo); case 'campus_data': return $this->getCampusData($userInfo); default: return []; } } /** * 获取我的数据(市场人员) */ private function getMyData($userInfo) { $staffId = $userInfo['staff_id']; $currentMonth = date('Y-m-01'); return [ // 核心统计指标 'stats' => [ [ 'label' => '本月新增资源', 'value' => $this->getResourceCount($staffId, $currentMonth), 'unit' => '个', 'trend' => $this->getResourceTrend($staffId) ], [ 'label' => '本月成交客户', 'value' => $this->getConvertedCount($staffId, $currentMonth), 'unit' => '人', 'trend' => $this->getConversionTrend($staffId) ], [ 'label' => '本月业绩', 'value' => $this->getPerformance($staffId, $currentMonth), 'unit' => '元', 'trend' => $this->getPerformanceTrend($staffId) ], [ 'label' => '本月提成', 'value' => $this->getCommission($staffId, $currentMonth), 'unit' => '元', 'trend' => $this->getCommissionTrend($staffId) ] ], // 资源分析 'resource_analysis' => [ 'channel_distribution' => $this->getChannelDistribution($staffId), 'source_distribution' => $this->getSourceDistribution($staffId), 'conversion_funnel' => $this->getConversionFunnel($staffId), 'monthly_trend' => $this->getMonthlyTrend($staffId) ], // 收益分析 'income_analysis' => [ 'commission_breakdown' => $this->getCommissionBreakdown($staffId), 'bonus_history' => $this->getBonusHistory($staffId), 'income_trend' => $this->getIncomeTrend($staffId) ] ]; } /** * 获取团队数据(经理权限) */ private function getTeamData($userInfo) { $campusId = $userInfo['campus_id']; $deptId = $userInfo['dept_id']; $currentMonth = date('Y-m-01'); return [ // 团队总览 'team_overview' => [ 'total_members' => $this->getTeamMemberCount($campusId, $deptId), 'total_resources' => $this->getTeamResourceCount($campusId, $deptId, $currentMonth), 'total_converted' => $this->getTeamConvertedCount($campusId, $deptId, $currentMonth), 'total_performance' => $this->getTeamPerformance($campusId, $deptId, $currentMonth) ], // 团队成员排名 'member_ranking' => $this->getTeamMemberRanking($campusId, $deptId, $currentMonth), // 团队业绩分布 'performance_distribution' => $this->getTeamPerformanceDistribution($campusId, $deptId, $currentMonth) ]; } /** * 获取部门数据 */ private function getDeptData($userInfo) { $campusId = $userInfo['campus_id']; $currentMonth = date('Y-m-01'); return [ // 部门总览 'dept_overview' => [ 'total_depts' => $this->getDeptCount($campusId), 'total_resources' => $this->getDeptResourceCount($campusId, $currentMonth), 'total_performance' => $this->getDeptPerformance($campusId, $currentMonth), 'conversion_rate' => $this->getDeptConversionRate($campusId, $currentMonth) ], // 部门排名 'dept_ranking' => $this->getDeptRanking($campusId, $currentMonth) ]; } /** * 获取校区数据 */ private function getCampusData($userInfo) { $campusId = $userInfo['campus_id']; $currentMonth = date('Y-m-01'); return [ // 校区总览 'campus_overview' => [ 'total_performance' => $this->getCampusPerformance($campusId, $currentMonth), 'total_resources' => $this->getCampusResourceCount($campusId, $currentMonth), 'total_converted' => $this->getCampusConvertedCount($campusId, $currentMonth), 'total_staff' => $this->getCampusStaffCount($campusId) ], // 校区部门对比 'dept_comparison' => $this->getCampusDeptComparison($campusId, $currentMonth) ]; } // ========== 数据查询方法 ========== /** * 获取资源数量 */ private function getResourceCount($staffId, $startDate) { return Db::table('school_customer_resources') ->where('consultant', $staffId) ->where('deleted_at', 0) ->where('created_at', '>=', $startDate) ->count(); } /** * 获取成交客户数量 */ private function getConvertedCount($staffId, $startDate) { 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') ->where('r.created_at', '>=', $startDate) ->count(); } /** * 获取业绩数据 */ private function getPerformance($staffId, $startDate) { $result = Db::table('school_order_table') ->where('staff_id', $staffId) ->where('order_type', '1') ->where('order_status', 'paid') ->where('payment_time', '>=', $startDate) ->sum('order_amount'); return $result ?: 0; } /** * 获取提成数据 */ private function getCommission($staffId, $startDate) { $result = Db::table('school_performance_records') ->where('staff_id', $staffId) ->whereIn('performance_type', ['sales', 'marketing', 'consultant']) ->where('order_status', 'completed') ->where('created_at', '>=', $startDate) ->sum('performance_value'); return $result ?: 0; } /** * 获取渠道分布 */ private function getChannelDistribution($staffId) { $results = Db::table('school_customer_resources') ->field('source_channel, COUNT(*) as count') ->where('consultant', $staffId) ->where('deleted_at', 0) ->group('source_channel') ->select(); $channelMap = [ '1' => '线上推广', '2' => '电话营销', '3' => '地推活动', '4' => '转介绍', '5' => '其他' ]; $data = []; foreach ($results as $row) { $channelName = $channelMap[$row['source_channel']] ?? '其他'; $data[] = [ 'name' => $channelName, 'value' => $row['count'] ]; } return $data; } /** * 获取来源分布 */ private function getSourceDistribution($staffId) { $results = Db::table('school_customer_resources') ->field('source, COUNT(*) as count') ->where('consultant', $staffId) ->where('deleted_at', 0) ->whereNotNull('source') ->where('source', '<>', '') ->group('source') ->select(); $sourceMap = [ '1' => '官网', '2' => '微信', '3' => '抖音', '4' => '小红书', '5' => '其他' ]; $data = []; foreach ($results as $row) { $sourceName = $sourceMap[$row['source']] ?? $row['source']; $data[] = [ 'name' => $sourceName, 'value' => $row['count'] ]; } return $data; } /** * 获取转化漏斗 */ private function getConversionFunnel($staffId) { // 总资源数 $totalResources = Db::table('school_customer_resources') ->where('consultant', $staffId) ->where('deleted_at', 0) ->count(); // 有效联系数(简化处理) $contactedResources = $totalResources; // 意向客户数 $intentionResources = Db::table('school_customer_resources') ->where('consultant', $staffId) ->where('deleted_at', 0) ->where('initial_intent', 'high') ->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') ->count(); return [ ['stage' => '新增资源', 'count' => $totalResources, 'rate' => 100], ['stage' => '有效联系', 'count' => $contactedResources, 'rate' => round($contactedResources * 100 / $totalResources, 1)], ['stage' => '意向客户', 'count' => $intentionResources, 'rate' => round($intentionResources * 100 / $totalResources, 1)], ['stage' => '成交客户', 'count' => $convertedResources, 'rate' => round($convertedResources * 100 / $totalResources, 1)] ]; } /** * 获取月度趋势 */ private function getMonthlyTrend($staffId) { $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(6) ->select(); return array_reverse($results->toArray()); // 按时间正序 } /** * 获取提成明细 */ private function getCommissionBreakdown($staffId) { $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') ->group('performance_type') ->select(); $typeMap = [ 'sales' => '销售提成', 'marketing' => '营销提成', 'consultant' => '咨询提成' ]; $data = []; foreach ($results as $row) { $typeName = $typeMap[$row['performance_type']] ?? $row['performance_type']; $data[] = [ 'type' => $typeName, 'amount' => $row['total_amount'], 'count' => $row['count'] ]; } return $data; } /** * 获取奖励历史 */ private function getBonusHistory($staffId) { return Db::table('school_salary') ->field('salary_month, other_subsidies as amount') ->where('staff_id', $staffId) ->where('other_subsidies', '>', 0) ->order('salary_month DESC') ->limit(6) ->select(); } /** * 获取收入趋势 */ private function getIncomeTrend($staffId) { $results = Db::table('school_performance_records') ->field('DATE_FORMAT(created_at, "%Y-%m") as month, SUM(performance_value) as total_income') ->where('staff_id', $staffId) ->where('order_status', 'completed') ->group('month') ->order('month DESC') ->limit(6) ->select(); return array_reverse($results->toArray()); // 按时间正序 } // ========== 团队数据查询方法 ========== /** * 获取团队成员数量 */ private function getTeamMemberCount($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') ->count(); } /** * 获取团队资源数量 */ private function getTeamResourceCount($campusId, $deptId, $startDate) { $members = 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') ->column('id'); return Db::table('school_customer_resources') ->whereIn('consultant', $members) ->where('deleted_at', 0) ->where('created_at', '>=', $startDate) ->count(); } /** * 获取团队成交数量 */ private function getTeamConvertedCount($campusId, $deptId, $startDate) { $members = 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') ->column('id'); return Db::table('school_customer_resources r') ->join('school_order_table o', 'r.id = o.resource_id') ->whereIn('r.consultant', $members) ->where('r.deleted_at', 0) ->where('o.order_type', '1') ->where('o.order_status', 'paid') ->where('r.created_at', '>=', $startDate) ->count(); } /** * 获取团队业绩 */ private function getTeamPerformance($campusId, $deptId, $startDate) { $members = 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') ->column('id'); $result = Db::table('school_order_table') ->whereIn('staff_id', $members) ->where('order_type', '1') ->where('order_status', 'paid') ->where('payment_time', '>=', $startDate) ->sum('order_amount'); return $result ?: 0; } /** * 获取团队成员排名 */ private function getTeamMemberRanking($campusId, $deptId, $startDate) { // 获取团队成员列表 $members = 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') ->column('id, name'); $ranking = []; foreach ($members as $member) { $resourceCount = $this->getResourceCount($member['id'], $startDate); $convertedCount = $this->getConvertedCount($member['id'], $startDate); $performance = $this->getPerformance($member['id'], $startDate); $commission = $this->getCommission($member['id'], $startDate); $ranking[] = [ 'staff_id' => $member['id'], 'staff_name' => $member['name'], 'resource_count' => $resourceCount, 'converted_count' => $convertedCount, 'performance' => $performance, 'commission' => $commission ]; } // 按业绩排序 usort($ranking, function($a, $b) { return $b['performance'] <=> $a['performance']; }); return $ranking; } // ========== 部门数据查询方法 ========== /** * 获取部门数量 */ private function getDeptCount($campusId) { return Db::table('school_departments') ->where('deleted_at', 0) ->count(); } /** * 获取部门资源数量 */ private function getDeptResourceCount($campusId, $startDate) { return Db::table('school_customer_resources') ->where('campus', $campusId) ->where('deleted_at', 0) ->where('created_at', '>=', $startDate) ->count(); } /** * 获取部门业绩 */ private function getDeptPerformance($campusId, $startDate) { $result = Db::table('school_order_table') ->where('campus_id', $campusId) ->where('order_type', '1') ->where('order_status', 'paid') ->where('payment_time', '>=', $startDate) ->sum('order_amount'); return $result ?: 0; } /** * 获取部门转化率 */ private function getDeptConversionRate($campusId, $startDate) { $totalResources = Db::table('school_customer_resources') ->where('campus', $campusId) ->where('deleted_at', 0) ->where('created_at', '>=', $startDate) ->count(); if ($totalResources == 0) return 0; $convertedResources = Db::table('school_customer_resources r') ->join('school_order_table o', 'r.id = o.resource_id') ->where('r.campus', $campusId) ->where('r.deleted_at', 0) ->where('o.order_type', '1') ->where('o.order_status', 'paid') ->where('r.created_at', '>=', $startDate) ->count(); return round($convertedResources * 100 / $totalResources, 1); } /** * 获取部门排名 */ private function getDeptRanking($campusId, $startDate) { $depts = Db::table('school_departments') ->where('deleted_at', 0) ->select(); $ranking = []; foreach ($depts as $dept) { $performance = Db::table('school_order_table') ->where('campus_id', $campusId) ->where('order_type', '1') ->where('order_status', 'paid') ->where('payment_time', '>=', $startDate) ->sum('order_amount'); $ranking[] = [ 'dept_id' => $dept['id'], 'dept_name' => $dept['department_name'], 'performance' => $performance ?: 0 ]; } // 按业绩排序 usort($ranking, function($a, $b) { return $b['performance'] <=> $a['performance']; }); return $ranking; } // ========== 校区数据查询方法 ========== /** * 获取校区业绩 */ private function getCampusPerformance($campusId, $startDate) { $result = Db::table('school_order_table') ->where('campus_id', $campusId) ->where('order_type', '1') ->where('order_status', 'paid') ->where('payment_time', '>=', $startDate) ->sum('order_amount'); return $result ?: 0; } /** * 获取校区资源数量 */ private function getCampusResourceCount($campusId, $startDate) { return Db::table('school_customer_resources') ->where('campus', $campusId) ->where('deleted_at', 0) ->where('created_at', '>=', $startDate) ->count(); } /** * 获取校区成交数量 */ private function getCampusConvertedCount($campusId, $startDate) { return Db::table('school_customer_resources r') ->join('school_order_table o', 'r.id = o.resource_id') ->where('r.campus', $campusId) ->where('r.deleted_at', 0) ->where('o.order_type', '1') ->where('o.order_status', 'paid') ->where('r.created_at', '>=', $startDate) ->count(); } /** * 获取校区员工数量 */ private function getCampusStaffCount($campusId) { return Db::table('school_personnel p') ->join('school_campus_person_role cpr', 'p.id = cpr.person_id') ->where('cpr.campus_id', $campusId) ->where('p.status', 1) ->where('p.deleted_at', '0') ->count(); } /** * 获取校区部门对比 */ private function getCampusDeptComparison($campusId, $startDate) { $depts = Db::table('school_departments') ->where('deleted_at', 0) ->select(); $comparison = []; foreach ($depts as $dept) { $performance = Db::table('school_order_table') ->join('school_customer_resources r', 'r.id = o.resource_id') ->where('o.campus_id', $campusId) ->where('r.consultant', '!=', '') ->where('o.order_type', '1') ->where('o.order_status', 'paid') ->where('o.payment_time', '>=', $startDate) ->sum('o.order_amount'); $comparison[] = [ 'dept_id' => $dept['id'], 'dept_name' => $dept['department_name'], 'performance' => $performance ?: 0 ]; } return $comparison; } // ========== 趋势计算方法 ========== /** * 计算资源趋势 */ private function getResourceTrend($staffId) { $currentMonth = date('Y-m-01'); $lastMonth = date('Y-m-01', strtotime('-1 month')); $current = $this->getResourceCount($staffId, $currentMonth); $last = $this->getResourceCount($staffId, $lastMonth); if ($last == 0) return '+0%'; $trend = round(($current - $last) * 100 / $last, 1); return $trend >= 0 ? '+' . $trend . '%' : $trend . '%'; } /** * 计算转化趋势 */ private function getConversionTrend($staffId) { // 简化处理,返回示例数据 return '+8%'; } /** * 计算业绩趋势 */ private function getPerformanceTrend($staffId) { // 简化处理,返回示例数据 return '+12%'; } /** * 计算提成趋势 */ private function getCommissionTrend($staffId) { // 简化处理,返回示例数据 return '+15%'; } /** * 渲染错误页面 */ private function renderErrorPage($message) { $errorHtml = View::fetch('dashboard/error', [ 'message' => $message ]); return response($errorHtml)->header([ 'Content-Type' => 'text/html; charset=utf-8' ]); } }