ciyon_ai/web/admin/www/keywordManage.php

612 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace web\admin\www;
class keywordManage
{
static function setwhere($db, $post, $rsuser)
{
$query = $post->get('query', array());
$csql = new \ciy\sql('www_keyword');
$val = objstr($query, 'cateid');
if (!empty($val)) {
$csqlt = new \ciy\sql('www_list_cate');
$csqlt->where('name like', $val);
$trow = $db->getone($csqlt);
if (is_array($trow)) {
$csql->where('cateid', $trow['id']);
$query['cateid'] = $trow['name'];
} else {
$csql->where('cateid=0');
}
} else
$csql->where('cateid', get('_cateid'));
$csql->where('name like', objstr($query, 'name'));
$csql->where('usetime like', objstr($query, 'usetime'));
$csql->wheredaterange('addtimes', objstr($query, 'addtimes'));
$order = objstr($query, 'order', 'id desc');
$csql->order($order);
$query['order'] = $order;
return [$query, $csql];
}
public static function json_list()
{
global $db;
$rsuser = verifyfast();
$post = new \ciy\post();
list($where, $csql) = self::setwhere($db, $post, $rsuser);
$pageno = $post->getint('pageno', 1);
$pagecount = $post->getint('pagecount', 10);
$csql->limit($pageno, $pagecount);
$mainrowcount = $post->getint('count');
$mrows = $db->get($csql, $mainrowcount);
if ($mrows === false)
return errjson($db->error);
$ret = array('searchwhere' => $where, 'pageno' => $pageno, 'pagecount' => $pagecount, 'count' => $mainrowcount, 'list' => $mrows);
if ($post->getbool('field')) {
$field = array();
$fshow = $db->getfield($field, 'www_keyword');
foreach ($field as $fr => $v) {
if (get('_' . $fr))
$field[$fr]['c'] = ',' . $field[$fr]['c'];
}
$fshow = fieldadd($fshow, $field, 0, '_btn', '操作');
$ret['field'] = $field;
$ret['fshow'] = $fshow;
}
if ($post->getbool('once')) {
$ret['once'] = true;
$input = array();
if (!get('_cateid'))
$input[] = array('type' => 'input', 'form' => 'cateid', 'name' => '所属栏目', 'prop' => ' style="width:8em;"');
$input[] = array('type' => 'input', 'form' => 'name', 'name' => '关键词', 'prop' => ' style="width:8em;"');
$input[] = array('type' => 'input', 'form' => 'usetime', 'name' => '使用次数', 'prop' => ' style="width:8em;"');
$input[] = array('type' => 'daterange', 'form' => 'addtimes', 'name' => '添加时间');
$ret['searchinput'] = $input;
$csql = (new \ciy\sql('www_list_cate'))->column('id,name');
$ret['www_list_cate'] = $db->get($csql);
}
return succjson($ret);
}
public static function json_update()
{
global $db;
$rsuser = verifyfast();
//if (nopower($db, $rsuser['id'], 'p u'))
// return errjson('您未被授权操作');
$post = new \ciy\post();
//$db->trace($post->get('_pf'), $rsuser);
$id = $post->getint('id');
$cateid = $post->getint('cateid');
$name = $post->get('name');
if ($cateid == 0)
return errjson('请填写所属栏目');
if (empty($name))
return errjson('请填写关键词');
$datarow = null;
if ($id > 0) {
$csql = new \ciy\sql('www_keyword');
$csql->where('id', $id);
$datarow = $db->getone($csql);
if (!is_array($datarow))
return errjson('数据不存在');
}
try {
$db->begin();
$updata = array();
$updata['cateid'] = $cateid;
$updata['name'] = $name;
$csql = new \ciy\sql('www_keyword'); //auto
if ($id > 0) {
$csql->where('id', $id);
if ($db->update($csql, $updata) === false)
throw new \Exception('更新失败:' . $db->error);
} else {
$updata['usetime'] = 0;
$updata['addtimes'] = tostamp();
if ($db->insert($csql, $updata) === false)
throw new \Exception('新增失败:' . $db->error);
$id = $db->insert_id();
}
$updata['id'] = $id;
//savelogdb($db, $rsuser['id'], 'www_keyword', $datarow, $updata);
$db->commit();
} catch (\Exception $ex) {
$db->rollback();
savelogfile('err_db', $ex->getMessage());
return errjson($ex->getMessage());
}
$ret['data'] = $updata;
return succjson($ret);
}
public static function json_del()
{
global $db;
$rsuser = verifyfast();
//if (nopower($db, $rsuser['id'], 'p d'))
// return errjson('您未被授权操作');
$post = new \ciy\post();
//$db->trace($post->get('_pf'), $rsuser);
$ids = $post->get('ids');
if (empty($ids))
return errjson('请选择至少一条');
$csql = new \ciy\sql('www_keyword');
$csql->where('id in', $ids);
$mrows = $db->get($csql);
$vids = array();
try {
$db->begin();
foreach ($mrows as $mrow) {
$delid = $mrow['id'];
//delcheck($db, $delid, 'tablexx', 'xxid', '管理员');
//delall($db, $delid, 'tablexx', 'xxid', '运动员'); //deltimeall
delme($db, $delid, 'www_keyword');
savelogdb($db, $rsuser['id'], 'www_keyword', $mrow, null);
$vids[] = $delid;
}
$db->commit();
} catch (\Exception $ex) {
$db->rollback();
savelogfile('err_db', $ex->getMessage());
return errjson($ex->getMessage());
}
$ret['ids'] = $vids;
return succjson($ret);
}
public static function json_exportxls()
{
global $db;
$rsuser = verifyfast();
//if (nopower($db, $rsuser['id'], 'p e'))a
// return errjson('您未被授权操作');
$post = new \ciy\post();
list($where, $csql) = self::setwhere($db, $post, $rsuser);
$mrows = $db->get($csql);
if (count($mrows) > 10000)
return errjson('将导出' . count($mrows) . '条不建议超过1万条请筛选缩小范围');
$fields = array();
$fields[] = array('style' => 'l', 'width' => 60, 'field' => 'id', 'name' => '行码');
$fields[] = array('style' => 'l', 'width' => 100, 'field' => 'cateid', 'name' => '所属栏目');
$fields[] = array('style' => 'l', 'width' => 150, 'field' => 'name', 'name' => '关键词');
$fields[] = array('style' => 'r', 'width' => 100, 'field' => 'usetime', 'name' => '使用次数');
$fields[] = array('style' => 'l', 'width' => 100, 'field' => 'addtimes', 'name' => '添加时间');
$code_cateid = $db->get((new \ciy\sql('www_list_cate'))->column('id,name'));
$datas = array();
foreach ($mrows as $mrow) {
$dat = array();
foreach ($fields as $field) {
$field = $field['field'];
$val = isset($mrow[$field]) ? $mrow[$field] : '';
if ($field == 'id')
$val = enid($val);
if ($field == 'cateid')
$val = ccode($code_cateid, $val);
if ($field == 'addtimes')
$val = ($val <= 0 ? '--' : date('Y-m-d H:i', $val));
$dat[] = $val;
}
$datas[] = $dat;
}
$param = array();
$param['field'] = $fields;
$param['data'] = $datas;
$param['sheetname'] = '数据报表';
$param['titleheight'] = '25'; //列头高度
$param['landscape'] = true; //横向打印
$param['fixtopage'] = true; //打印整个工作表
$param['toptitle'] = '关键词库数据报表';
$str = \ciy\excel::general_excel_xml($param);
$filename = '';
if (empty($filename))
$filename = date('Y-m-d_H-i-s') . rand(1000, 9999);
$filename .= '.xls';
file_put_contents(PATH_WEB . 'ud/tmp/' . $filename, $str);
return succjson(array('url' => '/ud/tmp/' . $filename));
}
public static function json_importxls_in()
{
global $db;
$rsuser = verifyfast();
//if (nopower($db, $rsuser['id'], 'p i'))
// return errjson('您未被授权操作');
$post = new \ciy\post();
$file = PATH_WEB . '/ud' . $post->get('file');
if (!file_exists($file))
return errjson('文件不存在');
require_once PATH_ROOT . '../libs/phpoffice/autoload.php';
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file);
$sheet = $spreadsheet->getActiveSheet();
$datas = $sheet->toArray('', true, true, false);
$datacnt = count($datas);
if ($datacnt < 2)
return errjson('数据为空');
$html = '';
$headsn = array();
$headsn[] = '行码.id';
$headsn[] = '所属栏目.cateid';
$headsn[] = '关键词.name';
$headsn[] = '使用次数.usetime';
$xlsidx = 1;
if (empty($datas[0][count($headsn) - 1]))
$xlsidx = 2;
$heads = array();
foreach ($headsn as $_head) {
$hd = explode('.', $_head);
if (count($hd) < 2)
continue;
$heads[] = array(
'idx' => array_search($hd[0], $datas[$xlsidx - 1]),
'fld' => $hd[1],
'name' => $hd[0]
);
}
$code_cateid = $db->get((new \ciy\sql('www_list_cate'))->column('id,name'));
$html .= '<div class="table" style="width: 100%;height: calc(100% - 2.2em);overflow: auto;">';
$html .= '<table><tbody><tr>';
$html .= '<th>#</th>';
foreach ($heads as $arr) {
$html .= '<th>' . $arr['name'] . '</th>';
}
$html .= '</tr>';
$cnt = 0;
$uniques = array();
$id = 0;
for ($rowidx = $xlsidx; $rowidx < $datacnt; $rowidx++) {
$bfull = false;
foreach ($datas[$rowidx] as $dat) {
if (empty($dat))
continue;
$bfull = true;
break;
}
if (!$bfull)
continue;
$lineidx = $rowidx - $xlsidx + 1;
$hrhtml = '';
$firsthtml = '<td><div>' . $lineidx . '</div></td>';
$bempty = true;
$unqs = array();
$csql = new \ciy\sql('www_keyword');
foreach ($heads as $arr) {
$name = $arr['name'];
$errmsg = ''; //数据有误,显示红色说明
$showdat = ''; //显示在表格中的数据
if ($arr['idx'] > -1)
$showdat = trim($datas[$rowidx][$arr['idx']]);
if ($showdat == '--')
$showdat = '';
$value = $showdat; //在表单中的数据(转换后)
$ext = ''; //扩展表单
if ($name == '行码') {
if (empty($showdat)) {
$value = 0;
$showdat = '<kbd>新增</kbd>';
} else {
$id = deid($showdat);
if ($id == 0)
$errmsg = $name . '解析错误';
else {
$csqlchk = new \ciy\sql('www_keyword');
$csqlchk->where('id', $id)->column('id');
$chkid = toint($db->get1($csqlchk));
if ($chkid != $id)
$errmsg = $name . '在数据库中不存在';
$value = $id;
}
}
} else if ($name == '所属栏目') {
if (empty($showdat)) {
$errmsg = $name . '为必填项';
} else {
$value = dcode($code_cateid, $showdat);
if ($value == -1)
$errmsg = $name . '文字与系统数据不匹配';
}
} else if ($name == '关键词') {
if (empty($showdat)) {
$errmsg = $name . '为必填项';
} else {
}
} else if ($name == '使用次数') {
if (empty($showdat)) {
$value = 0;
} else {
$showdat = str_replace(',', '', $showdat);
if (!is_numeric($showdat))
$errmsg = $name . '不是数字';
else
$value = toint($showdat);
}
}
if (!empty($showdat))
$bempty = false;
if (empty($errmsg))
$hrhtml .= '<td><div>' . $showdat . '<input type="hidden" name="' . $arr['fld'] . '_' . $lineidx . '" value="' . $value . '"/>' . $ext . '</div></td>';
else
$hrhtml .= '<td style="background:#ffe8c5;" title="#' . $lineidx . ':' . $errmsg . '"><div>' . $showdat . '</div></td>';
}
if ($bempty)
continue;
if (count($unqs) > 0) {
$unq = implode('|', $unqs);
if (in_array($unq, $uniques))
$firsthtml = '<td style="background:#ffe8c5;" title="#' . $lineidx . ':该行与待导入数据有重复"><div data-lang>重复</div></td>';
else {
$uniques[] = $unq;
$csql->column('id');
$chkid = toint($db->get1($csql));
if ($chkid > 0 && (($id > 0 && $chkid != $id) || $id == 0))
$firsthtml = '<td style="background:#ffe8c5;" title="#' . $lineidx . ':该行与数据库数据有重复"><div data-lang>重复</div></td>';
}
}
$html .= '<tr>' . $firsthtml . $hrhtml . '</tr>';
$cnt++;
}
$html .= '</tbody></table></div>';
$html .= '<input type="hidden" name="total" value="' . $cnt . '"/>';
$html .= '<code>共' . $cnt . '条数据</code>';
return succjson(array('html' => $html, 'count' => $cnt));
}
public static function json_importxls_data()
{
global $db;
$rsuser = verifyfast();
//if (nopower($db, $rsuser['id'], 'p i'))
// return errjson('您未被授权操作');
$post = new \ciy\post();
//$db->trace($post->get('_pf'), $rsuser);
$total = $post->getint('total');
try {
$db->begin();
for ($i = 1; $i <= $total; $i++) {
$id = $post->getint('id_' . $i);
$updata = array();
$updata['cateid'] = $post->get('cateid_' . $i);
$updata['name'] = $post->get('name_' . $i);
$updata['usetime'] = $post->get('usetime_' . $i);
$csql = new \ciy\sql('www_keyword');
if ($id == 0) {
$updata['addtimes'] = tostamp();
if ($db->insert($csql, $updata) === false)
throw new \Exception('新增导入失败:' . $db->error);
} else {
$csql->where('id', $id);
if ($db->update($csql, $updata) === false)
throw new \Exception('更新导入失败:' . $db->error);
}
}
$db->commit();
} catch (\Exception $ex) {
$db->rollback();
savelogfile('err_db', $ex->getMessage());
return errjson($ex->getMessage());
}
return succjson();
}
// 后端批量导入接口
public static function json_BatchAdd()
{
global $db;
$rsuser = verifyfast();
$post = new \ciy\post();
$font_cateid = $post->getint('cateid');
$font_names = trim($post->get('names'));
$Array_name = explode("\n", $font_names);
try {
$db->begin();
foreach ($Array_name as $name) {
$name = trim($name);
if ($name === '') continue;
$csql = new \ciy\sql('www_keyword');
$csql->where('name', $name);
$isExist = $db->get1($csql);
if ($isExist === '') {
$insertData = [
'cateid' => $font_cateid,
'name' => $name,
'usetime' => 0,
'addtimes' => tostamp()
];
$csql_insert = new \ciy\sql('www_keyword');
$db->insert($csql_insert, $insertData);
}
}
$db->commit();
return succjson('批量添加成功');
// return succjson([
// 'data'=> $font_names,
// 'cateid'=>$font_cateid
// ]);
} catch (\Exception $ex) {
$db->rollback();
return errjson('错误:' . $ex->getMessage());
}
}
// 交叉生成关键词
public static function json_GenerateKeywords()
{
global $db;
$rsuser = verifyfast();
$post = new \ciy\post();
$cateid = $post->getint('cateid');
$dim1 = trim($post->get('dim1'));
$dim2 = trim($post->get('dim2'));
$dim3 = trim($post->get('dim3'));
if ($cateid == 0) {
return errjson('请选择所属栏目');
}
if (empty($dim2)) {
return errjson('核心词不能为空');
}
$toArray = function ($text) {
$arr = explode("\n", $text);
$arr = array_map('trim', $arr);
$arr = array_filter($arr);
return array_unique($arr);
};
$arr1 = $toArray($dim1);
$arr2 = $toArray($dim2);
$arr3 = $toArray($dim3);
$keywords = [];
if (!empty($arr3) && !empty($arr1)) {
foreach ($arr1 as $a) {
foreach ($arr2 as $b) {
foreach ($arr3 as $c) {
$keywords[] = $a . $b . $c;
}
}
}
} else {
foreach ($arr2 as $b) {
$keywords[] = $b;
}
}
$keywords = array_unique($keywords);
if (empty($keywords)) {
return errjson('未生成有效关键词');
}
// 返回数组给前端编辑
return succjson([
'list' => $keywords
]);
}
// 确认后入库
public static function json_ConfirmSaveKeywords()
{
global $db;
$rsuser = verifyfast();
$post = new \ciy\post();
$cateid = $post->getint('cateid');
$text = trim($post->get('text'));
clog($text);
if (empty($cateid) || empty($text)) {
return errjson('请填写相应的信息');
}
$lines = explode("\n", $text);
$lines = array_map('trim', $lines);
$lines = array_filter($lines);
$lines = array_unique($lines);
$addNum = 0;
try {
$db->begin();
foreach ($lines as $name) {
$sql = new \ciy\sql('www_keyword');
$sql->where('name', $name);
if ($db->get1($sql)) continue;
$ins = [
'cateid' => $cateid,
'name' => $name,
'usetime' => 0,
'addtimes' => tostamp()
];
$db->insert(new \ciy\sql('www_keyword'), $ins);
$addNum++;
}
$db->commit();
return succjson(['msg' => "保存完成,新增 {$addNum}"]);
} catch (\Exception $e) {
$db->rollback();
return errjson($e->getMessage());
}
}
//AI相关功能
public static function json_AIFunction()
{
global $db;
$rsuser = verifyfast();
$post = new \ciy\post();
$function_type = trim($post->get('param'));
// AI配置
$aiConfig = [
'baseurl' => 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'aikey' => 'sk-0cd7b8c72ae04d049306e345f17c6790',
'model' => 'qwen-turbo',
'maxtoken' => 2000
];
try {
$openai = new \ciy\openai($aiConfig);
// 角色定位
if ($function_type === '修改') {
$content = trim($post->get('content'));
if (empty($content)) {
return errjson('请先等待生成关键词后再操作');
}
$system = '你是SEO关键词清洗优化助手严格遵守
1. 核心词绝对不能修改、删除、替换;
2. 只剔除不通顺、重复、无意义、垃圾关键词;
3. 可优化前后修饰词,不改变核心;
4. 输出严格一行一个,无解释、无符号、无序号;
5. 只净化,不新增。';
$prompt = "请清洗优化以下关键词:\n{$content}";
} else {
$cateid = trim($post->get('cateid'));
$dim1 = trim($post->get('dim1'));
$new_dim1 = empty($dim1) ? "自行补充,与核心词高度关联" : $dim1;
$dim2 = trim($post->get('dim2'));
$core_words = explode("\n", $dim2);
$core_words = array_filter(array_map('trim', $core_words));
$filter_str = implode('、', $core_words);
$dim3 = trim($post->get('dim3'));
$new_dim3 = empty($dim3) ? "自行补充,与核心词高度关联" : $dim3;;
if (empty($cateid)) {
return errjson('请选择所属栏目');
}
if(empty($dim2)){
return errjson('请填写核心关键词');
}
// AI 联想
$system = '你是专业的SEO关键词生成助手严格遵守
1. 核心词绝对不变;
2. 根据核心词自动生成合理的前缀词+核心词+后缀词组合的关键词;
3. 剔除不通顺、重复、无意义内容;
4. 输出一行一个,无多余内容;
5. 生成数量 7-12 个。';
$prompt = "前缀词: . {$new_dim1} . 核心词:.{$filter_str}.后缀词:.{$new_dim3} . 请根据提供的前缀词、核心词、后缀词生成生成优质关键词";}
$openai->newsystem($system);
$res = $openai->completion($prompt);
if (is_array($res) && !empty($res['content'])) {
return succjson(['data' => trim($res['content'])]);
} else {
return errjson('AI处理失败' . $res);
}
} catch (\Exception $e) {
return errjson('接口异常:' . $e->getMessage());
}
}
}