feat(task): 增加AI自动分析开关(系统级+项目级)

系统设置新增 task_ai_auto_analyze 开关控制全局AI任务分析;项目设置新增 ai_auto_analyze 开关,系统关闭时项目无法开启。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kuaifan 2026-04-02 17:51:38 +08:00
parent fc171bc71f
commit 4b32472d64
6 changed files with 78 additions and 4 deletions

View File

@ -301,6 +301,7 @@ class ProjectController extends AbstractController
* @apiParam {String} [desc] 项目介绍
* @apiParam {String} [archive_method] 归档方式
* @apiParam {Number} [archive_days] 自动归档天数
* @apiParam {String} [ai_auto_analyze] AI自动分析open|close
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -315,6 +316,7 @@ class ProjectController extends AbstractController
$desc = trim(Request::input('desc', ''));
$archive_method = Request::input('archive_method');
$archive_days = intval(Request::input('archive_days'));
$ai_auto_analyze = Request::input('ai_auto_analyze');
if (mb_strlen($name) < 2) {
return Base::retError('项目名称不可以少于2个字');
} elseif (mb_strlen($name) > 32) {
@ -330,7 +332,7 @@ class ProjectController extends AbstractController
}
//
$project = Project::userProject($project_id, true, true);
AbstractModel::transaction(function () use ($archive_days, $archive_method, $desc, $name, $project) {
AbstractModel::transaction(function () use ($archive_days, $archive_method, $ai_auto_analyze, $desc, $name, $project) {
if ($project->name != $name) {
$project->addLog("修改项目名称", [
'change' => [$project->name, $name]
@ -356,6 +358,12 @@ class ProjectController extends AbstractController
]);
$project->archive_days = $archive_days;
}
if (in_array($ai_auto_analyze, ['open', 'close']) && $project->ai_auto_analyze != $ai_auto_analyze) {
$project->addLog("修改AI自动分析", [
'change' => [$project->ai_auto_analyze, $ai_auto_analyze]
]);
$project->ai_auto_analyze = $ai_auto_analyze;
}
$project->save();
});
$project->pushMsg('update');

View File

@ -93,6 +93,7 @@ class SystemController extends AbstractController
'file_upload_limit',
'unclaimed_task_reminder',
'unclaimed_task_reminder_time',
'task_ai_auto_analyze',
])) {
unset($all[$key]);
}
@ -146,6 +147,7 @@ class SystemController extends AbstractController
$setting['file_upload_limit'] = $setting['file_upload_limit'] ?: '';
$setting['unclaimed_task_reminder'] = $setting['unclaimed_task_reminder'] ?: 'close';
$setting['unclaimed_task_reminder_time'] = $setting['unclaimed_task_reminder_time'] ?: '';
$setting['task_ai_auto_analyze'] = $setting['task_ai_auto_analyze'] ?: 'open';
$setting['server_timezone'] = config('app.timezone');
$setting['server_version'] = Base::getVersion();
//

View File

@ -37,10 +37,20 @@ class AiTaskLoopTask extends AbstractTask
return;
}
// 检查系统级 AI 自动分析开关
if (Base::settingFind('system', 'task_ai_auto_analyze', 'open') === 'close') {
return;
}
// 查询待处理的任务
$tasks = $this->findPendingTasks();
foreach ($tasks as $task) {
// 检查项目级 AI 自动分析开关
if ($task->project && $task->project->ai_auto_analyze === 'close') {
continue;
}
// 为任务创建事件记录
$this->createEventRecords($task);
@ -62,7 +72,8 @@ class AiTaskLoopTask extends AbstractTask
->pluck('task_id');
// 查询新建任务(未处理过的)
$newTasks = ProjectTask::where('parent_id', 0) // 只处理主任务
$newTasks = ProjectTask::with('project')
->where('parent_id', 0) // 只处理主任务
->whereNull('deleted_at')
->whereNull('archived_at')
->where('created_at', '<=', $delayTime) // 创建超过延迟时间
@ -81,7 +92,8 @@ class AiTaskLoopTask extends AbstractTask
->take(self::BATCH_SIZE - $newTasks->count())
->pluck('task_id');
$retryTasks = ProjectTask::whereIn('id', $retryTaskIds)
$retryTasks = ProjectTask::with('project')
->whereIn('id', $retryTaskIds)
->whereNull('deleted_at')
->get();

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAiAutoAnalyzeToProjectsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('projects', function (Blueprint $table) {
$table->string('ai_auto_analyze', 20)->default('open')->after('archive_days');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('projects', function (Blueprint $table) {
$table->dropColumn('ai_auto_analyze');
});
}
}

View File

@ -416,6 +416,15 @@
</template>
</FormItem>
<FormItem :label="$L('AI任务分析')" prop="ai_auto_analyze">
<RadioGroup v-model="settingData.ai_auto_analyze">
<Radio label="open" :disabled="systemConfig.task_ai_auto_analyze === 'close'">{{$L('开启')}}</Radio>
<Radio label="close">{{$L('关闭')}}</Radio>
</RadioGroup>
<div v-if="systemConfig.task_ai_auto_analyze === 'close'" class="form-tip">{{$L('系统已关闭AI任务分析功能')}}</div>
<div v-else-if="settingData.ai_auto_analyze === 'open'" class="form-tip">{{$L('新建任务后AI自动分析并给出建议。')}}</div>
<div v-else class="form-tip">{{$L('关闭后本项目将不再自动分析任务。')}}</div>
</FormItem>
</Form>
<div slot="footer" class="adaption">
<Button type="default" @click="settingShow=false">{{$L('取消')}}</Button>
@ -696,6 +705,8 @@ export default {
'cacheUserBasic',
'formOptions',
'systemConfig',
]),
...mapGetters(['projectData', 'transforTasks']),
@ -1508,7 +1519,8 @@ export default {
name: this.projectData.name,
desc: this.projectData.desc,
archive_method: this.projectData.archive_method,
archive_days: this.projectData.archive_days
archive_days: this.projectData.archive_days,
ai_auto_analyze: this.projectData.ai_auto_analyze || 'open'
});
this.settingShow = true;
this.$nextTick(() => {

View File

@ -124,6 +124,14 @@
:placeholder="$L('请选择提醒时间')"
transfer/>
</FormItem>
<FormItem :label="$L('AI任务分析')" prop="taskAiAutoAnalyze">
<RadioGroup v-model="formDatum.task_ai_auto_analyze">
<Radio label="open">{{$L('开启')}}</Radio>
<Radio label="close">{{$L('关闭')}}</Radio>
</RadioGroup>
<div v-if="formDatum.task_ai_auto_analyze == 'open'" class="form-tip">{{$L('新建任务后AI自动分析并给出建议')}}</div>
<div v-else class="form-tip">{{$L('关闭后所有项目将不再自动分析任务。')}}</div>
</FormItem>
<FormItem :label="$L('个人任务上限')" prop="taskUserLimit">
<div style="width: 110px;">
<Input type="number" number v-model="formDatum.task_user_limit" @on-keyup="$A.inputNumberLimit($event, 1, 2000)">