123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- <?php
- // +----------------------------------------------------------------------
- // | Yzncms [ 御宅男工作室 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2018 http://yzncms.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
- // +----------------------------------------------------------------------
- // | fastadmin: https://www.fastadmin.net/
- // +----------------------------------------------------------------------
-
- // +----------------------------------------------------------------------
- // | 邮箱验证码接口
- // +----------------------------------------------------------------------
- namespace app\api\controller;
-
- use app\member\controller\MemberApi;
- use think\Db;
-
- /**
- * @title 邮箱验证码接口
- * @controller api\controller\Ems
- * @group base
- */
- class Ai extends MemberApi
- {
-
- protected $noNeedLogin = ['login', 'register','uploadCsv','uploadCsvFrom','exportCsv'];
- protected $noNeedRight = [];
-
- //初始化
- protected function initialize()
- {
- //yzncms本身已经做了跨域处理 妈的
- //$this->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] . '<br/>';
- }
- $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) . '<br/>';
- $s_num++;
- } else {
- //写日志
- $log_content_error .= '<p>短标题-' . $line[0] . '-已存在-指令短标题id:' . $one['id'] . '</p>';
- $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' => '<p>'.$log_content.'</p>',
- ]);
- }
-
- 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' => '<p>'.$log_content_error.'</p>',
- ]);
- }
-
- 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);
- }
- }
|