123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687 |
- <?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','dsTitle','dsTitlelist','dsTitle13'];
- 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);
-
- //插入 重复也无所谓了
- Db::name('pc')->insert(['catid'=>31,'title'=>$task_no,'create_time' => time(),'update_time' => time()]);
-
- $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) //分类id
- ->where('zc', '=', $title) //主词
- ->where('gzxh', '=', $rule) //规则id
- ->where('sj','=',$task_no) //时间维度 批次
- ->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,
- 'zc' => $title, //增加主词字段
- 'create_time' => time(),
- 'update_time' => time(),
- 'status' => 0, //默认禁用状态 定时手动开启 自动化再读取即可
- 'pid' => $pid, //关联日志的aid,可查询到规则序号 主词 文件地址 执行情况
- 'ptlx' => 0,
- 'is_use' => $is_use, //是否合法
- 'desc' => $desc, //非法原因 或者 合法匹配结果
- 'gzxh' => $rule,
- 'sj' => $task_no, //写入时间维度 批次
- 'is_use_id' => json_encode($rule_id,JSON_UNESCAPED_UNICODE), //写入具体规则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++;
-
- //通知前端
- $is_use_desc = $is_use === 1?'合法':'不匹配';
- $msg = [
- 'info' => '['.$line[0].']成功新增记录!匹配结果:'.$is_use_desc
- ];
- $this->curlPost($msg);
- } else {
- //写日志
- $log_content_error .= '<p>短标题-' . $line[0] . '-已存在-指令短标题id:' . $one['id'] . '</p>';
- $f_num++;
-
- //通知前端
- $msg = [
- 'info' => '相同规则与相同主词下,['.$line[0].']已存在-不可重复导入!'
- ];
- $this->curlPost($msg);
- }
- }
- }
- $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($is_bh === 0){
- //$fc 无法确认值 所以无法匹配副词规则
- //当主词规则 都没有填写副词列表 就表示不匹配副词了
- }
-
- //存在多个副词 不合理
- 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];
- }
-
- //9.判断是否合法 分类词
- [$is_bh,$fc] = $this->isInRule($data['flc'],$line);
- if($is_bh > 0){
- $desc .= '存在分类词'.$fc.',不合法-|-';
- return [0,$desc,$data];
- }
-
- //10.判断是否合法 时间词
- [$is_bh,$fc] = $this->isInRule($data['sjc'],$line);
- if($is_bh > 0){
- $desc .= '存在时间词'.$fc.',不合法-|-';
- return [0,$desc,$data];
- }
-
- //11.判断是否合法 屏蔽词
- [$is_bh,$fc] = $this->isInRule($data['pbc'],$line);
- if($is_bh > 0){
- $desc .= '存在屏蔽词'.$fc.',不合法-|-';
- return [0,$desc,$data];
- }
-
- //12.判断是否合法 同时存在触发词和并发词
- [$is_bh1,$fc1] = $this->isInRule($data['cfc'],$line);
- [$is_bh2,$fc2] = $this->isInRule($data['bfc'],$line);
-
-
- //13.替换指令的变量
- //var_dump($data['zlj']);die;
- if(!empty($data['zlj'])){
- $zlj = json_decode($data['zlj'],true);
- $zlj_new = [];
- foreach ($zlj as $k => $v) {
- $key = ''.(string)$k.'';
- if (strpos($v,'K') !== false) {
- $v_str = str_replace("K", $line, $v);
- $zlj_new[$key] = $v_str;
- }else{
- $zlj_new[$key] = $v;
- }
- }
- $zlj_new_json = json_encode($zlj_new,JSON_UNESCAPED_UNICODE);
- $data['zlj'] = $zlj_new_json;
- //var_dump($zlj_new_json);die;
- }
-
- if($is_bh1 > 0 && $is_bh2 > 0){
- //同时存在
- $desc .= '同时存在并发词['.$fc2.']和触发词['.$fc1.']合法';
- return [1,$desc,$data];
- }else{
- $desc .= '不同时存在并发词['.$fc2.']和触发词['.$fc1.'],不合法';
- return [0,$desc,$data];
- }
- }
-
- /*
- * 规则设定
- */
- 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);
-
- //执行下载
-
- }
-
- /*
- * curl - post 通知
- */
- public function curlPost($data){
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, "http://workerman.dev.zx2049.com/work/push/test");
- curl_setopt($ch, CURLOPT_POST, 1);
- //The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
- curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($data));
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- $output = curl_exec($ch);
- curl_close($ch);
- return $output;
- }
-
-
- /*
- * 定时自动通过合法的短标题
- * http://console.zx2049.com/api/ai/dsTitle
- */
- public function dsTitle()
- {
- $id_list = Db::name('cms_zl')->where([
- 'catid'=>18,
- 'is_use' => 1,
- 'status' => 0
- ])->limit(10)->column('id');
- dump($id_list);
- Db::name('cms_zl')->where('id','in',$id_list)->update([
- 'status' => 1
- ]);
- }
-
- /*
- * 定时同步通过审核的短标题到自动发文
- * http://console.zx2049.com/api/ai/dsTitlelist
- * 必须判断唯一 如果标题一样 就不写入了
- */
- public function dsTitlelist()
- {
- //得到最后时间
- $row = Db::name('cms_ai')->where([
- 'catid' => 13
- ])
- ->order('tb_time desc')
- ->limit(1)
- ->find();
-
- //var_dump($row);
-
- if(isset($row['tb_time'])){
- $lasttime = $row['tb_time'];
- }else{
- $lasttime = 0;
- }
-
- $list = Db::name('cms_zl')->where([
- 'catid'=>18,
- 'is_use' => 1, //合法
- 'status' => 1,
- 'is_cf' => 0, //是否重复
- //'id'=>1199
- ])
- ->field('id,title,create_time,is_use_id')
- ->where('create_time','>',$lasttime)
- //->limit(10) //不能限制数量 不然时间查询 下次会漏掉某些时间相同的剩余数量 //要么使用状态字段 //要么使用自增id判断
- ->order('create_time asc') //必须asc排序 先入库
- ->select();
-
- //dump($list);die;
-
- foreach ($list as $index=>$row) {
- $one = Db::name('cms_ai')->field('id,title')->where(['catid' => 13])->where('title','=',$row['title'])->find();
-
- if(empty($one)){
-
- //$json = strip_tags(htmlspecialchars_decode($row['is_use_id']));
- //echo $json;
- $json = $row['is_use_id'];
- $json = json_decode($json,true);
- //dump($json);die;
-
- //读取指令集
- $zlj = $json['zlj'];
- $zlj_arr = json_decode($zlj,true);
- $zlj_end = end($zlj_arr);
- $key = count($zlj_arr)-1;
- unset($zlj_arr[$key]);
- $zlj = json_encode($zlj_arr,JSON_UNESCAPED_UNICODE);
-
-
- //获取创意
- if((string)$json['is_sj'] === '-1'){
- //不需要加创意
- $cy = '0';
- }else{
- if((int)$json['is_sj'] > 0){
- //既然指定 不管管是否为空
- $cy = $json['cy'.$json['is_sj']];
- }else{
-
- //随机
-
-
- $sj_num = [];
- for($i=1;$i<=6;$i++){
- if(!empty($json['cy'.$i])){
- $sj_num[] = $i;
- }
- }
- if(!empty($sj_num)){
- $randomKey = array_rand($sj_num);
- $num = $sj_num[$randomKey];
- $cy = $json['cy'.$num];
- }else{
- $cy = '0';
- }
- }
- }
-
- //不存在于ai中
- $data = [
- 'catid' => 13,
- 'title' => $row['title'],
- 'content' => '0',
- 'topic_1' => '0',
- 'topic_2' => '0',
- 'topic_3' => '0',
- 'didian' => '0',
- 'dssj' => '0',
- 'fbsj' => '0',
- 'tb_time' => $row['create_time'],
- 'create_time' => time(),
- 'update_time' => time(),
- 'status' => 0, //默认手动开启
- 'cy' => $cy, //创意
- 'zlj' => $zlj, //指令集 json字符串
- 'tpzl' => $zlj_end,
- 'sjcy' => $json['is_sj'], //随机创意
- 'lyjlid' => $row['id'], //来源id
- 'sblx' => 3,//设别类型 电脑A
- 'is_sc' => 0, //是否生成文章
- ];
- $run = Db::name('cms_ai')->insert($data);
- Db::name('cms_zl')->where('id',$row['id'])->update(['is_cf'=>2]); //已检测 同步
- echo $run;
- }else{
- //更新为重复记录
- Db::name('cms_zl')->where('id',$row['id'])->update(['is_cf'=>1]);
- echo $row['title']."已存在,更新为重复记录";
- }
- }
- }
-
- /*
- * 定时自动通过合法的发文标题
- * http://console.zx2049.com/api/ai/dsTitle13
- */
- public function dsTitle13()
- {
- $id_list = Db::name('cms_ai')->where([
- 'catid'=>13,
- 'status' => 0
- ])->limit(10)->column('id');
- dump($id_list);
- Db::name('cms_ai')->where('id','in',$id_list)->update([
- 'status' => 1
- ]);
- }
-
- }
|