调整关键词管理布局,实现AI剔除和联想功能
This commit is contained in:
parent
368377f949
commit
de679172ea
|
|
@ -33,20 +33,27 @@
|
||||||
<div style="margin-top:12px;text-align:right;margin-top:12px;">
|
<div style="margin-top:12px;text-align:right;margin-top:12px;">
|
||||||
<button class="btn lg" onclick="GenerateKeywords()">交叉生成预览</button>
|
<button class="btn lg" onclick="GenerateKeywords()">交叉生成预览</button>
|
||||||
<button class="btn lg" onclick="BatchAdd()" style="margin-left:8px;">批量添加</button>
|
<button class="btn lg" onclick="BatchAdd()" style="margin-left:8px;">批量添加</button>
|
||||||
<button class="btn lg" onclick="AIGenerateKeyWord()" style="margin-left:8px;">AI联想</button>
|
<button class="btn lg" onclick="AIFunction('联想')" style="margin-left:8px;">AI联想</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 可编辑预览区域 -->
|
<!-- 可编辑预览区域 -->
|
||||||
<div id="editBox" style="display:none;border:1px solid #eee;padding:15px;border-radius:6px;margin:10px 0;">
|
<div id="editBox" style="display:none;border:1px solid #eee;padding:15px;border-radius:6px;margin:10px 0;">
|
||||||
<h4>预览生成关键词</h4>
|
<h4>预览交叉生成关键词</h4>
|
||||||
<textarea id="editKeywordText" style="width:100px;width:100%;height:260px;padding:10px;margin:10px 0;resize:vertical;"></textarea>
|
<textarea id="editKeywordText" style="width:100px;width:100%;height:260px;padding:10px;margin:10px 0;resize:vertical;"></textarea>
|
||||||
<div style="text-align:right;">
|
<div style="text-align:right;">
|
||||||
<button class="btn lg" onclick="AIModify()">AI修改</button>
|
<button class="btn lg" onclick="AIFunction('修改')">AI修改</button>
|
||||||
<button class="btn lg" onclick="saveEditKeywords()">确认保存入库</button>
|
<button class="btn lg" onclick="saveEditKeywords()">确认保存入库</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="AI_editBox" style="display:none;border:1px solid #eee;padding:15px;border-radius:6px;margin:10px 0;">
|
||||||
|
<h4>预览AI联想生成关键词</h4>
|
||||||
|
<textarea id="AI_editKeywordText" style="width:100px;width:100%;height:260px;padding:10px;margin:10px 0;resize:vertical;"></textarea>
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<button class="btn lg" onclick="saveEditKeywords()">确认保存入库</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="table" style="display:none !important; height:0; overflow:hidden;">
|
<div class="table" style="display:none !important; height:0; overflow:hidden;">
|
||||||
<div class="loading">Loading...</div>
|
<div class="loading">Loading...</div>
|
||||||
<div class="list"></div>
|
<div class="list"></div>
|
||||||
|
|
@ -120,26 +127,40 @@
|
||||||
|
|
||||||
// 保存编辑后的关键词入库
|
// 保存编辑后的关键词入库
|
||||||
function saveEditKeywords(){
|
function saveEditKeywords(){
|
||||||
let text = $5('[id=editKeywordText]').val().trim();
|
let text = '';
|
||||||
|
var aiBox = document.getElementById('AI_editBox');
|
||||||
|
var editBox = document.getElementById('editBox');
|
||||||
|
var currentCateid = $5('[id=cross_cateid_select]').val().trim();
|
||||||
|
if(aiBox.style.display !== 'none'){
|
||||||
|
text = document.getElementById('AI_editKeywordText').value.trim();
|
||||||
|
console.log("AI:"+text);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
text = document.getElementById('editKeywordText').value.trim();
|
||||||
|
console.log("normal:"+text);
|
||||||
|
}
|
||||||
|
|
||||||
if(!text){
|
if(!text){
|
||||||
ciyfn.toast('没有需要保存的关键词');
|
ciyfn.toast('没有需要保存的关键词');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ciyfn.callfunc('ConfirmSaveKeywords',{
|
ciyfn.callfunc('ConfirmSaveKeywords',{
|
||||||
cateid:currentCateid,
|
cateid: currentCateid,
|
||||||
text:text
|
text: text
|
||||||
},function(res){
|
},function(res){
|
||||||
if(res.code === 1){
|
if(res.code === 1){
|
||||||
ciyfn.toast(res.msg);
|
ciyfn.toast(res.msg);
|
||||||
$5('[id=editBox]').hide();
|
editBox.style.display = 'none';
|
||||||
$5('[id=editKeywordText]').val('');
|
aiBox.style.display = 'none';
|
||||||
|
document.getElementById('editKeywordText').value = '';
|
||||||
|
document.getElementById('AI_editKeywordText').value = '';
|
||||||
}else{
|
}else{
|
||||||
ciyfn.toast(res.errmsg);
|
ciyfn.toast(res.errmsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 原有批量添加不变
|
//批量添加不变
|
||||||
function BatchAdd() {
|
function BatchAdd() {
|
||||||
var cateid = $5('[id=cross_cateid_select]').val();
|
var cateid = $5('[id=cross_cateid_select]').val();
|
||||||
var names = $5('[name=cross_dim2]').val().trim();
|
var names = $5('[name=cross_dim2]').val().trim();
|
||||||
|
|
@ -164,6 +185,66 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
//AI相关功能
|
||||||
|
function AIFunction(param) {
|
||||||
|
let text = '';
|
||||||
|
if(param === '修改'){
|
||||||
|
text = $5('[id=editKeywordText]').val().trim();
|
||||||
|
if (!text) {
|
||||||
|
ciyfn.toast('请先生成关键词再使用AI修改');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ciyfn.toast('AI正在处理中...', 9999);
|
||||||
|
ciyfn.callfunc('AIFunction', {
|
||||||
|
content: text,
|
||||||
|
param: param
|
||||||
|
}, function (res) {
|
||||||
|
if (res.code === 1) {
|
||||||
|
$5('[id=editKeywordText]').val(res.data);
|
||||||
|
$5('[id=editBox]').show();
|
||||||
|
$5('[id=AI_editBox]').hide();
|
||||||
|
ciyfn.toast('AI ' + param + ' 完成');
|
||||||
|
} else {
|
||||||
|
ciyfn.toast('AI ' + param + ' 失败:' + res.errmsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
var cateid = $5('[id=cross_cateid_select]').val();
|
||||||
|
var dim1 = $5('[name=cross_dim1]').val().trim();
|
||||||
|
var dim2 = $5('[name=cross_dim2]').val().trim();
|
||||||
|
var dim3 = $5('[name=cross_dim3]').val().trim();
|
||||||
|
if(!cateid){
|
||||||
|
ciyfn.toast('请选择所属栏目');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dim2) {
|
||||||
|
ciyfn.toast('请填写核心词');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ciyfn.toast('AI联想中...', 9999);
|
||||||
|
ciyfn.callfunc('AIFunction', {
|
||||||
|
cateid: cateid,
|
||||||
|
dim1: dim1,
|
||||||
|
dim2: dim2,
|
||||||
|
dim3: dim3,
|
||||||
|
param: param
|
||||||
|
}, function (res) {
|
||||||
|
if (res.code === 1) {
|
||||||
|
$5('[id=AI_editKeywordText]').val(res.data);
|
||||||
|
$5('[id=AI_editBox]').show();
|
||||||
|
$5('[id=editBox]').hide();
|
||||||
|
ciyfn.toast('AI ' + param + ' 完成');
|
||||||
|
} else {
|
||||||
|
ciyfn.toast('AI ' + param + ' 失败:' + res.errmsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -390,111 +390,111 @@ class keywordManage
|
||||||
}
|
}
|
||||||
|
|
||||||
// 后端批量导入接口
|
// 后端批量导入接口
|
||||||
public static function json_BatchAdd()
|
public static function json_BatchAdd()
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
$rsuser = verifyfast();
|
$rsuser = verifyfast();
|
||||||
$post = new \ciy\post();
|
$post = new \ciy\post();
|
||||||
|
|
||||||
$font_cateid = $post->getint('cateid');
|
$font_cateid = $post->getint('cateid');
|
||||||
$font_names = trim($post->get('names'));
|
$font_names = trim($post->get('names'));
|
||||||
|
|
||||||
$Array_name = explode("\n", $font_names);
|
$Array_name = explode("\n", $font_names);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$db->begin();
|
$db->begin();
|
||||||
|
|
||||||
foreach ($Array_name as $name) {
|
foreach ($Array_name as $name) {
|
||||||
$name = trim($name);
|
$name = trim($name);
|
||||||
if ($name === '') continue;
|
if ($name === '') continue;
|
||||||
|
|
||||||
$csql = new \ciy\sql('www_keyword');
|
$csql = new \ciy\sql('www_keyword');
|
||||||
$csql->where('name', $name);
|
$csql->where('name', $name);
|
||||||
$isExist = $db->get1($csql);
|
$isExist = $db->get1($csql);
|
||||||
|
|
||||||
if ($isExist === '') {
|
if ($isExist === '') {
|
||||||
$insertData = [
|
$insertData = [
|
||||||
'cateid' => $font_cateid,
|
'cateid' => $font_cateid,
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'usetime' => 0,
|
'usetime' => 0,
|
||||||
'addtimes' => tostamp()
|
'addtimes' => tostamp()
|
||||||
];
|
];
|
||||||
|
|
||||||
$csql_insert = new \ciy\sql('www_keyword');
|
$csql_insert = new \ciy\sql('www_keyword');
|
||||||
$db->insert($csql_insert, $insertData);
|
$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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
return succjson('批量添加成功');
|
||||||
|
// return succjson([
|
||||||
|
// 'data'=> $font_names,
|
||||||
|
// 'cateid'=>$font_cateid
|
||||||
|
// ]);
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
$db->rollback();
|
||||||
|
return errjson('错误:' . $ex->getMessage());
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
foreach ($arr2 as $b) {
|
|
||||||
$keywords[] = $b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$keywords = array_unique($keywords);
|
// 交叉生成关键词
|
||||||
if (empty($keywords)) {
|
public static function json_GenerateKeywords()
|
||||||
return errjson('未生成有效关键词');
|
{
|
||||||
|
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
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回数组给前端编辑
|
// 确认后入库
|
||||||
return succjson([
|
public static function json_ConfirmSaveKeywords()
|
||||||
'list' => $keywords
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认后入库
|
|
||||||
public static function json_ConfirmSaveKeywords()
|
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
$rsuser = verifyfast();
|
$rsuser = verifyfast();
|
||||||
|
|
@ -502,7 +502,7 @@ public static function json_ConfirmSaveKeywords()
|
||||||
|
|
||||||
$cateid = $post->getint('cateid');
|
$cateid = $post->getint('cateid');
|
||||||
$text = trim($post->get('text'));
|
$text = trim($post->get('text'));
|
||||||
|
clog($text);
|
||||||
if (empty($cateid) || empty($text)) {
|
if (empty($cateid) || empty($text)) {
|
||||||
return errjson('请填写相应的信息');
|
return errjson('请填写相应的信息');
|
||||||
}
|
}
|
||||||
|
|
@ -536,4 +536,77 @@ public static function json_ConfirmSaveKeywords()
|
||||||
return errjson($e->getMessage());
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user