控制台应用,yzncms本身基于tp5.1框架,里面的队列用不了,bug,坑
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Yzncms [ 御宅男工作室 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2018 http://yzncms.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | fastadmin: https://www.fastadmin.net/
  10. // +----------------------------------------------------------------------
  11. // +----------------------------------------------------------------------
  12. // | 邮箱验证码接口
  13. // +----------------------------------------------------------------------
  14. namespace app\api\controller;
  15. use app\member\controller\MemberApi;
  16. use think\Db;
  17. /**
  18. * @title 邮箱验证码接口
  19. * @controller api\controller\Ems
  20. * @group base
  21. */
  22. class Ai extends MemberApi
  23. {
  24. protected $noNeedLogin = ['login', 'register','uploadCsv','uploadCsvFrom','exportCsv','dsTitle','dsTitlelist','dsTitle13','bdPicHandle','titleHandleApi'];
  25. protected $noNeedRight = [];
  26. //初始化
  27. protected function initialize()
  28. {
  29. //yzncms本身已经做了跨域处理 妈的
  30. //$this->getHook();
  31. parent::initialize();
  32. }
  33. public static function getHook()
  34. {
  35. //需要使用静态方法Facade 不然会报错
  36. \think\Facade\Hook::listen('response_send');
  37. }
  38. /*
  39. * 业务控制器
  40. * 上传csv关键词数据
  41. * https://console.zx2049.com/api/ai/uploadCsv?file=20240504/eebcb4ca6a8a69fdd9e0f60c16b55746.csv
  42. */
  43. public function uploadCsv(){
  44. //测试
  45. $url = request()->get('file',0);
  46. if($url !== 0){
  47. $this->csvHandle('./uploads/'.$url);
  48. return json([]);
  49. }
  50. $file = request()->file('file'); //$file = $_FILES['file'];
  51. $info = $file->move( './uploads');
  52. if($info){
  53. // 成功上传后 获取上传信息
  54. // 输出 jpg
  55. //$url = $info->getExtension();
  56. // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
  57. $url = $info->getSaveName();
  58. // 输出 42a79759f284b767dfcb2a0197904287.jpg
  59. //echo $info->getFilename();
  60. $data = ['code' => 0, 'msg' => '文件上传成功', 'data' =>['src'=>$url]];
  61. }else{
  62. // 上传失败获取错误信息
  63. $info = $file->getError();
  64. $data = ['code' => 1, 'msg' => '文件上传失败', 'data' =>$info];
  65. }
  66. return json($data);
  67. }
  68. /*
  69. * 业务控制器
  70. * 处理表单
  71. */
  72. public function uploadCsvFrom(){
  73. $post = request()->post();
  74. /*
  75. * rule:
  76. 0
  77. title:
  78. 建筑职称
  79. file:
  80. url:
  81. 20240505/2aff80b14c861480183278bbc9442f56.csv
  82. */
  83. //判断关键词是否存在
  84. $one = Db::name('options')->where('title','=',$post['title'])->where('status','=',1)->find();
  85. if(empty($one)){
  86. $data = ['code' => 1, 'msg' => '关键词不存在', 'data' => []];
  87. return json($data);
  88. }
  89. if(!empty($post['url'])){
  90. $this->csvHandle('./uploads/'.$post['url'],$post['rule'],$post['title']);
  91. $data = ['code' => 0, 'msg' => '提交成功', 'data' =>$post];
  92. }else{
  93. $data = ['code' => 1, 'msg' => '提交失败', 'data' => []];
  94. }
  95. return json($data);
  96. }
  97. /*
  98. * 逻辑控制器
  99. * 规则的指令集和创意 如果为空 调用全局的即可 同样优先调用自身规则
  100. */
  101. public function csvHandle($url,$rule,$title){
  102. // 读取CSV文件
  103. $filename = $url;
  104. if (file_exists($filename)) {
  105. $file = fopen($filename, 'r');
  106. //任务批次
  107. $task_no = date('YmdHis',time()).'-'.rand(1,10000);
  108. //插入 重复也无所谓了
  109. Db::name('pc')->insert(['catid'=>31,'title'=>$task_no,'create_time' => time(),'update_time' => time()]);
  110. $pid = time(); //不考虑并发提交多次间隔也是秒级
  111. $num = 1;
  112. $log_content = '';
  113. $log_content_error = '';
  114. $s_num = 0;
  115. $f_num = 0;
  116. while (($line = fgetcsv($file)) !== FALSE) {
  117. // $line是一个数组,包含CSV的一行数据
  118. //print_r($line);
  119. if($num === 1){
  120. $row = $line;
  121. }else{
  122. if(!empty($line[0])) {
  123. //关键词步骤省略 需要去站长之家搜索并导出 这个步骤由人工操作
  124. //判断是否存在短标题 重复性检测
  125. //相同规则 短标题只能存在一个
  126. $one = Db::name('cms_zl')
  127. ->where('title', '=', $line[0])
  128. ->where('catid', '=', 18) //分类id
  129. ->where('zc', '=', $title) //主词
  130. ->where('gzxh', '=', $rule) //规则id
  131. ->where('sj','=',$task_no) //时间维度 批次
  132. ->find();
  133. if (empty($one)) {
  134. //过滤标题是否合法的函数 这个可以用定时任务处理
  135. [$is_use, $desc, $rule_id] = $this->titleHandle($line[0], $rule, $title);
  136. //构建详情
  137. $html = '';
  138. for ($i = 1; $i < 10; $i++) {
  139. $html .= $row[$i] . ':' . $line[$i] . '<br/>';
  140. }
  141. $data = [
  142. 'catid' => 18, //短标题
  143. 'title' => $line[0], //短标题
  144. 'content' => $html,
  145. 'zc' => $title, //增加主词字段
  146. 'create_time' => time(),
  147. 'update_time' => time(),
  148. 'status' => 0, //默认禁用状态 定时手动开启 自动化再读取即可
  149. 'pid' => $pid, //关联日志的aid,可查询到规则序号 主词 文件地址 执行情况
  150. 'ptlx' => 0,
  151. 'is_use' => $is_use, //是否合法
  152. 'desc' => $desc, //非法原因 或者 合法匹配结果
  153. 'gzxh' => $rule,
  154. 'sj' => $task_no, //写入时间维度 批次
  155. 'is_use_id' => json_encode($rule_id,JSON_UNESCAPED_UNICODE), //写入具体规则id 可查询到对应规则是什么 判断是否合法
  156. ];
  157. //dump($data);
  158. //插入记录
  159. $doc_id = Db::name('cms_zl')->insertGetId($data);
  160. //写入日志
  161. $log_content .= '指令id-' . $doc_id . '-' . json_encode($line, JSON_UNESCAPED_UNICODE) . '<br/>';
  162. $s_num++;
  163. //通知前端
  164. $is_use_desc = $is_use === 1?'合法':'不匹配';
  165. $msg = [
  166. 'info' => '['.$line[0].']成功新增记录!匹配结果:'.$is_use_desc
  167. ];
  168. $this->curlPost($msg);
  169. } else {
  170. //写日志
  171. $log_content_error .= '<p>短标题-' . $line[0] . '-已存在-指令短标题id:' . $one['id'] . '</p>';
  172. $f_num++;
  173. //通知前端
  174. $msg = [
  175. 'info' => '相同规则与相同主词下,['.$line[0].']已存在-不可重复导入!'
  176. ];
  177. $this->curlPost($msg);
  178. }
  179. }
  180. }
  181. $num++;
  182. }
  183. //每次操作 1-2条 日志记录
  184. if(!empty($log_content)){
  185. Db::name('log')->insert([
  186. 'catid' => 27,
  187. 'title' => '批次'.$task_no.'成功导入处理-'.$s_num.'条数据',
  188. 'keywords' => $title, //主词
  189. 'description' => $filename,//对应文件地址
  190. 'create_time' => time(),
  191. 'update_time' => time(),
  192. 'status' => 1,
  193. 'site_id'=> 1,
  194. 'cid' => (int)$rule, //规则序号
  195. 'aid' => $pid, //对应记录id
  196. 'content' => '<p>'.$log_content.'</p>',
  197. ]);
  198. }
  199. if(!empty($log_content_error)){
  200. Db::name('log')->insert([
  201. 'catid' => 27,
  202. 'title' => '批次'.$task_no.'导入处理已存在-'.$f_num.'条数据',
  203. 'keywords' => $title, //主词
  204. 'description' => $filename,//对应文件地址
  205. 'create_time' => time(),
  206. 'update_time' => time(),
  207. 'status' => 1,
  208. 'site_id'=> 1,
  209. 'cid' => (int)$rule, //规则序号
  210. 'aid' => $pid, //对应记录id
  211. 'content' => '<p>'.$log_content_error.'</p>',
  212. ]);
  213. }
  214. fclose($file);
  215. }
  216. /*// 写入CSV文件
  217. $data = [
  218. ['Name', 'Age', 'Email'],
  219. ['Alice', 25, 'alice@example.com'],
  220. ['Bob', 30, 'bob@example.com']
  221. ];
  222. $filename = 'output.csv';
  223. $file = fopen($filename, 'w');
  224. foreach ($data as $row) {
  225. fputcsv($file, $row);
  226. }
  227. fclose($file);*/
  228. }
  229. /*
  230. * 模型控制器 操作数据
  231. */
  232. /*
  233. * http://console.zx2049.com/api/ai/titleHandleApi
  234. * 调试
  235. */
  236. public function titleHandleApi(){
  237. $t = $this->titleHandle('建筑职称评审',0,'建筑职称');
  238. var_dump($t);
  239. }
  240. /*
  241. * 处理函数
  242. * $title 主词
  243. */
  244. public function titleHandle($line,$rule,$title){
  245. //规则1
  246. $desc = '';
  247. //是否完全匹配主词
  248. if (strpos($line, $title) !== false) {
  249. //包含主词
  250. }else{
  251. return [0,'短标题不包含主词['.$title.']',0];
  252. }
  253. //1.查询是否存在主词规则
  254. $one = Db::name('cms_zl')
  255. ->where('catid','=',17)
  256. ->where('title','=',$title) //只能一条 已做标题重复校验
  257. ->where('is_qj','=',0) //非全局
  258. ->where('zllx','=',1) //指令类型是 主词
  259. ->where('gzxh','=',$rule)
  260. ->where('status','=',1) //多条需要控制开关
  261. ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条
  262. ->find();
  263. //2.查询全局主词规则
  264. if(empty($one)){
  265. $one = Db::name('cms_zl')
  266. ->where('catid','=',17)
  267. ->where('title','=','全局-主词类型') //只能一条 已做标题重复校验
  268. ->where('is_qj','=',1) //是全局
  269. ->where('zllx','=',1) //指令类型是 主词
  270. ->where('gzxh','=',$rule)
  271. ->where('status','=',1) //多条需要控制开关
  272. ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条
  273. ->find();
  274. }
  275. //3.查询全局规则
  276. if(empty($one)){
  277. $one = Db::name('cms_zl')
  278. ->where('catid','=',17)
  279. ->where('title','=','全局-非主非副') //只能一条 已做标题重复校验
  280. ->where('is_qj','=',1) //是全局
  281. ->where('zllx','=',0) //指令类型是 非主非副
  282. ->where('gzxh','=',$rule)
  283. ->where('status','=',1) //多条需要控制开关
  284. ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条
  285. ->find();
  286. }
  287. if(empty($one)){
  288. return [0,'不存在全局通用规则,全局主词规则,当前主词规则',0];
  289. }
  290. //4.获取到全局或主词的副词
  291. $two = [];
  292. if(empty($one['fclb']) || (string)$one['fclb'] === '0'){
  293. //不存在副词规则 快照 表示这条规则 没有副词匹配要求
  294. //即使标题里面存在 主词设置的副词列表
  295. //即使存在某些副词规则 不存在副词规则 确定不了哪个是副词 故二无法匹配
  296. $desc .= '不存在副词规则-|-';
  297. }else{
  298. //存在副词规则
  299. $one['fclb'] = $one['fclb'].',';
  300. $fclb = explode(',',$one['fclb']);
  301. $line_sor = str_replace($title, "", $line); //短标题去除主词
  302. $is_bh = 0;
  303. $fc = '';
  304. $fc_num = 0;
  305. foreach ($fclb as $k => $v) {
  306. //该判断 主词和副词 不一定是连在一起的
  307. if(!empty($v)) {
  308. if (strpos($line_sor, $v) !== false) {
  309. //包含
  310. $is_bh = 1;
  311. $fc = $v;
  312. //break; //跳出 目前只匹配一个 存在多个不做处理 以第一个为主
  313. $fc_num++;
  314. }
  315. }
  316. }
  317. //如果副词快照存在,那么以副词快照里面找不到,那么再去找主词设置是否存在
  318. //这样判断是不真实的 因为主词设置是会修改的
  319. if($is_bh === 0){
  320. //$fc 无法确认值 所以无法匹配副词规则
  321. //当主词规则 都没有填写副词列表 就表示不匹配副词了
  322. }
  323. //存在多个副词 不合理
  324. if($fc_num > 1){
  325. return [0,'存在多个副词,不合法',$one['id']];
  326. }
  327. //5.判断是否存在副词
  328. if($is_bh === 1){
  329. //6.查询主词+副词是否存在规则
  330. $two = Db::name('cms_zl')
  331. ->where('catid','=',17)
  332. ->where('title','=',$title.$fc) //查询设置 按照主词+副词 格式查询 //只能一条 已做标题重复校验
  333. ->where('is_qj','=',0) //非全局
  334. ->where('zllx','=',2) //指令类型是 副词
  335. ->where('gzxh','=',$rule)
  336. ->where('status','=',1) //多条需要控制开关
  337. ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条
  338. ->find();
  339. //7.查询副词通用全局规则
  340. if(empty($two)){
  341. $two = Db::name('cms_zl')
  342. ->where('catid','=',17)
  343. ->where('title','=','全局-副词类型') //查询设置 按照主词+副词 格式查询 //只能一条 已做标题重复校验
  344. ->where('is_qj','=',1) //非全局
  345. ->where('zllx','=',2) //指令类型是 副词
  346. ->where('gzxh','=',$rule)
  347. ->where('status','=',1) //多条需要控制开关
  348. ->order('id asc') //可能添加多条 以第一条为主 理论每个规则只添加一条
  349. ->find();
  350. }
  351. }else{
  352. //短标题不包含副词
  353. $desc .= '短标题不包含副词-|-';
  354. }
  355. }
  356. //短标题的主词和副词 不一定是连在一起的
  357. if(!empty($two)){
  358. //存在副词规则 按照此规则执行
  359. $data = $two;
  360. }else{
  361. //按照$one规则记录执行
  362. $data = $one;
  363. }
  364. //8.判断是否合法 地区词
  365. [$is_bh,$fc] = $this->isInRule($data['dqc'],$line);
  366. if($is_bh > 0){
  367. $desc .= '存在地区词'.$fc.',不合法-|-';
  368. return [0,$desc,$data];
  369. }
  370. //9.判断是否合法 分类词
  371. [$is_bh,$fc] = $this->isInRule($data['flc'],$line);
  372. if($is_bh > 0){
  373. $desc .= '存在分类词'.$fc.',不合法-|-';
  374. return [0,$desc,$data];
  375. }
  376. //10.判断是否合法 时间词
  377. [$is_bh,$fc] = $this->isInRule($data['sjc'],$line);
  378. if($is_bh > 0){
  379. $desc .= '存在时间词'.$fc.',不合法-|-';
  380. return [0,$desc,$data];
  381. }
  382. //11.判断是否合法 屏蔽词
  383. [$is_bh,$fc] = $this->isInRule($data['pbc'],$line);
  384. if($is_bh > 0){
  385. $desc .= '存在屏蔽词'.$fc.',不合法-|-';
  386. return [0,$desc,$data];
  387. }
  388. //12.替换指令的变量
  389. //var_dump($data['zlj']);die;
  390. if(!empty($data['zlj'])){
  391. $zlj = json_decode($data['zlj'],true);
  392. $zlj_new = [];
  393. foreach ($zlj as $k => $v) {
  394. $key = ''.(string)$k.'';
  395. if (strpos($v,'K') !== false) {
  396. $v_str = str_replace("K", $line, $v);
  397. $zlj_new[$key] = $v_str;
  398. }else{
  399. $zlj_new[$key] = $v;
  400. }
  401. }
  402. $zlj_new_json = json_encode($zlj_new,JSON_UNESCAPED_UNICODE);
  403. $data['zlj'] = $zlj_new_json;
  404. //var_dump($zlj_new_json);die;
  405. }
  406. //13.判断是否合法 同时存在触发词和并发词
  407. //增加判断可以不存在并发词和触发词
  408. //只需要匹配 包含主词即可通过
  409. if(!empty($data['cfc']) && (string)$data['cfc'] != '0' || !empty($data['bfc']) && (string)$data['bfc'] != '0'){
  410. [$is_bh1,$fc1] = $this->isInRule($data['cfc'],$line);
  411. [$is_bh2,$fc2] = $this->isInRule($data['bfc'],$line);
  412. }else{
  413. $desc .= '不需要验证并发词和触发词,合法';
  414. return [1,$desc,$data];
  415. }
  416. //var_dump($data['cfc']);
  417. //var_dump($is_bh1);
  418. //var_dump($is_bh2);
  419. //die;
  420. if($is_bh1 > 0 && $is_bh2 > 0){
  421. //同时存在
  422. $desc .= '合法,同时存在并发词['.$fc2.']和触发词['.$fc1.']';
  423. return [1,$desc,$data];
  424. }else if($is_bh1 > 0 || $is_bh2 > 0){
  425. $desc .= '合法,不同时存在并发词['.$fc2.']和触发词['.$fc1.']';
  426. return [1,$desc,$data];
  427. }else{
  428. $desc .= '不合法,同时不存在并发词['.$fc2.']和触发词['.$fc1.']';
  429. return [0,$desc,$data];
  430. }
  431. }
  432. /*
  433. * 规则设定
  434. */
  435. public function setRule(){
  436. //方案1: 定义config配置文件
  437. //方案2: 直接代码写死
  438. //方案3: 后台设置 -- 采用这个
  439. $json = [
  440. ''
  441. ];
  442. }
  443. /*
  444. * 函数 是否包含
  445. */
  446. public function isInRule($data,$str){
  447. $data = $data.',';
  448. $data = explode(',',$data);
  449. $is_bh = 0;
  450. $fc = '';
  451. foreach ($data as $k => $v) {
  452. //该判断 主词和副词 不一定是连在一起的
  453. if(!empty($v)) {
  454. if (strpos($str, $v) !== false) {
  455. //包含
  456. $is_bh = 1;
  457. $fc = $v;
  458. break; //跳出 目前只匹配一个 存在多个不做处理 以第一个为主
  459. }
  460. }
  461. }
  462. return [$is_bh,$fc];
  463. }
  464. /*
  465. * 导出csv
  466. * http://console.zx2049.com/api/ai/exportCsv
  467. */
  468. public function exportCsv(){
  469. $list = Db::name('cms_zl')->field('id,title,desc')->where('catid','=',18)->select();
  470. /* $data = [
  471. ['Name', 'Age', 'Email'],
  472. ['Alice', 25, 'alice@example.com'],
  473. ['Bob', 30, 'bob@example.com']
  474. ];*/
  475. $filename = 'output.csv';
  476. $file = fopen($filename, 'w');
  477. foreach ($list as $row) {
  478. fputcsv($file, $row);
  479. }
  480. fclose($file);
  481. //执行下载
  482. }
  483. /*
  484. * curl - post 通知
  485. */
  486. public function curlPost($data){
  487. $ch = curl_init();
  488. curl_setopt($ch, CURLOPT_URL, "http://workerman.dev.zx2049.com/work/push/test");
  489. curl_setopt($ch, CURLOPT_POST, 1);
  490. //The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
  491. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
  492. curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($data));
  493. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  494. $output = curl_exec($ch);
  495. curl_close($ch);
  496. return $output;
  497. }
  498. /*
  499. * 定时自动通过合法的短标题
  500. * http://console.zx2049.com/api/ai/dsTitle
  501. */
  502. public function dsTitle()
  503. {
  504. $id_list = Db::name('cms_zl')->where([
  505. 'catid'=>18,
  506. 'is_use' => 1,
  507. 'status' => 0
  508. ])->limit(10)->column('id');
  509. dump($id_list);
  510. Db::name('cms_zl')->where('id','in',$id_list)->update([
  511. 'status' => 1
  512. ]);
  513. }
  514. /*
  515. * 定时同步通过审核的短标题到自动发文
  516. * http://console.zx2049.com/api/ai/dsTitlelist
  517. * 必须判断唯一 如果标题一样 就不写入了
  518. */
  519. public function dsTitlelist()
  520. {
  521. //得到最后时间
  522. $row = Db::name('cms_ai')->where([
  523. 'catid' => 13
  524. ])
  525. ->order('tb_time desc')
  526. ->limit(1)
  527. ->find();
  528. //var_dump($row);
  529. if(isset($row['tb_time'])){
  530. $lasttime = $row['tb_time'];
  531. }else{
  532. $lasttime = 0;
  533. }
  534. $list = Db::name('cms_zl')->where([
  535. 'catid'=>18,
  536. 'is_use' => 1, //合法
  537. 'status' => 1,
  538. 'is_cf' => 0, //是否重复
  539. //'id'=>1199
  540. ])
  541. ->field('id,title,create_time,is_use_id')
  542. ->where('create_time','>',$lasttime)
  543. //->limit(10) //不能限制数量 不然时间查询 下次会漏掉某些时间相同的剩余数量 //要么使用状态字段 //要么使用自增id判断
  544. ->order('create_time asc') //必须asc排序 先入库
  545. ->select();
  546. //dump($list);die;
  547. foreach ($list as $index=>$row) {
  548. $one = Db::name('cms_ai')->field('id,title')->where(['catid' => 13])->where('title','=',$row['title'])->find();
  549. if(empty($one)){
  550. //$json = strip_tags(htmlspecialchars_decode($row['is_use_id']));
  551. //echo $json;
  552. $json = $row['is_use_id'];
  553. $json = json_decode($json,true);
  554. //dump($json);die;
  555. //读取指令集
  556. $zlj = $json['zlj'];
  557. $zlj_arr = json_decode($zlj,true);
  558. $zlj_end = end($zlj_arr);
  559. $key = count($zlj_arr)-1;
  560. unset($zlj_arr[$key]);
  561. $zlj = json_encode($zlj_arr,JSON_UNESCAPED_UNICODE);
  562. //获取创意
  563. if((string)$json['is_sj'] === '-1'){
  564. //不需要加创意
  565. $cy = '0';
  566. }else{
  567. if((int)$json['is_sj'] > 0){
  568. //既然指定 不管管是否为空
  569. $cy = $json['cy'.$json['is_sj']];
  570. }else{
  571. //随机
  572. $sj_num = [];
  573. for($i=1;$i<=6;$i++){
  574. if(!empty($json['cy'.$i])){
  575. $sj_num[] = $i;
  576. }
  577. }
  578. if(!empty($sj_num)){
  579. $randomKey = array_rand($sj_num);
  580. $num = $sj_num[$randomKey];
  581. $cy = $json['cy'.$num];
  582. }else{
  583. $cy = '0';
  584. }
  585. }
  586. }
  587. //不存在于ai中
  588. $data = [
  589. 'catid' => 13,
  590. 'title' => $row['title'],
  591. 'content' => '0',
  592. 'topic_1' => '0',
  593. 'topic_2' => '0',
  594. 'topic_3' => '0',
  595. 'didian' => '0',
  596. 'dssj' => '0',
  597. 'fbsj' => '0',
  598. 'tb_time' => $row['create_time'],
  599. 'create_time' => time(),
  600. 'update_time' => time(),
  601. 'status' => 0, //默认手动开启
  602. 'cy' => $cy, //创意
  603. 'zlj' => $zlj, //指令集 json字符串
  604. 'tpzl' => $zlj_end,
  605. 'sjcy' => $json['is_sj'], //随机创意
  606. 'lyjlid' => $row['id'], //来源id
  607. 'sblx' => 3,//设别类型 电脑A
  608. 'is_sc' => 0, //是否生成文章
  609. 'pic_html' => '0',
  610. 'imgs' => '{}'
  611. ];
  612. $run = Db::name('cms_ai')->insert($data);
  613. Db::name('cms_zl')->where('id',$row['id'])->update(['is_cf'=>2]); //已检测 同步
  614. echo $run;
  615. }else{
  616. //更新为重复记录
  617. Db::name('cms_zl')->where('id',$row['id'])->update(['is_cf'=>1]);
  618. echo $row['title']."已存在,更新为重复记录";
  619. }
  620. }
  621. }
  622. /*
  623. * 定时自动通过合法的发文标题
  624. * http://console.zx2049.com/api/ai/dsTitle13
  625. */
  626. public function dsTitle13()
  627. {
  628. $id_list = Db::name('cms_ai')->where([
  629. 'catid'=>13,
  630. 'status' => 0
  631. ])->limit(10)->column('id');
  632. dump($id_list);
  633. Db::name('cms_ai')->where('id','in',$id_list)->update([
  634. 'status' => 1
  635. ]);
  636. }
  637. /*
  638. * 处理百度的的ai图片 变成本地的
  639. * 定时任务处理
  640. * http://console.zx2049.com/api/ai/bdPicHandle
  641. */
  642. public function bdPicHandle(){
  643. //查找是否已处理图片 本地化
  644. $id_list = Db::name('cms_ai')->where([
  645. 'catid'=>13,
  646. 'is_pic' => 0,
  647. 'is_sc' => 1, //已生成文章
  648. ])->find();
  649. if(!empty($id_list['pic_html'])){
  650. //提取图片
  651. //var_dump($id_list['pic_html']);
  652. $str = htmlspecialchars_decode($id_list['pic_html']);
  653. $pattern="/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png?]))[\'|\"].*?[\/]?>/";
  654. preg_match_all($pattern,$str,$match);
  655. print_r($match[1]);
  656. //下载文件到本地服务器
  657. $imgs = $match[1];
  658. if(!empty($imgs)){
  659. $dir_name = '/ai/images/'.date('Y-m-d',time()).'/';
  660. $dir = '.'.$dir_name;
  661. if(!is_dir($dir)) {
  662. mkdir($dir, 0777, true);
  663. }
  664. $new_img = [];
  665. foreach ($imgs as $k => $v){
  666. //去除字符
  667. $v = str_replace("?", "", $v);
  668. $this->downloadImage($v, $dir);
  669. $filename = pathinfo($v, PATHINFO_BASENAME);
  670. $new_img[] = $dir_name.$filename;
  671. }
  672. //保存图片信息
  673. $new_img = json_encode($new_img);
  674. Db::name('cms_ai')->where([
  675. 'id' => $id_list['id']
  676. ])->update([
  677. 'is_pic' => 1,
  678. 'imgs' => $new_img,
  679. 'username' => 'admin',
  680. 'sysadd' => 1,
  681. 'hits' => 1
  682. ]);
  683. }else{
  684. //图片为空 同样更新为
  685. Db::name('cms_ai')->where([
  686. 'id' => $id_list['id']
  687. ])->update([
  688. 'is_pic' => 1,
  689. 'imgs' => "{}",
  690. 'username' => 'admin',
  691. 'sysadd' => 1,
  692. 'hits' => 1
  693. ]);
  694. }
  695. }
  696. }
  697. //保存文件方法
  698. public function saveAsImage($url, $file, $path)
  699. {
  700. $filename = pathinfo($url, PATHINFO_BASENAME);
  701. $resource = fopen($path . $filename, 'a');
  702. fwrite($resource, $file);
  703. fclose($resource);
  704. }
  705. //下载文件方法
  706. public function downloadImage($url, $path)
  707. {
  708. $ch = curl_init();
  709. curl_setopt($ch, CURLOPT_URL, $url);
  710. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  711. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  712. //避免https 的ssl验证
  713. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  714. curl_setopt($ch, CURLOPT_SSLVERSION, false);
  715. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  716. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  717. $file = curl_exec($ch);
  718. if(curl_exec($ch) === false) echo 'Curl error: ' . curl_error($ch);
  719. curl_close($ch);
  720. $this->saveAsImage($url, $file, $path);
  721. }
  722. }