mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 03:01:12 +00:00
no message
- 添加AI助手流式会话凭证生成方法 - 优化AI助手模型获取逻辑 - 更新相关接口调用
This commit is contained in:
parent
7a6bbfac75
commit
f6e4ed7c60
@ -3,8 +3,9 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Module\AI;
|
||||||
|
use App\Module\Apps;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Ihttp;
|
|
||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,6 +15,11 @@ use Request;
|
|||||||
*/
|
*/
|
||||||
class AssistantController extends AbstractController
|
class AssistantController extends AbstractController
|
||||||
{
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Apps::isInstalledThrow('ai');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/assistant/auth 生成授权码
|
* @api {post} api/assistant/auth 生成授权码
|
||||||
*
|
*
|
||||||
@ -40,104 +46,28 @@ class AssistantController extends AbstractController
|
|||||||
$modelName = trim(Request::input('model_name', ''));
|
$modelName = trim(Request::input('model_name', ''));
|
||||||
$contextInput = Request::input('context', []);
|
$contextInput = Request::input('context', []);
|
||||||
|
|
||||||
if ($modelType === '' || $modelName === '') {
|
return AI::createStreamKey($modelType, $modelName, $contextInput);
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_string($contextInput)) {
|
|
||||||
$decoded = json_decode($contextInput, true);
|
|
||||||
if (json_last_error() === JSON_ERROR_NONE) {
|
|
||||||
$contextInput = $decoded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_array($contextInput)) {
|
|
||||||
return Base::retError('context 参数格式错误');
|
|
||||||
}
|
|
||||||
|
|
||||||
$context = [];
|
|
||||||
foreach ($contextInput as $item) {
|
|
||||||
if (!is_array($item) || count($item) < 2) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$role = trim((string)($item[0] ?? ''));
|
|
||||||
$message = trim((string)($item[1] ?? ''));
|
|
||||||
if ($role === '' || $message === '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$context[] = [$role, $message];
|
|
||||||
}
|
|
||||||
|
|
||||||
$contextJson = json_encode($context, JSON_UNESCAPED_UNICODE);
|
|
||||||
if ($contextJson === false) {
|
|
||||||
return Base::retError('context 参数格式错误');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/assistant/models 获取AI模型
|
||||||
|
*
|
||||||
|
* @apiDescription 获取所有AI机器人模型设置
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup assistant
|
||||||
|
* @apiName models
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function models()
|
||||||
|
{
|
||||||
$setting = Base::setting('aibotSetting');
|
$setting = Base::setting('aibotSetting');
|
||||||
$apiKey = Base::val($setting, $modelType . '_key');
|
$setting = array_filter($setting, function ($value, $key) {
|
||||||
if ($modelType === 'wenxin') {
|
return str_ends_with($key, '_models') || str_ends_with($key, '_model');
|
||||||
$wenxinSecret = Base::val($setting, 'wenxin_secret');
|
}, ARRAY_FILTER_USE_BOTH);
|
||||||
if ($wenxinSecret) {
|
|
||||||
$apiKey = trim(($apiKey ?: '') . ':' . $wenxinSecret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($modelType === 'ollama' && empty($apiKey)) {
|
|
||||||
$apiKey = Base::strRandom(6);
|
|
||||||
}
|
|
||||||
if (empty($apiKey)) {
|
|
||||||
return Base::retError('模型未启用');
|
|
||||||
}
|
|
||||||
|
|
||||||
$remoteModelType = match ($modelType) {
|
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
||||||
'qianwen' => 'qwen',
|
|
||||||
default => $modelType,
|
|
||||||
};
|
|
||||||
|
|
||||||
$authParams = [
|
|
||||||
'api_key' => $apiKey,
|
|
||||||
'model_type' => $remoteModelType,
|
|
||||||
'model_name' => $modelName,
|
|
||||||
'context' => $contextJson,
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($setting[$modelType . '_base_url']) {
|
|
||||||
$authParams['base_url'] = $setting[$modelType . '_base_url'];
|
|
||||||
}
|
|
||||||
if ($setting[$modelType . '_agency']) {
|
|
||||||
$authParams['agency'] = $setting[$modelType . '_agency'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$thinkPatterns = [
|
|
||||||
"/^(.+?)(\s+|\s*[_-]\s*)(think|thinking|reasoning)\s*$/",
|
|
||||||
"/^(.+?)\s*\(\s*(think|thinking|reasoning)\s*\)\s*$/"
|
|
||||||
];
|
|
||||||
$thinkMatch = [];
|
|
||||||
foreach ($thinkPatterns as $pattern) {
|
|
||||||
if (preg_match($pattern, $authParams['model_name'], $thinkMatch)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($thinkMatch && !empty($thinkMatch[1])) {
|
|
||||||
$authParams['model_name'] = $thinkMatch[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
$authResult = Ihttp::ihttp_post('http://nginx/ai/invoke/auth', $authParams, 30);
|
|
||||||
|
|
||||||
if (Base::isError($authResult)) {
|
|
||||||
return Base::retError($authResult['msg']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$body = Base::json2array($authResult['data']);
|
|
||||||
if ($body['code'] !== 200) {
|
|
||||||
return Base::retError($body['error'] ?: 'AI 接口返回异常', $body);
|
|
||||||
}
|
|
||||||
|
|
||||||
$streamKey = Base::val($body, 'data.stream_key');
|
|
||||||
if (empty($streamKey)) {
|
|
||||||
return Base::retError('AI 接口返回数据异常');
|
|
||||||
}
|
|
||||||
|
|
||||||
return Base::retSuccess('success', [
|
|
||||||
'stream_key' => $streamKey,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -333,27 +333,6 @@ class SystemController extends AbstractController
|
|||||||
return Base::retSuccess($type == 'save' ? '保存成功' : 'success', $setting ?: json_decode('{}'));
|
return Base::retSuccess($type == 'save' ? '保存成功' : 'success', $setting ?: json_decode('{}'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/system/setting/aibot_models 获取AI模型
|
|
||||||
*
|
|
||||||
* @apiDescription 获取所有AI机器人模型设置
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup system
|
|
||||||
* @apiName aibot_models
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function setting__aibot_models()
|
|
||||||
{
|
|
||||||
$setting = Base::setting('aibotSetting');
|
|
||||||
$setting = array_filter($setting, function($value, $key) {
|
|
||||||
return str_ends_with($key, '_models') || str_ends_with($key, '_model');
|
|
||||||
}, ARRAY_FILTER_USE_BOTH);
|
|
||||||
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/setting/checkin 获取签到设置、保存签到设置(限管理员)
|
* @api {get} api/system/setting/checkin 获取签到设置、保存签到设置(限管理员)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -132,6 +132,126 @@ class AI
|
|||||||
return Base::retSuccess("success", $result);
|
return Base::retSuccess("success", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 AI 流式会话凭证
|
||||||
|
* @param string $modelType
|
||||||
|
* @param string $modelName
|
||||||
|
* @param mixed $contextInput
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function createStreamKey($modelType, $modelName, $contextInput = [])
|
||||||
|
{
|
||||||
|
$modelType = trim((string)$modelType);
|
||||||
|
$modelName = trim((string)$modelName);
|
||||||
|
|
||||||
|
if ($modelType === '' || $modelName === '') {
|
||||||
|
return Base::retError('参数错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($contextInput)) {
|
||||||
|
$decoded = json_decode($contextInput, true);
|
||||||
|
if (json_last_error() === JSON_ERROR_NONE) {
|
||||||
|
$contextInput = $decoded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($contextInput)) {
|
||||||
|
return Base::retError('context 参数格式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$context = [];
|
||||||
|
foreach ($contextInput as $item) {
|
||||||
|
if (!is_array($item) || count($item) < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$role = trim((string)($item[0] ?? ''));
|
||||||
|
$message = trim((string)($item[1] ?? ''));
|
||||||
|
if ($role === '' || $message === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$context[] = [$role, $message];
|
||||||
|
}
|
||||||
|
|
||||||
|
$contextJson = json_encode($context, JSON_UNESCAPED_UNICODE);
|
||||||
|
if ($contextJson === false) {
|
||||||
|
return Base::retError('context 参数格式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
$setting = Base::setting('aibotSetting');
|
||||||
|
if (!is_array($setting)) {
|
||||||
|
$setting = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiKey = Base::val($setting, $modelType . '_key');
|
||||||
|
if ($modelType === 'wenxin') {
|
||||||
|
$wenxinSecret = Base::val($setting, 'wenxin_secret');
|
||||||
|
if ($wenxinSecret) {
|
||||||
|
$apiKey = trim(($apiKey ?: '') . ':' . $wenxinSecret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($modelType === 'ollama' && empty($apiKey)) {
|
||||||
|
$apiKey = Base::strRandom(6);
|
||||||
|
}
|
||||||
|
if (empty($apiKey)) {
|
||||||
|
return Base::retError('模型未启用');
|
||||||
|
}
|
||||||
|
|
||||||
|
$remoteModelType = match ($modelType) {
|
||||||
|
'qianwen' => 'qwen',
|
||||||
|
default => $modelType,
|
||||||
|
};
|
||||||
|
|
||||||
|
$authParams = [
|
||||||
|
'api_key' => $apiKey,
|
||||||
|
'model_type' => $remoteModelType,
|
||||||
|
'model_name' => $modelName,
|
||||||
|
'context' => $contextJson,
|
||||||
|
];
|
||||||
|
|
||||||
|
$baseUrl = trim((string)($setting[$modelType . '_base_url'] ?? ''));
|
||||||
|
if ($baseUrl !== '') {
|
||||||
|
$authParams['base_url'] = $baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
$agency = trim((string)($setting[$modelType . '_agency'] ?? ''));
|
||||||
|
if ($agency !== '') {
|
||||||
|
$authParams['agency'] = $agency;
|
||||||
|
}
|
||||||
|
|
||||||
|
$thinkPatterns = [
|
||||||
|
"/^(.+?)(\s+|\s*[_-]\s*)(think|thinking|reasoning)\s*$/",
|
||||||
|
"/^(.+?)\s*\(\s*(think|thinking|reasoning)\s*\)\s*$/"
|
||||||
|
];
|
||||||
|
$thinkMatch = [];
|
||||||
|
foreach ($thinkPatterns as $pattern) {
|
||||||
|
if (preg_match($pattern, $authParams['model_name'], $thinkMatch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($thinkMatch && !empty($thinkMatch[1])) {
|
||||||
|
$authParams['model_name'] = $thinkMatch[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$authResult = Ihttp::ihttp_post('http://nginx/ai/invoke/auth', $authParams, 30);
|
||||||
|
if (Base::isError($authResult)) {
|
||||||
|
return Base::retError($authResult['msg']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = Base::json2array($authResult['data']);
|
||||||
|
if (($body['code'] ?? null) !== 200) {
|
||||||
|
return Base::retError(($body['error'] ?? '') ?: 'AI 接口返回异常', $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
$streamKey = Base::val($body, 'data.stream_key');
|
||||||
|
if (empty($streamKey)) {
|
||||||
|
return Base::retError('AI 接口返回数据异常');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base::retSuccess('success', [
|
||||||
|
'stream_key' => $streamKey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/** ******************************************************************************************** */
|
/** ******************************************************************************************** */
|
||||||
/** ******************************************************************************************** */
|
/** ******************************************************************************************** */
|
||||||
/** ******************************************************************************************** */
|
/** ******************************************************************************************** */
|
||||||
@ -146,6 +266,8 @@ class AI
|
|||||||
*/
|
*/
|
||||||
public static function transcriptions($filePath, $extParams = [], $extHeaders = [], $noCache = false)
|
public static function transcriptions($filePath, $extParams = [], $extHeaders = [], $noCache = false)
|
||||||
{
|
{
|
||||||
|
Apps::isInstalledThrow('ai');
|
||||||
|
|
||||||
if (!file_exists($filePath)) {
|
if (!file_exists($filePath)) {
|
||||||
return Base::retError("语音文件不存在");
|
return Base::retError("语音文件不存在");
|
||||||
}
|
}
|
||||||
@ -202,6 +324,8 @@ class AI
|
|||||||
*/
|
*/
|
||||||
public static function translations($text, $targetLanguage, $noCache = false)
|
public static function translations($text, $targetLanguage, $noCache = false)
|
||||||
{
|
{
|
||||||
|
Apps::isInstalledThrow('ai');
|
||||||
|
|
||||||
$cacheKey = "openAItranslations::" . md5($text . '_' . $targetLanguage);
|
$cacheKey = "openAItranslations::" . md5($text . '_' . $targetLanguage);
|
||||||
if ($noCache) {
|
if ($noCache) {
|
||||||
Cache::forget($cacheKey);
|
Cache::forget($cacheKey);
|
||||||
@ -285,6 +409,10 @@ class AI
|
|||||||
*/
|
*/
|
||||||
public static function generateTitle($text, $noCache = false)
|
public static function generateTitle($text, $noCache = false)
|
||||||
{
|
{
|
||||||
|
if (!Apps::isInstalled('ai')) {
|
||||||
|
return Base::retError('应用「AI Assistant」未安装');
|
||||||
|
}
|
||||||
|
|
||||||
$cacheKey = "openAIGenerateTitle::" . md5($text);
|
$cacheKey = "openAIGenerateTitle::" . md5($text);
|
||||||
if ($noCache) {
|
if ($noCache) {
|
||||||
Cache::forget($cacheKey);
|
Cache::forget($cacheKey);
|
||||||
@ -362,6 +490,10 @@ class AI
|
|||||||
*/
|
*/
|
||||||
public static function generateJokeAndSoup($noCache = false)
|
public static function generateJokeAndSoup($noCache = false)
|
||||||
{
|
{
|
||||||
|
if (!Apps::isInstalled('ai')) {
|
||||||
|
return Base::retError('应用「AI Assistant」未安装');
|
||||||
|
}
|
||||||
|
|
||||||
$cacheKey = "openAIJokeAndSoup::" . md5(date('Y-m-d'));
|
$cacheKey = "openAIJokeAndSoup::" . md5(date('Y-m-d'));
|
||||||
if ($noCache) {
|
if ($noCache) {
|
||||||
Cache::forget($cacheKey);
|
Cache::forget($cacheKey);
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class Apps
|
|||||||
{
|
{
|
||||||
if (!self::isInstalled($appId)) {
|
if (!self::isInstalled($appId)) {
|
||||||
$name = match ($appId) {
|
$name = match ($appId) {
|
||||||
'ai' => 'AI Robot',
|
'ai' => 'AI Assistant',
|
||||||
'face' => 'Face check-in',
|
'face' => 'Face check-in',
|
||||||
'appstore' => 'AppStore',
|
'appstore' => 'AppStore',
|
||||||
'approve' => 'Approval',
|
'approve' => 'Approval',
|
||||||
|
|||||||
@ -446,7 +446,7 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
}
|
}
|
||||||
// 判断AI应用是否安装
|
// 判断AI应用是否安装
|
||||||
if (!Apps::isInstalled('ai')) {
|
if (!Apps::isInstalled('ai')) {
|
||||||
throw new Exception('应用「AI Robot」未安装');
|
throw new Exception('应用「AI Assistant」未安装');
|
||||||
}
|
}
|
||||||
// 整理机器人参数
|
// 整理机器人参数
|
||||||
$setting = Base::setting('aibotSetting');
|
$setting = Base::setting('aibotSetting');
|
||||||
|
|||||||
@ -4,10 +4,7 @@
|
|||||||
:title="$L('AI 助手')"
|
:title="$L('AI 助手')"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
:styles="{
|
:width="shouldCreateNewSession ? '420px' : '600px'"
|
||||||
width: '90%',
|
|
||||||
maxWidth: shouldCreateNewSession ? '420px' : '600px',
|
|
||||||
}"
|
|
||||||
class-name="ai-assistant-modal">
|
class-name="ai-assistant-modal">
|
||||||
<div class="ai-assistant-content">
|
<div class="ai-assistant-content">
|
||||||
<div
|
<div
|
||||||
@ -126,6 +123,7 @@ export default {
|
|||||||
inputModel: '',
|
inputModel: '',
|
||||||
modelGroups: [],
|
modelGroups: [],
|
||||||
modelMap: {},
|
modelMap: {},
|
||||||
|
modelsFirstLoad: true,
|
||||||
modelsLoading: false,
|
modelsLoading: false,
|
||||||
modelCacheKey: 'aiAssistant.model',
|
modelCacheKey: 'aiAssistant.model',
|
||||||
cachedModelId: '',
|
cachedModelId: '',
|
||||||
@ -139,7 +137,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
emitter.on('openAIAssistant', this.onOpenAIAssistant);
|
emitter.on('openAIAssistant', this.onOpenAIAssistant);
|
||||||
this.initModelCache();
|
this.loadCachedModel();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
emitter.off('openAIAssistant', this.onOpenAIAssistant);
|
emitter.off('openAIAssistant', this.onOpenAIAssistant);
|
||||||
@ -181,6 +179,7 @@ export default {
|
|||||||
//
|
//
|
||||||
this.responses = [];
|
this.responses = [];
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
|
this.fetchModelOptions();
|
||||||
this.clearActiveSSEClients();
|
this.clearActiveSSEClients();
|
||||||
this.clearAutoSubmitTimer();
|
this.clearAutoSubmitTimer();
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@ -188,14 +187,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化模型缓存与下拉数据
|
|
||||||
*/
|
|
||||||
async initModelCache() {
|
|
||||||
await this.loadCachedModel();
|
|
||||||
this.fetchModelOptions();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取缓存的模型ID
|
* 读取缓存的模型ID
|
||||||
*/
|
*/
|
||||||
@ -222,17 +213,31 @@ export default {
|
|||||||
* 拉取模型配置
|
* 拉取模型配置
|
||||||
*/
|
*/
|
||||||
async fetchModelOptions() {
|
async fetchModelOptions() {
|
||||||
|
const needFetch = this.modelsFirstLoad
|
||||||
|
if (needFetch) {
|
||||||
|
this.modelsFirstLoad = false;
|
||||||
this.modelsLoading = true;
|
this.modelsLoading = true;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const {data} = await this.$store.dispatch("call", {
|
const {data} = await this.$store.dispatch("call", {
|
||||||
url: 'system/setting/aibot_models',
|
url: 'assistant/models',
|
||||||
});
|
});
|
||||||
this.normalizeModelOptions(data);
|
this.normalizeModelOptions(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$A.modalError(error?.msg || error || '获取模型列表失败');
|
if (this.modelGroups.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$A.modalError({
|
||||||
|
content: error?.msg || error || '获取模型列表失败',
|
||||||
|
onOk: _ => {
|
||||||
|
this.showModal = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
|
if (needFetch) {
|
||||||
this.modelsLoading = false;
|
this.modelsLoading = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -488,6 +493,7 @@ export default {
|
|||||||
if (!streamKey) {
|
if (!streamKey) {
|
||||||
throw new Error('获取 stream_key 失败');
|
throw new Error('获取 stream_key 失败');
|
||||||
}
|
}
|
||||||
|
this.clearActiveSSEClients();
|
||||||
const sse = new SSEClient($A.mainUrl(`ai/invoke/stream/${streamKey}`));
|
const sse = new SSEClient($A.mainUrl(`ai/invoke/stream/${streamKey}`));
|
||||||
this.registerSSEClient(sse);
|
this.registerSSEClient(sse);
|
||||||
sse.subscribe(['append', 'replace', 'done'], (type, event) => {
|
sse.subscribe(['append', 'replace', 'done'], (type, event) => {
|
||||||
@ -925,10 +931,16 @@ export default {
|
|||||||
|
|
||||||
.ai-assistant-footer {
|
.ai-assistant-footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: between;
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
.ai-assistant-footer-models {
|
.ai-assistant-footer-models {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
.ivu-select-disabled {
|
||||||
|
.ivu-select-selection {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
.ivu-select-selection {
|
.ivu-select-selection {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|||||||
@ -490,10 +490,7 @@
|
|||||||
v-model="delayTaskShow"
|
v-model="delayTaskShow"
|
||||||
:title="$L('任务延期')"
|
:title="$L('任务延期')"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:styles="{
|
width="450px">
|
||||||
width: '90%',
|
|
||||||
maxWidth: '450px'
|
|
||||||
}">
|
|
||||||
<Form
|
<Form
|
||||||
ref="formDelayTaskRef"
|
ref="formDelayTaskRef"
|
||||||
:model="delayTaskForm"
|
:model="delayTaskForm"
|
||||||
|
|||||||
@ -108,10 +108,7 @@
|
|||||||
v-model="moveTaskShow"
|
v-model="moveTaskShow"
|
||||||
:title="$L('移动任务')"
|
:title="$L('移动任务')"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:styles="{
|
width="540px"
|
||||||
width: '90%',
|
|
||||||
maxWidth: '540px'
|
|
||||||
}"
|
|
||||||
footer-hide>
|
footer-hide>
|
||||||
<TaskMove ref="addTask" v-model="moveTaskShow" :task="task"/>
|
<TaskMove ref="addTask" v-model="moveTaskShow" :task="task"/>
|
||||||
</Modal>
|
</Modal>
|
||||||
@ -121,10 +118,7 @@
|
|||||||
v-model="copyTaskShow"
|
v-model="copyTaskShow"
|
||||||
:title="$L('复制任务')"
|
:title="$L('复制任务')"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:styles="{
|
width="540px"
|
||||||
width: '90%',
|
|
||||||
maxWidth: '540px'
|
|
||||||
}"
|
|
||||||
footer-hide>
|
footer-hide>
|
||||||
<TaskMove v-model="copyTaskShow" :task="task" type="copy"/>
|
<TaskMove v-model="copyTaskShow" :task="task" type="copy"/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user