getHook(); parent::initialize(); } public static function getHook() { //需要使用静态方法Facade 不然会报错 \think\Facade\Hook::listen('response_send'); } /* * 业务控制器 * 上传csv关键词数据 * https://console.zx2049.com/api/ai/uploadCsv?file=20240504/eebcb4ca6a8a69fdd9e0f60c16b55746.csv */ public function uploadCsv(){ //测试 $url = request()->get('file',0); if($url !== 0){ $this->csvHandle('./uploads/'.$url); return json([]); } $file = request()->file('file'); //$file = $_FILES['file']; $info = $file->move( './uploads'); if($info){ // 成功上传后 获取上传信息 // 输出 jpg //$url = $info->getExtension(); // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg $url = $info->getSaveName(); // 输出 42a79759f284b767dfcb2a0197904287.jpg //echo $info->getFilename(); $data = ['code' => 0, 'msg' => '文件上传成功', 'data' =>['src'=>$url]]; }else{ // 上传失败获取错误信息 $info = $file->getError(); $data = ['code' => 1, 'msg' => '文件上传失败', 'data' =>$info]; } return json($data); } /* * 业务控制器 * 处理表单 */ public function uploadCsvFrom(){ $post = request()->post(); /* * rule: 0 title: 建筑职称 file: url: 20240505/2aff80b14c861480183278bbc9442f56.csv */ //判断关键词是否存在 $one = Db::name('options')->where('title','=',$post['title'])->where('status','=',1)->find(); if(empty($one)){ $data = ['code' => 1, 'msg' => '关键词不存在', 'data' => []]; return json($data); } if(!empty($post['url'])){ $this->csvHandle('./uploads/'.$post['url'],$post['rule'],$post['title']); $data = ['code' => 0, 'msg' => '提交成功', 'data' =>$post]; }else{ $data = ['code' => 1, 'msg' => '提交失败', 'data' => []]; } return json($data); } /* * 逻辑控制器 * 规则的指令集和创意 如果为空 调用全局的即可 同样优先调用自身规则 */ public function csvHandle($url,$rule,$title){ // 读取CSV文件 $filename = $url; if (file_exists($filename)) { $file = fopen($filename, 'r'); //任务批次 $task_no = date('YmdHis',time()).'-'.rand(1,10000); $pid = time(); //不考虑并发提交多次间隔也是秒级 $num = 1; $log_content = ''; $log_content_error = ''; $s_num = 0; $f_num = 0; while (($line = fgetcsv($file)) !== FALSE) { // $line是一个数组,包含CSV的一行数据 //print_r($line); if($num === 1){ $row = $line; }else{ if(!empty($line[0])) { //关键词步骤省略 需要去站长之家搜索并导出 这个步骤由人工操作 //判断是否存在短标题 重复性检测 //相同规则 短标题只能存在一个 $one = Db::name('cms_zl') ->where('title', '=', $line[0]) ->where('catid', '=', 18) ->where('gzxh', '=', $rule) ->find(); if (empty($one)) { //过滤标题是否合法的函数 这个可以用定时任务处理 [$is_use, $desc, $rule_id] = $this->titleHandle($line[0], $rule, $title); //构建详情 $html = ''; for ($i = 1; $i < 10; $i++) { $html .= $row[$i] . ':' . $line[$i] . '
'; } $data = [ 'catid' => 18, //短标题 'title' => $line[0], //短标题 'content' => $html, 'create_time' => time(), 'update_time' => time(), 'status' => 0, //默认禁用状态 定时手动开启 自动化再读取即可 'pid' => $pid, //关联日志的aid,可查询到规则序号 主词 文件地址 执行情况 'ptlx' => 0, 'is_use' => $is_use, //是否合法 'desc' => $desc, //非法原因 或者 合法匹配结果 'gzxh' => $rule, 'is_use_id' => (int)$rule_id, //写入具体规则id 可查询到对应规则是什么 判断是否合法 ]; //dump($data); //插入记录 $doc_id = Db::name('cms_zl')->insertGetId($data); //写入日志 $log_content .= '指令id-' . $doc_id . '-' . json_encode($line, JSON_UNESCAPED_UNICODE) . '
'; $s_num++; } else { //写日志 $log_content_error .= '

短标题-' . $line[0] . '-已存在-指令短标题id:' . $one['id'] . '

'; $f_num++; } } } $num++; } //每次操作 1-2条 日志记录 if(!empty($log_content)){ Db::name('log')->insert([ 'catid' => 27, 'title' => '批次'.$task_no.'成功导入处理-'.$s_num.'条数据', 'keywords' => $title, //主词 'description' => $filename,//对应文件地址 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'site_id'=> 1, 'cid' => (int)$rule, //规则序号 'aid' => $pid, //对应记录id 'content' => '

'.$log_content.'

', ]); } if(!empty($log_content_error)){ Db::name('log')->insert([ 'catid' => 27, 'title' => '批次'.$task_no.'导入处理已存在-'.$f_num.'条数据', 'keywords' => $title, //主词 'description' => $filename,//对应文件地址 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'site_id'=> 1, 'cid' => (int)$rule, //规则序号 'aid' => $pid, //对应记录id 'content' => '

'.$log_content_error.'

', ]); } fclose($file); } /*// 写入CSV文件 $data = [ ['Name', 'Age', 'Email'], ['Alice', 25, 'alice@example.com'], ['Bob', 30, 'bob@example.com'] ]; $filename = 'output.csv'; $file = fopen($filename, 'w'); foreach ($data as $row) { fputcsv($file, $row); } fclose($file);*/ } /* * 模型控制器 操作数据 */ /* * 处理函数 * $title 主词 */ public function titleHandle($line,$rule,$title){ //规则1 $desc = ''; //是否完全匹配主词 if (strpos($line, $title) !== false) { //包含主词 }else{ return [0,'短标题不包含主词['.$title.']',0]; } //1.查询是否存在主词规则 $one = Db::name('cms_zl') ->where('catid','=',17) ->where('title','=',$title) //只能一条 已做标题重复校验 ->where('is_qj','=',0) //非全局 ->where('zllx','=',1) //指令类型是 主词 ->where('gzxh','=',$rule) ->where('status','=',1) //多条需要控制开关 ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条 ->find(); //2.查询全局主词规则 if(empty($one)){ $one = Db::name('cms_zl') ->where('catid','=',17) ->where('title','=','全局-主词类型') //只能一条 已做标题重复校验 ->where('is_qj','=',1) //是全局 ->where('zllx','=',1) //指令类型是 主词 ->where('gzxh','=',$rule) ->where('status','=',1) //多条需要控制开关 ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条 ->find(); } //3.查询全局规则 if(empty($one)){ $one = Db::name('cms_zl') ->where('catid','=',17) ->where('title','=','全局-非主非副') //只能一条 已做标题重复校验 ->where('is_qj','=',1) //是全局 ->where('zllx','=',0) //指令类型是 非主非副 ->where('gzxh','=',$rule) ->where('status','=',1) //多条需要控制开关 ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条 ->find(); } if(empty($one)){ return [0,'不存在全局通用规则,全局主词规则,当前主词规则',0]; } //4.获取到全局或主词的副词 $two = []; if(empty($one['fclb']) || (string)$one['fclb'] === '0'){ //不存在副词规则 $desc .= '不存在副词规则-|-'; }else{ //存在副词规则 $one['fclb'] = $one['fclb'].','; $fclb = explode(',',$one['fclb']); $line_sor = str_replace($title, "", $line); //短标题去除主词 $is_bh = 0; $fc = ''; $fc_num = 0; foreach ($fclb as $k => $v) { //该判断 主词和副词 不一定是连在一起的 if(!empty($v)) { if (strpos($line_sor, $v) !== false) { //包含 $is_bh = 1; $fc = $v; //break; //跳出 目前只匹配一个 存在多个不做处理 以第一个为主 $fc_num++; } } } //存在多个副词 不合理 if($fc_num > 1){ return [0,'存在多个副词,不合法',$one['id']]; } //5.查询是否存在副词 if($is_bh === 1){ //6.查询主词+副词是否存在规则 $two = Db::name('cms_zl') ->where('catid','=',17) ->where('title','=',$title.$fc) //查询设置 按照主词+副词 格式查询 //只能一条 已做标题重复校验 ->where('is_qj','=',0) //非全局 ->where('zllx','=',2) //指令类型是 副词 ->where('gzxh','=',$rule) ->where('status','=',1) //多条需要控制开关 ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条 ->find(); //7.查询副词通用全局规则 if(empty($two)){ $two = Db::name('cms_zl') ->where('catid','=',17) ->where('title','=','全局-副词类型') //查询设置 按照主词+副词 格式查询 //只能一条 已做标题重复校验 ->where('is_qj','=',1) //非全局 ->where('zllx','=',2) //指令类型是 副词 ->where('gzxh','=',$rule) ->where('status','=',1) //多条需要控制开关 ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条 ->find(); } }else{ //短标题不包含副词 $desc .= '短标题不包含副词-|-'; } } //短标题的主词和副词 不一定是连在一起的 if(!empty($two)){ //存在副词规则 按照此规则执行 $data = $two; }else{ //按照$one规则记录执行 $data = $one; } //8.判断是否合法 地区词 [$is_bh,$fc] = $this->isInRule($data['dqc'],$line); if($is_bh > 0){ $desc .= '存在地区词'.$fc.',不合法-|-'; return [0,$desc,$data['id']]; } //9.判断是否合法 分类词 [$is_bh,$fc] = $this->isInRule($data['flc'],$line); if($is_bh > 0){ $desc .= '存在分类词'.$fc.',不合法-|-'; return [0,$desc,$data['id']]; } //10.判断是否合法 时间词 [$is_bh,$fc] = $this->isInRule($data['sjc'],$line); if($is_bh > 0){ $desc .= '存在时间词'.$fc.',不合法-|-'; return [0,$desc,$data['id']]; } //11.判断是否合法 屏蔽词 [$is_bh,$fc] = $this->isInRule($data['pbc'],$line); if($is_bh > 0){ $desc .= '存在屏蔽词'.$fc.',不合法-|-'; return [0,$desc,$data['id']]; } //12.判断是否合法 同时存在触发词和并发词 [$is_bh1,$fc1] = $this->isInRule($data['cfc'],$line); [$is_bh2,$fc2] = $this->isInRule($data['bfc'],$line); if($is_bh1 > 0 && $is_bh2 > 0){ //同时存在 $desc .= '同时存在并发词['.$fc2.']和触发词['.$fc1.']合法'; return [1,$desc,$data['id']]; }else{ $desc .= '不同时存在并发词['.$fc2.']和触发词['.$fc1.'],不合法'; return [0,$desc,$data['id']]; } } /* * 规则设定 */ public function setRule(){ //方案1: 定义config配置文件 //方案2: 直接代码写死 //方案3: 后台设置 -- 采用这个 $json = [ '' ]; } /* * 函数 是否包含 */ public function isInRule($data,$str){ $data = $data.','; $data = explode(',',$data); $is_bh = 0; $fc = ''; foreach ($data as $k => $v) { //该判断 主词和副词 不一定是连在一起的 if(!empty($v)) { if (strpos($str, $v) !== false) { //包含 $is_bh = 1; $fc = $v; break; //跳出 目前只匹配一个 存在多个不做处理 以第一个为主 } } } return [$is_bh,$fc]; } /* * 导出csv * http://console.zx2049.com/api/ai/exportCsv */ public function exportCsv(){ $list = Db::name('cms_zl')->field('id,title,desc')->where('catid','=',18)->select(); /* $data = [ ['Name', 'Age', 'Email'], ['Alice', 25, 'alice@example.com'], ['Bob', 30, 'bob@example.com'] ];*/ $filename = 'output.csv'; $file = fopen($filename, 'w'); foreach ($list as $row) { fputcsv($file, $row); } fclose($file); } }