Compare commits

...

2 Commits

2 changed files with 256 additions and 102 deletions

View File

@ -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>

View File

@ -389,111 +389,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();
@ -501,7 +501,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('请填写相应的信息');
} }
@ -535,4 +535,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());
}
}
} }