From 180b56717d1f5b22646391791e4e0591db8c8984 Mon Sep 17 00:00:00 2001 From: xiaoyu Date: Mon, 14 Aug 2023 13:49:16 +0800 Subject: [PATCH] cfrom --- api/controllers/dms/CurlAutoLogin.php | 483 ++++++++++++++++++ api/controllers/dms/Test.php | 189 +++++++ common/models/dms/Dms_clues_model.php | 20 + .../receiver/Receiver_customers_model.php | 14 +- 4 files changed, 702 insertions(+), 4 deletions(-) create mode 100644 api/controllers/dms/CurlAutoLogin.php create mode 100644 api/controllers/dms/Test.php create mode 100755 common/models/dms/Dms_clues_model.php diff --git a/api/controllers/dms/CurlAutoLogin.php b/api/controllers/dms/CurlAutoLogin.php new file mode 100644 index 00000000..a30481fb --- /dev/null +++ b/api/controllers/dms/CurlAutoLogin.php @@ -0,0 +1,483 @@ +logPath = $logPath; + } else { + $this->logPath = dirname(__FILE__) . '/../logs/run.log'; + if(!file_exists($this->logPath)) { + if(!is_dir(dirname($this->logPath))) { + mkdir(dirname($this->logPath), 0755, true); + } + } + } + } + + /** + * 设置全局请求opt(方便使用代理之类的请求) + * @param $opts + */ + public function setGlobalOpts($opts = []) + { + $this->globalOpts += $opts; + return $this; + } + + /** + * 根据curl信息执行并解析结果,核心方法常用方法之一 + * @param string $curlContent 利用Firefox浏览器复制cURL命令 + * @param boolean $callbackBefore 对curl结果前置处理,如更换用户名、密码等 + * @param boolean $callbackAfter 对采集结果后置处理,如解析结果的csrf token等 + * @param boolean $storeParams 是否存储最后请求参数供重放使用,默认存储 + * @return mixed + */ + public function execCurl($curlContent, $callbackBefore = false, $callbackAfter = false, $storeParams = true) { + //存储参数供请求重放使用 + if($storeParams) { + $this->lastExecParams = func_get_args(); + } + $parseCurlResult = $this->parseCurl($curlContent); + if(is_callable($callbackBefore)) { + $parseCurlResult = $callbackBefore($parseCurlResult); + } + $parseCurlResult['opt'] += $this->globalOpts; + $execCurlResult = $this->_execCurl($parseCurlResult); + + if(is_callable($callbackAfter)) { + $execCurlResult = $callbackAfter($parseCurlResult, $execCurlResult); + } + + return $execCurlResult; + } + + /** + * 携带cookie执行curl命令,核心方法常用方法之一,直接利用curl命令里的header头cookie参数 + * @param string $curlContent 利用Firefox浏览器复制cURL命令 + * @param boolean $callbackBefore 对curl结果前置处理,如更换用户名、密码等 + * @param boolean $callbackAfter 对采集结果后置处理,如解析结果的csrf token等 + * @return mixed + */ + public function execCurlWithCookie($curlContent, $callbackBefore = false, $callbackAfter = false) { + return $this->execCurl($curlContent, function($parseCurlResult) use ($callbackBefore) { + $parseCurlResult['header'][] = $parseCurlResult['cookie']; + if(is_callable($callbackBefore)) { + $parseCurlResult = $callbackBefore($parseCurlResult); + } + return $parseCurlResult; + }, $callbackAfter); + } + + /** + * 重放请求,依赖登录的场景出现登录失败的情况,重新登录后,调用此方法重试上一次的请求 + * @return mixed + */ + public function repeatRequest() + { + //最后一次请求参数不为空才重放 + if(!empty($this->lastExecParams)) { + list($curlContent, $callbackBefore, $callbackAfter) = array_pad($this->lastExecParams, 3, false); + return $this->execCurl($curlContent, $callbackBefore, $callbackAfter, true); + } + return null; + } + + /** + * 获取最后一次请求参数 + * @return array + */ + public function getLastExecParams() + { + return $this->lastExecParams; + } + + /** + * 主动销毁最后一次请求参数 + * @return $this + */ + public function unsetLastExecParams() + { + $this->lastExecParams = []; + return $this; + } + + /** + * 解析curl信息 + * @param string $curlContent 利用Firefox浏览器复制cURL命令 + * @return bool|array + */ + public function parseCurl($curlContent) { + if(!preg_match("#curl '([^']*)'#is", $curlContent, $matchUrl) + && !preg_match("#curl.*'([^']*)'\s*$#is", $curlContent, $matchUrl) + ) { + return false; + } + + //get cookie + if(!preg_match("#-H '(Cookie:[^']*)'#is", $curlContent, $cookieMatch)) { + $cookieData = ''; + } else { + $cookieData = $cookieMatch[1]; + } + + //remove cookie data in header + $curlContent = preg_replace("#-H 'Cookie:[^']*'#is", '', $curlContent); + + //get header + if(!preg_match_all("#-H '([^']*)'#is", $curlContent, $headerMatches)) { + $httpHeader = array(); + } else { + $httpHeader = $headerMatches[1]; + } + + //get data + //单引号 + if(!preg_match("#(?:--data\S*|-d) \\$?'([^']*)'#is", $curlContent, $postDataMatch)) { + //双引号 + if(!preg_match('#(?:--data\S*|-d) \\$?"([^"]*)"#is', $curlContent, $postDataMatch)) { + $postDataMatch[1] = ''; + } + } + $postData = $postDataMatch[1]; + + return array( + 'url' => $matchUrl[1], + 'header' => $httpHeader, + 'post' => $postData, + 'opt' => array(), //扩展opt,在callbackBefore里添加 + 'cookie' => $cookieData, + ); + } + + /** + * 执行curl请求 + * @param array $parseCurlResult curl信息的解析结果,包含 url/header/post 三个键值参数 + * @return string + */ + protected function _execCurl($parseCurlResult) { + if(empty($parseCurlResult['url'])) { + return ''; + } + + $ch = curl_init($parseCurlResult['url']); + curl_setopt($ch,CURLOPT_HEADER,0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出 + curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩 + + //add header + if(!empty($parseCurlResult['header'])) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $parseCurlResult['header']); + } + + //add ssl support + if(substr($parseCurlResult['url'], 0, 5) == 'https') { + // curl_setopt($ch, CURLOPT_SSLVERSION,1); //error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112) + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //SSL 报错时使用 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //SSL 报错时使用 + } + + //add 302 support + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + + //add cookie support + //设置一个不存在的目录以在系统临时目录随机生成一个缓存文件,避免多进程cookie覆盖 + $cookieFile = @tempnam('/not_exist_dir/', 'autologin'); + curl_setopt($ch,CURLOPT_COOKIEJAR,$cookieFile); //存储提交后得到的cookie数据 + + //add previous curl cookie + if(!empty($this->lastCookieFile)) { + curl_setopt($ch,CURLOPT_COOKIEFILE, $this->lastCookieFile); //使用提交后得到的cookie数据 + } + + //add post data support + if(!empty($parseCurlResult['post'])) { + curl_setopt($ch,CURLOPT_POST, 1); + curl_setopt($ch,CURLOPT_POSTFIELDS, $parseCurlResult['post']); + } + + //extend opt + if(!empty($parseCurlResult['opt'])) { + foreach ($parseCurlResult['opt'] as $key => $value) { + curl_setopt($ch, $key, $value); + } + } + + $content = ''; + try { + $content = curl_exec($ch); //执行并存储结果 + } catch (\Exception $e) { + $this->_log($e->getMessage()); + } + + $curlError = curl_error($ch); + if(!empty($curlError)) { + $this->_log($curlError); + } + + curl_close($ch); + + //update last cookie file + $this->setLastCookieFile($cookieFile); + + return $content; + } + + /** + * 设置日志路径 + * @param string $logPath 绝对路径,必须可写 + */ + public function setLogPath($logPath) { + $this->logPath = $logPath; + return $this; + } + + /** + * 记录日志 + * @param [type] $msg [description] + * @return [type] [description] + */ + protected function _log($msg) { + try { + $res = file_put_contents($this->logPath, $msg . "\n", FILE_APPEND); + } catch (\Exception $e) { + error_log("CurlAutoLogin 无法写入日志文件 {$this->logPath}: {$msg}"); + } + } + + /** + * 获取上一次存储cookie的文件 + * @return [type] [description] + */ + public function getLastCookieFile() { + return $this->lastCookieFile; + } + + /** + * 获取最后一次存储的cookie内容 + * @return string + */ + public function getLastCookieContent() { + if($file = $this->getLastCookieFile()) { + if(file_exists($file)) { + return file_get_contents($file); + } + } + return ''; + } + + /** + * 手动追加cookie内容到最后一次存储的cookie文件 + * @param $content + * @return bool|int + */ + public function appendCookieContent($content) + { + if(file_exists($file = $this->getLastCookieFile())) { + return file_put_contents($file, $content . "\n", FILE_APPEND); + } + return false; + } + + /** + * 设置上一次存储cookie的文件 + * @param [type] $cookieFile [description] + */ + public function setLastCookieFile($cookieFile) { + if(!$this->lockedLastCookieFile) { + $this->lastCookieFile = $cookieFile; + } + return $this; + } + + /** + * 清空上次存储的cookie + */ + public function removeLastCookie() { + if($file = $this->getLastCookieFile()) { + //文件存在才清空 + if(file_exists($file)) { + file_put_contents($file, ''); + } + } + return $this; + } + + /** + * 登录成功后,锁定上一次存储cookie的文件,避免覆盖 + * @return [type] [description] + */ + public function lockLastCookieFile() { + $this->lockedLastCookieFile = true; + return $this; + } + + /** + * 解锁上一次存储cookie的文件 + * @return [type] [description] + */ + public function unlockLastCookieFile() { + $this->lockedLastCookieFile = false; + return $this; + } + + /** + * 登录成功后,锁定cookie,可以基于get方式获取url信息 + * @param [type] $url [description] + * @param boolean $header [description] + * @param array $opts [description] + * @return [type] [description] + */ + public function getUrl($url, $header = false, $opts = []) { + $ch = curl_init($url); + curl_setopt($ch,CURLOPT_HEADER,0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出 + curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩 + + //add header + if(!empty($header)) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + } + + //add ssl support + if(substr($url, 0, 5) == 'https') { + // curl_setopt($ch, CURLOPT_SSLVERSION,1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //SSL 报错时使用 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //SSL 报错时使用 + } + + //add 302 support + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + + curl_setopt($ch,CURLOPT_COOKIEFILE, $this->lastCookieFile); //使用提交后得到的cookie数据 + + //extend opt + $opts += $this->globalOpts; + if(!empty($opts)) { + foreach ($opts as $key => $value) { + curl_setopt($ch, $key, $value); + } + } + + $content = ''; + try { + $content = curl_exec($ch); //执行并存储结果 + } catch (\Exception $e) { + $this->_log($e->getMessage()); + } + + $curlError = curl_error($ch); + if(!empty($curlError)) { + $this->_log($curlError); + } + + curl_close($ch); + + return $content; + } + + /** + * 登录成功后,锁定cookie,可以基于post方式获取url信息 + * @param [type] $url [description] + * @param boolean $postData [description] + * @param boolean $header [description] + * @param array $opts [description] + * @return [type] [description] + */ + public function postUrl($url, $postData = false, $header = false, $opts = []) { + $ch = curl_init($url); + curl_setopt($ch,CURLOPT_HEADER,0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出 + curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩 + + //add header + if(!empty($header)) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + } + + //add ssl support + if(substr($url, 0, 5) == 'https') { + // curl_setopt($ch, CURLOPT_SSLVERSION,1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //SSL 报错时使用 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //SSL 报错时使用 + } + + //add 302 support + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + + curl_setopt($ch,CURLOPT_COOKIEFILE, $this->lastCookieFile); //使用提交后得到的cookie数据 + + //add post data support + curl_setopt($ch,CURLOPT_POST, 1); + if(!empty($postData)) { + curl_setopt($ch,CURLOPT_POSTFIELDS, $postData); + } + + //extend opt + $opts += $this->globalOpts; + if(!empty($opts)) { + foreach ($opts as $key => $value) { + curl_setopt($ch, $key, $value); + } + } + + $content = ''; + try { + $content = curl_exec($ch); //执行并存储结果 + } catch (\Exception $e) { + $this->_log($e->getMessage()); + } + + $curlError = curl_error($ch); + if(!empty($curlError)) { + $this->_log($curlError); + } + + curl_close($ch); + + return $content; + } + + /** + * 断言内容中包含某个字符(判断登录信息,如“退出”字眼) + * @param string $content 内容 + * @param string $subStr 包含字符串 + */ + public function assertContainStr($content, $subStr) { + if(false !== stripos($content, $subStr)) { + return true; + } + + return false; + } + + /** + * 获取换行符 + */ + public function getLineBreak() { + if('cli' == PHP_SAPI) { + $lineBreak = "\n"; + } else { + $lineBreak = "
"; + } + + return $lineBreak; + } +} diff --git a/api/controllers/dms/Test.php b/api/controllers/dms/Test.php new file mode 100644 index 00000000..4b7ed34f --- /dev/null +++ b/api/controllers/dms/Test.php @@ -0,0 +1,189 @@ +load->model('dms/dms_clues_model','dms_clues_model'); + } + + public function index() + { + //登录态缓存文件 + $loginResultFile = APPPATH . "cache/loginRes.txt"; + $autoLogin = new CurlAutoLogin(); + + //已有登录态,则直接读取登录态,避免多次重复登录 + if(!file_exists($loginResultFile)) { + $resArr = $this->doLogin($autoLogin, $loginResultFile); + } else { + echo "有登录态,自动登录...\n"; + $resArr = json_decode(file_get_contents($loginResultFile), true); + } + + if(empty($resArr['username'])) { + exit("未登录成功\n"); + } + + $token = $resArr['token']; + $pageIndex = 1; + $pageSize = 30; + $dollor = '$'; + + $createdDateStart = date("Y-m-d 00:00:00",strtotime("-1 day")); + $createdDateEnd = date("Y-m-d 00:00:00"); + + $redis = &load_cache('redis'); + $redisKey = 'dms_cid'; + + while(true) { + echo "处理第".$pageIndex."页..\n"; + + $curl = <<execCurl($curl); + $resArr = json_decode($content, true); + + if(!$resArr['result']) { + $resArr = $this->doLogin($autoLogin, $loginResultFile); + $resArr = json_decode($content, true); + } + + print_r($resArr);exit; + + foreach ($resArr['data']['clueServerQueryFromDlr']['rows'] as $k => $v){ + if($pageIndex == 1 && $k == 0){ + $cid = $redis->get($redisKey); + if($cid == $v['serverOrder']){ + $pageIndex = 999; + break; + }else{ + $redis->save($redisKey, $v['serverOrder'], 86400); + } + } + + $add = array( + 'c_id' => $v['serverOrder'], + 'name' => $v['custName'], + 'mobile' => $v['contactTel'], + 'cfrom1' => $v['infoChanMName'], + 'cfrom2' => $v['infoChanDName'], + 'jsondata' => json_encode($v, JSON_UNESCAPED_UNICODE), + 'c_time' => strtotime($v['createdDate']) + ); + + $this->dms_clues_model->add($add); + } + + sleep(random_int(5,10)); + $pageIndex++; + + if($resArr['data']['clueServerQueryFromDlr']['pages'] < $pageIndex) { + break; + } + + } + } + + public function doLogin($autoLogin, $loginResultFile) + { + echo "无登录态,模拟登录...\n"; + $curl = <<execCurl($curl); + $resArr = json_decode($content, true); + file_put_contents($loginResultFile, $content); //存储登录结果 + + return $resArr; + } + + public function test() + { + $url = 'http://dms.dna-nev.com.cn/mp/login/validlogin.do'; + $header = array ( + 0 => 'Accept: application/json, text/plain, */*', + 1 => 'Accept-Language: zh-CN,zh;q=0.9', + 2 => 'Connection: keep-alive', + 3 => 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8', + 4 => 'Origin: http://dms.dna-nev.com.cn', + 5 => 'Referer: http://dms.dna-nev.com.cn/', + 6 => 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', + ); + $postData = 'reuestParas=vrdCxWqmC6nNDXrxEyNCX5sThLElae5I%2FznYqpsieYmu3oIOQecGrZpH%2Bhpntm%2Bnb10K23tP9k9i2sqCxHESj1Leu%2BkGr2FYklTI%2BwwdCn2KZNQ7zrgAZ%2FzR9jd5XQEQzwyUCcwxllqqZWKDNMoWSJCLAYbMf0p%2FuqiVE105v%2Fi7yStvG5q7pE6lk%2B9g7oDsAHBbSqn21c6TpJyXHprF766eukiB4b5urdLilNsNQikR6rU2pY5dfymx5S2ytZzlnIE4pE2GHVV9VW6jzLot1w%3D%3D'; +// $postData = array( +// 'reuestParas' => 'vrdCxWqmC6nNDXrxEyNCX5sThLElae5I/znYqpsieYnyP9dYSVqrnNbryed0peXaee4199dAmuV61oHp3hUaIveISmjsLLKviH0eoWO1+5WKZNQ7zrgAZ/zR9jd5XQEQVyCBtq6canDPslkbJJaqBBqDnXrTNfDkp/nCJWdfJaoYGaQma/2+6KOacVm3jq6DAHBbSqn21c6TpJyXHprF766eukiB4b5urdLilNsNQimy2E6KL8vBaa+L4mnRHsEAU3RYz8uFJO2ZRHl9aPfJCA==' +// ); + $cookie = 'Cookie: pwRKey=1'; //需要cookie的话去掉这行的注释 + $timeout = 10; + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出 + curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩 + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //302/301 + //SSL + if(substr($url, 0, 8) === 'https://') { + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + //error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)解决 + //值有0-6,请参考手册,值1不行试试其他值 + //curl_setopt($ch, CURLOPT_SSLVERSION, 1); + } + //post数据 + if(!empty($postData)) { + curl_setopt($ch, CURLOPT_POST, 1); //发送POST类型数据 + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); //POST数据,$post可以是数组(multipart/form-data),也可以是拼接参数串(application/x-www-form-urlencoded) + } + if(!empty($cookie)) { + $header[] = $cookie; + } + if(!empty($header)) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //使用header头信息 + } + //超时时间 + curl_setopt($ch, CURLOPT_TIMEOUT, (int)$timeout); + //执行 + $content = curl_exec($ch); + if($error = curl_error($ch)) { + //log error + error_log($error); + } + curl_close($ch); + + print_r($content); + + return $content; + } +} diff --git a/common/models/dms/Dms_clues_model.php b/common/models/dms/Dms_clues_model.php new file mode 100755 index 00000000..c9aaf8ca --- /dev/null +++ b/common/models/dms/Dms_clues_model.php @@ -0,0 +1,20 @@ +table_name, 'default'); + } + +} diff --git a/common/models/receiver/Receiver_customers_model.php b/common/models/receiver/Receiver_customers_model.php index df6ae100..035ab46b 100644 --- a/common/models/receiver/Receiver_customers_model.php +++ b/common/models/receiver/Receiver_customers_model.php @@ -83,9 +83,12 @@ class Receiver_customers_model extends HD_Model { $arr[1] = ['name' => '自然到店', 'list' => []]; $arr[2] = ['name' => '转介绍', 'list' => [' 26' => '老车主', ' 20' => '其他4S店', ' 21' => '其他二网', ' 22' => '汽车美容', ' 23' => '二手车', ' 24' => '修车厂', ' 25' => '驾校', ' 27' => '亲朋好友']]; - $arr[3] = ['name' => '网络推广', 'list' => [' 32' => '懂车帝', ' 33' => '易车', ' 34' => '汽车之家', ' 30' => '抖音本地通表单', ' 38' => '抖音本地通私信',' 39' => '抖音效果通', ' 36' => '厂商分配', ' 37' => '狸车分配']]; + $arr[3] = ['name' => '门店垂媒', 'list' => [' 32' => '懂车帝', ' 33' => '易车', ' 34' => '汽车之家']]; $arr[4] = ['name' => '外展外拓', 'list' => [' 40' => '精准地推', ' 41' => '车展', ' 42' => '静展', ' 43' => '走进企业']]; - $arr[5] = ['name' => '自媒体', 'list' => [' 50' => '小红书号', ' 51' => '咸鱼号', ' 52' => '抖音-抖音号', ' 53' => '狸车素材', ' 54' => '知乎号', ' 55' => '私域直播',' 56' => '抖音-短视频', ' 57' => '抖音-直播', ' 58' => '抖音-私信']]; + $arr[5] = ['name' => '自媒体', 'list' => [' 50' => '小红书号', ' 51' => '咸鱼号', ' 52' => '抖音号', ' 53' => '狸车素材', ' 54' => '知乎号', ' 55' => '视频号']]; + $arr[6] = ['name' => '网络推广', 'list' => [' 60' => '抖音本地通表单', ' 61' => '抖音本地通私信', ' 62' => '视频号', ' 63' => '本地投放(狸车分配)']]; + $arr[7] = ['name' => '厂商分配', 'list' => [' 70' => '传统渠道', ' 71' => '垂媒-懂车帝', ' 72' => '垂媒-汽车之家', ' 73' => '垂媒-易车', ' 74' => '抖音-效果通', ' 75' => '抖音-本地生活', ' 76' => '抖音-本地通', ' 77' => '直播活动']]; + if ($id) { return $arr[$id]; } else { @@ -96,9 +99,12 @@ class Receiver_customers_model extends HD_Model { $arr[1] = ['name' => '自然到店', 'list' => []]; $arr[2] = ['name' => '转介绍', 'list' => [26 => '老车主',20 => '其他4S店', 21 => '其他二网', 22 => '汽车美容', 23 => '二手车', 24 => '修车厂', 25 => '驾校', 27 => '亲朋好友']]; - $arr[3] = ['name' => '网络推广', 'list' => [32 => '懂车帝', 33 => '易车', 34 => '汽车之家', 30 => '抖音本地通表单',38 => '抖音本地通私信', 39 => '抖音效果通', 36 => '厂商分配', 37 => '狸车分配']]; + $arr[3] = ['name' => '门店垂媒', 'list' => [32 => '懂车帝', 33 => '易车', 34 => '汽车之家']]; $arr[4] = ['name' => '外展外拓', 'list' => [40 => '精准地推', 41 => '车展', 42 => '静展', 43 => '走进企业']]; - $arr[5] = ['name' => '自媒体', 'list' => [50 => '小红书号', 51 => '咸鱼号', 52 => '抖音-抖音号', 53 => '狸车素材', 54 => '知乎号', 55 => '私域直播',56 => '抖音-短视频',57 => '抖音-直播',58 => '抖音-私信']]; + $arr[5] = ['name' => '自媒体', 'list' => [50 => '小红书号', 51 => '咸鱼号', 52 => '抖音号', 53 => '狸车素材', 54 => '知乎号', 55 => '视频号']]; + $arr[6] = ['name' => '网络推广', 'list' => [60 => '抖音本地通表单', 61 => '抖音本地通私信', 62 => '视频号', 63 => '狸车分配']]; + $arr[7] = ['name' => '厂商分配', 'list' => [70 => '传统渠道', 71 => '垂媒-懂车帝', 72 => '垂媒-汽车之家', 73 => '垂媒-易车', 74 => '抖音-效果通', 75 => '抖音-本地生活', 76 => '抖音-本地通', 77 => '直播活动']]; + if ($id) { return $arr[$id]; } else {