Browse Source

更新内容

tags/6.5.2
tianya 6 days ago
parent
commit
0449ba1845
7 changed files with 176 additions and 186 deletions
  1. +174
    -179
      src/admin/ai_dialog.php
  2. +0
    -1
      src/admin/api.php
  3. +0
    -1
      src/admin/sys_sql_query.php
  4. +1
    -1
      src/install/sql-dfdata.txt
  5. +1
    -1
      src/install/update.txt
  6. +0
    -2
      src/static/ckeditor/plugins/dedebizai/plugin.js
  7. +0
    -1
      src/user/api.php

+ 174
- 179
src/admin/ai_dialog.php View File

@@ -1,6 +1,6 @@
<?php
/**
* 富文本AI对话框
* 小德AI助手对话框
*
* @version $id:ai_dialog.php 2025 tianya $
* @package DedeBIZ.Dialog
@@ -9,7 +9,6 @@
* @link https://www.dedebiz.com
*/
require_once(dirname(__FILE__) . "/config.php");

if (empty($f)) {
$f = 'form1.enclosure';
}
@@ -29,202 +28,198 @@ if (!empty($noeditor)) {
?>
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>AI提示词对话框</title>
<link rel="stylesheet" href="/static/web/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/web/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/web/css/admin.css">
<script src="/static/web/js/jquery.min.js"></script>
<script src="/static/web/js/bootstrap.min.js"></script>
<script src="/static/web/js/admin.main.js"></script>
</head>

<body class="p-3">
<div class="card shadow-sm">
<div class="card-header">小德AI助手:内容处理</div>
<div class="card-body">
<div class="form-group">
<div class="alert alert-warning mb-0" role="alert">
<span>处理过程中请勿关闭当前对话框,否则富文本处理将终止</span>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<title>小德AI助手对话框</title>
<link rel="stylesheet" href="/static/web/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/web/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/web/css/admin.css">
<script src="/static/web/js/jquery.min.js"></script>
<script src="/static/web/js/bootstrap.min.js"></script>
<script src="/static/web/js/admin.main.js"></script>
</head>
<body class="p-3">
<div class="card shadow-sm">
<div class="card-header">小德AI助手:内容处理</div>
<div class="card-body">
<div class="form-group">
<div class="alert alert-warning mb-0" role="alert">
<span>处理过程中请勿关闭当前对话框,否则富文本处理将终止</span>
</div>
</div>
<div class="form-group">
<textarea id="prompt" class="form-control" style="height:160px" placeholder="请输入内容处理要求,例如:我需要将内容润色下,希望更专业"></textarea>
</div>
<div class="form-group">
<label for="modelid" class="form-label">选择模型</label>
<select id="modelid" class="form-control">
<?php
$dsql->SetQuery("SELECT AM.*,A.title as aititle FROM `#@__ai_model` AM LEFT JOIN `#@__ai` A ON A.id = AM.aiid ORDER BY AM.sortrank ASC,AM.id DESC");
$dsql->Execute();
while ($row = $dsql->GetObject()) {
?>
<option value="<?php echo $row->id; ?>" <?php echo $row->isdefault == 1 ? ' selected' : ''; ?>><?php echo $row->model; ?> <?php echo $row->aititle; ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<button type="button" id="btnAIAction" class="btn btn-success btn-sm">确定</button>
</div>
</div>
<div class="form-group">
<textarea id="prompt" class="form-control" style="height:160px" placeholder="请输入内容处理要求,例如:我需要将内容润色下,希望更专业"></textarea>
</div>
<div class="form-group">
<label for="modelid" class="form-label">选择模型</label>
<select id="modelid" class="form-control">
<?php
$dsql->SetQuery("SELECT AM.*,A.title as aititle FROM `#@__ai_model` AM LEFT JOIN `#@__ai` A ON A.id = AM.aiid ORDER BY AM.sortrank ASC,AM.id DESC");
$dsql->Execute();
while ($row = $dsql->GetObject()) {
?>
<option value="<?php echo $row->id; ?>" <?php echo $row->isdefault == 1 ? ' selected' : ''; ?>><?php echo $row->model; ?> <?php echo $row->aititle; ?></option>
<?php
}
?>
</select>
</div>
<div class="form-group">
<button type="button" id="btnAIAction" class="btn btn-success btn-sm">确定</button>
</div>
</div>
</div>
<script>
$("#btnAIAction").click(async function() {
let body = window.opener.CKEDITOR.instances["<?php echo $f ?>"].getData();
let prompt = document.getElementById("prompt").value;
let modelid = document.getElementById("modelid").value;
let req = await fetch(`api.php?action=get_ai_server&pname=body_edit&modelid=${modelid}&prompt=${prompt}`);
let resp = await req.json();
if (resp.code !== 0) {
ShowMsg("获取服务器地址失败");
return
}

let req2 = await fetch(`api.php?action=get_setbody_url`);
let resp2 = await req2.json();
if (resp2.code !== 0) {
ShowMsg("获取服务器地址失败");
return
}
let req3 = await fetch(resp2.data, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
body: body
})
});
let resp3 = await req3.json();
if (resp3.code !== 0) {
ShowMsg("提交原始内容失败");
return
}
let eventSource = new EventSource(resp.data);
//新增状态跟踪变量
let currentKey = null;
let tagBuffer = "";
let isClosingTag = false;
$("#mdlAI").modal('hide');
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').disable();
$("#btnAIAction").attr("disabled", "disabled");
$("#prompt").attr("disabled", "disabled");
$("#modelid").attr("disabled", "disabled");
prompt = "";
let bodyHtml = "";
let lastChar = "";
eventSource.onmessage = (event) => {
const chars = event.data.split('');
chars.forEach(char => {
if (lastChar === '\\' && char === 'r') {
char = '<br>'; //替换为br标签
lastChar = ""; //清空追踪字符
} else {
lastChar = char; //记录当前字符
}
if (char === '\\') {
return; //如果是反斜杠,跳过处理
}
if (currentKey) {
if (char === '{') {
isClosingTag = true;
tagBuffer = '{';
return;
<script>
$("#btnAIAction").click(async function() {
let body = window.opener.CKEDITOR.instances["<?php echo $f ?>"].getData();
let prompt = document.getElementById("prompt").value;
let modelid = document.getElementById("modelid").value;
let req = await fetch(`api.php?action=get_ai_server&pname=body_edit&modelid=${modelid}&prompt=${prompt}`);
let resp = await req.json();
if (resp.code !== 0) {
ShowMsg("获取服务器地址失败");
return
}
let req2 = await fetch(`api.php?action=get_setbody_url`);
let resp2 = await req2.json();
if (resp2.code !== 0) {
ShowMsg("获取服务器地址失败");
return
}
let req3 = await fetch(resp2.data, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
body: body
})
});
let resp3 = await req3.json();
if (resp3.code !== 0) {
ShowMsg("提交原始内容失败");
return
}
let eventSource = new EventSource(resp.data);
//新增状态跟踪变量
let currentKey = null;
let tagBuffer = "";
let isClosingTag = false;
$("#mdlAI").modal('hide');
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').disable();
$("#btnAIAction").attr("disabled", "disabled");
$("#prompt").attr("disabled", "disabled");
$("#modelid").attr("disabled", "disabled");
prompt = "";
let bodyHtml = "";
let lastChar = "";
eventSource.onmessage = (event) => {
const chars = event.data.split('');
chars.forEach(char => {
if (lastChar === '\\' && char === 'r') {
char = '<br>'; //替换为br标签
lastChar = ""; //清空追踪字符
} else {
lastChar = char; //记录当前字符
}
if (isClosingTag) {
tagBuffer += char;
if (tagBuffer === `{/${currentKey}}`) {
if (currentKey == "content") {
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
bodyHtml = "";
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) $(input).prop("disabled", false).removeClass("disabled"); //恢复输入状态
}
currentKey = null;
isClosingTag = false;
tagBuffer = "";
if (char === '\\') {
return; //如果是反斜杠,跳过处理
}
if (currentKey) {
if (char === '{') {
isClosingTag = true;
tagBuffer = '{';
return;
}
if (!`{/${currentKey}}`.startsWith(tagBuffer)) {
if (isClosingTag) {
tagBuffer += char;
if (tagBuffer === `{/${currentKey}}`) {
if (currentKey == "content") {
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
bodyHtml = "";
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) $(input).prop("disabled", false).removeClass("disabled"); //恢复输入状态
}
currentKey = null;
isClosingTag = false;
tagBuffer = "";
return;
}
if (!`{/${currentKey}}`.startsWith(tagBuffer)) {
if (currentKey == "content") {
bodyHtml += tagBuffer;
console.log(bodyHtml);
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) input.value += tagBuffer;
}
isClosingTag = false;
tagBuffer = "";
}
} else {
if (currentKey == "content") {
bodyHtml += tagBuffer;
console.log(bodyHtml);
bodyHtml += char;
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) input.value += tagBuffer;
if (input) {
input.value += char;
input.scrollTop = input.scrollHeight; //滚动到底部
}
}
isClosingTag = false;
tagBuffer = "";
}
} else {
if (currentKey == "content") {
bodyHtml += char;
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) {
input.value += char;
input.scrollTop = input.scrollHeight; //滚动到底部
}
}
}
} else {
if (char === '{') {
tagBuffer = '{';
} else if (tagBuffer.startsWith('{')) {
tagBuffer += char;
if (char === '}') {
const match = tagBuffer.match(/{([^>]+)}/);
if (match) {
currentKey = match[1];
if (currentKey == "content") {
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(true);
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) {
$(input).prop("disabled", true).addClass("disabled"); //仅禁用当前输入框
input.value = "";
if (char === '{') {
tagBuffer = '{';
} else if (tagBuffer.startsWith('{')) {
tagBuffer += char;
if (char === '}') {
const match = tagBuffer.match(/{([^>]+)}/);
if (match) {
currentKey = match[1];
if (currentKey == "content") {
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(true);
} else {
const input = document.querySelector(`[name="${currentKey}"]`);
if (input) {
$(input).prop("disabled", true).addClass("disabled"); //仅禁用当前输入框
input.value = "";
}
}
}
tagBuffer = "";
}
tagBuffer = "";
}
}
});
};
eventSource.onerror = (error) => {
if (error.target.readyState === EventSource.CONNECTING) {
ShowMsg("连接失败,请确保您已开启并正确配置了DedeBIZ小德AI助手。 <a class='text-success' href='https://www.dedebiz.com/ai?from=dedebiz' target='_blank'>如何配置?</a>");
} else if (typeof error.data !== "undefined" && error.data !== "" && error.target.readyState !== EventSource.CLOSED) {
ShowMsg(error.data);
}
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
$("#btnAI").prop("disabled", false);
$("#btnAIAction").prop("disabled", false);
$("#prompt").prop("disabled", false);
$("#modelid").prop("disabled", false);
eventSource.close();
};
//监听特定事件close
eventSource.addEventListener('close', (event) => {
console.log('SSE connection closed:', event.data);
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
$("#btnAIAction").prop("disabled", false);
$("#prompt").prop("disabled", false);
$("#modelid").prop("disabled", false);
eventSource.close(); //关闭连接
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
});
};
eventSource.onerror = (error) => {
if (error.target.readyState === EventSource.CONNECTING) {
ShowMsg("连接失败,请确保您已开启并正确配置了DedeBIZ小德AI助手。 <a class='text-success' href='https://www.dedebiz.com/ai?from=dedebiz' target='_blank'>如何配置?</a>");
} else if (typeof error.data !== "undefined" && error.data !== "" && error.target.readyState !== EventSource.CLOSED) {
ShowMsg(error.data);
}
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
$("#btnAI").prop("disabled", false);
$("#btnAIAction").prop("disabled", false);
$("#prompt").prop("disabled", false);
$("#modelid").prop("disabled", false);
eventSource.close();
};
//监听特定事件close
eventSource.addEventListener('close', (event) => {
console.log('SSE connection closed:', event.data);
window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
$("#btnAIAction").prop("disabled", false);
$("#prompt").prop("disabled", false);
$("#modelid").prop("disabled", false);
eventSource.close(); //关闭连接
window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
});
});
</script>
</body>

</script>
</body>
</html>

+ 0
- 1
src/admin/api.php View File

@@ -474,7 +474,6 @@ if ($action === 'is_need_check_code') {
$cuserLogin = new userLogin();
$params['adminid'] = $cuserLogin->getUserID(); // 加入时间戳
$params['ip'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; // 获取客户端IP

ksort($params); // 按字典序排序
$queryString = http_build_query($params); // 生成查询字符串
$params['sign'] = md5($queryString . $cfg_ai_apikey); // 计算MD5签名


+ 0
- 1
src/admin/sys_sql_query.php View File

@@ -88,7 +88,6 @@ else if ($dopost == "query") {
$mysqlVersions = explode('.',trim($row[0]));
$mysqlVersion = $mysqlVersions[0].".".$mysqlVersions[1];
$sqlquery = trim(stripslashes($sqlquery));

if (preg_match("#drop(.*)table#i", $sqlquery) || preg_match("#drop(.*)database#", $sqlquery)) {
echo "删除数据表或数据库的语句不允许在这里执行";
exit();


+ 1
- 1
src/install/sql-dfdata.txt View File

@@ -4113,4 +4113,4 @@ INSERT INTO `#@__sysconfig` (`varname`, `info`, `groupid`, `type`, `value`) VALU
INSERT INTO `#@__sysconfig` (`varname`, `info`, `groupid`, `type`, `value`) VALUES ('cfg_ai_top_p', '核采样(为空则采用模型默认值)', 8, 'string', '');
INSERT INTO `#@__sysconfig` (`varname`, `info`, `groupid`, `type`, `value`) VALUES ('cfg_ai_enabled', '是否开启智能助手', 8, 'bool', 'Y');
INSERT INTO `#@__ai_prompt` (`pname`, `title`, `issystem`, `description`, `info`, `prompt`, `dfprompt`) VALUES ('body_edit', '编辑器内容修改', 1, '富文本编辑器中内容修改', '系统提示词变量,不建议修改。需要助手1.0.3版本以上<hr>body:富文本内容', '用户将会提供内容修改要求,根据要求对下面的文章内容html内容进行处理,需要保障html的完整。\r\n\r\n文章内容:\r\n~body~\r\n\r\n参考输入 EXAMPLE INPUT:\r\n帮我加粗“穆云智能”\r\n\r\n参考格式返回 EXAMPLE OUTPUT:\r\n{content}<p>公司简介</p><p><strong>穆云智能</strong>科技是一家专注于人工智能技术研发与应用的高科技企业,致力于为各行业提供智能化解决方案,助力企业提升效率,推动数字化转型。公司业务涵盖计算机视觉、自然语言处理、机器学习等多个AI技术领域,并广泛应用于营销、制造、金融、医疗等行业。</p>{/content}', '我需要将内容润色下,希望更专业');
INSERT INTO `#@__ai_prompt` (`pname`, `title`, `issystem`, `description`, `info`, `prompt`, `dfprompt`) VALUES ('body_edit', '编辑器内容修改', 1, '富文本编辑器中内容修改', '系统提示词变量,不建议修改。需要助手1.0.3版本以上<hr>body:富文本内容', '用户将会提供内容修改要求,根据要求对下面的内容进行处理,需要保障html的完整。严格按照参考格式返回。\r\n\r\n内容:\r\n{content}~body~{/content}\r\n\r\n参考输入 EXAMPLE INPUT:\r\n帮我加粗“穆云智能”\r\n\r\n参考格式返回 EXAMPLE OUTPUT:\r\n{content}<p>公司简介</p><p><strong>穆云智能</strong>科技是一家专注于人工智能技术研发与应用的高科技企业,致力于为各行业提供智能化解决方案,助力企业提升效率,推动数字化转型。公司业务涵盖计算机视觉、自然语言处理、机器学习等多个AI技术领域,并广泛应用于营销、制造、金融、医疗等行业。</p>{/content}', '我需要将内容润色下,希望更专业');

+ 1
- 1
src/install/update.txt View File

@@ -223,5 +223,5 @@ CREATE TABLE `#@__tagindex_infos` (
) TYPE=MyISAM;

-- 6.5.2
INSERT INTO `#@__ai_prompt` (`pname`, `title`, `issystem`, `description`, `info`, `prompt`, `dfprompt`) VALUES ('body_edit', '编辑器内容修改', 1, '富文本编辑器中内容修改', '系统提示词变量,不建议修改。需要助手1.0.3版本以上<hr>body:富文本内容', '用户将会提供内容修改要求,根据要求对下面的文章内容html内容进行处理,需要保障html的完整。\r\n\r\n文章内容:\r\n~body~\r\n\r\n参考输入 EXAMPLE INPUT:\r\n帮我加粗“穆云智能”\r\n\r\n参考格式返回 EXAMPLE OUTPUT:\r\n{content}<p>公司简介</p><p><strong>穆云智能</strong>科技是一家专注于人工智能技术研发与应用的高科技企业,致力于为各行业提供智能化解决方案,助力企业提升效率,推动数字化转型。公司业务涵盖计算机视觉、自然语言处理、机器学习等多个AI技术领域,并广泛应用于营销、制造、金融、医疗等行业。</p>{/content}', '我需要将内容润色下,希望更专业');
INSERT INTO `#@__ai_prompt` (`pname`, `title`, `issystem`, `description`, `info`, `prompt`, `dfprompt`) VALUES ('body_edit', '编辑器内容修改', 1, '富文本编辑器中内容修改', '系统提示词变量,不建议修改。需要助手1.0.3版本以上<hr>body:富文本内容', '用户将会提供内容修改要求,根据要求对下面的内容进行处理,需要保障html的完整。严格按照参考格式返回。\r\n\r\n内容:\r\n{content}~body~{/content}\r\n\r\n参考输入 EXAMPLE INPUT:\r\n帮我加粗“穆云智能”\r\n\r\n参考格式返回 EXAMPLE OUTPUT:\r\n{content}<p>公司简介</p><p><strong>穆云智能</strong>科技是一家专注于人工智能技术研发与应用的高科技企业,致力于为各行业提供智能化解决方案,助力企业提升效率,推动数字化转型。公司业务涵盖计算机视觉、自然语言处理、机器学习等多个AI技术领域,并广泛应用于营销、制造、金融、医疗等行业。</p>{/content}', '我需要将内容润色下,希望更专业');
INSERT INTO `#@__flink` (`sortrank`, `url`, `webname`, `msg`, `email`, `logo`, `dtime`, `typeid`, `ischeck`) VALUES(4, 'https://www.dedebiz.com/ai', 'AI建站', '', '', '', 1742983936, 8, 2);

+ 0
- 2
src/static/ckeditor/plugins/dedebizai/plugin.js View File

@@ -8,10 +8,8 @@ CKEDITOR.plugins.add("dedebizai", {
var h = 600;
var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
var dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
var systemZoom = width / window.screen.availWidth;
var posLeft = (width - w) / 2 / systemZoom + dualScreenLeft;
var posTop = (height - h) / 2 / systemZoom + dualScreenTop;


+ 0
- 1
src/user/api.php View File

@@ -201,7 +201,6 @@ if ($action === 'is_need_check_code') {
$dsql->ExecuteNoneQuery($inquery);
}
}
if (move_uploaded_file($ff["tmp_name"], $target_file)) {
if ($mediatype === 1) {
//图片自动裁剪


Loading…
Cancel
Save