'dashboard', 'label' => '仪表盘', 'icon' => '📊', 'url' => 'CRM'], ['k' => 'customers', 'label' => '客户管理', 'icon' => '🤝', 'url' => 'CRM/customers'], ['k' => 'leads', 'label' => '商机线索', 'icon' => '💡', 'url' => 'CRM/leads'], ['k' => 'followups', 'label' => '跟进记录', 'icon' => '📞', 'url' => 'CRM/followups'], ]; } public function index() { $leads = (new Lead())->all(); $customers = (new Customer())->all(); $cmap = []; foreach ($customers as $c) { $cmap[$c['id']] = $c['name']; } return $this->renderSubsys('crm', 'crm/leads', ['leads' => $leads, 'cmap' => $cmap], $this->nav(), 'leads'); } public function create() { subsys_admin('crm') or \Core\App::forbidden('需要 CRM 管理员权限'); $customers = (new Customer())->all(); return $this->renderSubsys('crm', 'crm/lead_form', ['lead' => null, 'customers' => $customers], $this->nav(), 'leads'); } public function store() { subsys_admin('crm') or \Core\App::forbidden('需要 CRM 管理员权限'); if (!csrf_check()) return $this->redirect('CRM/leads'); (new Lead())->insert($this->collect()); return $this->redirect('CRM/leads'); } public function edit($id) { subsys_admin('crm') or \Core\App::forbidden('需要 CRM 管理员权限'); $lead = (new Lead())->find($id); if (!$lead) return $this->redirect('CRM/leads'); $customers = (new Customer())->all(); return $this->renderSubsys('crm', 'crm/lead_form', ['lead' => $lead, 'customers' => $customers], $this->nav(), 'leads'); } public function update($id) { subsys_admin('crm') or \Core\App::forbidden('需要 CRM 管理员权限'); if (!csrf_check()) return $this->redirect('CRM/leads'); $lead = (new Lead())->find($id); if (!$lead) return $this->redirect('CRM/leads'); (new Lead())->update($id, $this->collect()); return $this->redirect('CRM/leads'); } public function destroy($id) { subsys_admin('crm') or \Core\App::forbidden('需要 CRM 管理员权限'); (new Lead())->delete($id); return $this->redirect('CRM/leads'); } private function collect(): array { return [ 'customer_id' => (int)$this->post('customer_id'), 'title' => trim($this->post('title')), 'amount' => (float)$this->post('amount'), 'stage' => $this->post('stage') ?: 'new', 'expected_close' => trim($this->post('expected_close')), 'source' => trim($this->post('source')), 'probability' => (int)$this->post('probability'), 'owner' => trim($this->post('owner')) ?: ($_SESSION['admin_name'] ?? ''), 'remark' => trim($this->post('remark')), 'created_at' => date('Y-m-d'), ]; } }