diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index a015a1c08..fa3b9d170 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -286,6 +286,8 @@ class ProjectController extends AbstractController * @apiParam {Number} project_id 项目ID * @apiParam {String} name 项目名称 * @apiParam {String} [desc] 项目介绍 + * @apiParam {String} [archive_method] 归档方式 + * @apiParam {Number} [archive_days] 自动归档天数 * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -298,6 +300,8 @@ class ProjectController extends AbstractController $project_id = intval(Request::input('project_id')); $name = trim(Request::input('name', '')); $desc = trim(Request::input('desc', '')); + $archive_method = Request::input('archive_method'); + $archive_days = intval(Request::input('archive_days')); if (mb_strlen($name) < 2) { return Base::retError('项目名称不可以少于2个字'); } elseif (mb_strlen($name) > 32) { @@ -306,9 +310,14 @@ class ProjectController extends AbstractController if (mb_strlen($desc) > 255) { return Base::retError('项目介绍最多只能设置255个字'); } + if ($archive_method == 'custom') { + if ($archive_days < 1 || $archive_days > 365) { + return Base::retError('自动归档天数设置错误,范围:1-365'); + } + } // $project = Project::userProject($project_id, true, true); - AbstractModel::transaction(function () use ($desc, $name, $project) { + AbstractModel::transaction(function () use ($archive_days, $archive_method, $desc, $name, $project) { if ($project->name != $name) { $project->addLog("修改项目名称", [ 'change' => [$project->name, $name] @@ -322,6 +331,18 @@ class ProjectController extends AbstractController $project->desc = $desc; $project->addLog("修改项目介绍"); } + if ($project->archive_method != $archive_method) { + $project->addLog("修改归档方式", [ + 'change' => [$project->archive_method, $archive_method] + ]); + $project->archive_method = $archive_method; + } + if ($project->archive_method == 'custom') { + $project->addLog("修改自动归档天数", [ + 'change' => [$project->archive_days, $archive_days] + ]); + $project->archive_days = $archive_days; + } $project->save(); }); $project->pushMsg('update'); diff --git a/app/Models/Project.php b/app/Models/Project.php index 30bf549e8..2d58bcfad 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -20,6 +20,8 @@ use Request; * @property string|null $desc 描述、备注 * @property int|null $userid 创建人 * @property int|null $personal 是否个人项目 + * @property string|null $archive_method 自动归档方式 + * @property int|null $archive_days 自动归档天数 * @property string|null $user_simple 成员总数|1,2,3 * @property int|null $dialog_id 聊天会话ID * @property \Illuminate\Support\Carbon|null $archived_at 归档时间 @@ -48,6 +50,8 @@ use Request; * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore() * @method static \Illuminate\Database\Eloquent\Builder|Project whereArchivedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Project whereArchivedUserid($value) + * @method static \Illuminate\Database\Eloquent\Builder|Project whereArchiveDays($value) + * @method static \Illuminate\Database\Eloquent\Builder|Project whereArchiveMethod($value) * @method static \Illuminate\Database\Eloquent\Builder|Project whereCreatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Project whereDeletedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Project whereDesc($value) diff --git a/app/Tasks/AutoArchivedTask.php b/app/Tasks/AutoArchivedTask.php index 9bd049c72..fccf32ddb 100644 --- a/app/Tasks/AutoArchivedTask.php +++ b/app/Tasks/AutoArchivedTask.php @@ -21,25 +21,62 @@ class AutoArchivedTask extends AbstractTask } public function start() + { + $this->systemAutoArchived(); + $this->projectAutoArchived(); + } + + /** + * 处理已完成未归档的任务(系统默认) + */ + private function systemAutoArchived() { $setting = Base::setting('system'); - if ($setting['auto_archived'] === 'open') { - $archivedDay = floatval($setting['archived_day']); - if ($archivedDay > 0) { - $archivedDay = min(100, $archivedDay); - $archivedTime = Carbon::now()->subDays($archivedDay); - //获取已完成未归档的任务 - $taskLists = ProjectTask::whereNotNull('complete_at') - ->where('complete_at', '<=', $archivedTime) - ->where('archived_userid', 0) - ->whereNull('archived_at') - ->take(100) - ->get(); - /** @var ProjectTask $task */ - foreach ($taskLists AS $task) { - $task->archivedTask(Carbon::now(), true); - } - } + if ($setting['auto_archived'] !== 'open') { + return; + } + $archivedDay = min(365, floatval($setting['archived_day'])); + if ($archivedDay <= 0) { + return; + } + $taskLists = ProjectTask::select('project_tasks.*') + ->join('projects', 'projects.id', '=', 'project_tasks.project_id') + ->whereNotNull('project_tasks.complete_at') + ->where('project_tasks.complete_at', '<=', Carbon::now()->subDays($archivedDay)) + ->where('project_tasks.archived_userid', 0) + ->whereNull('project_tasks.archived_at') + ->where('projects.archive_method', '!=', 'custom') + ->take(100) + ->get(); + /** @var ProjectTask $task */ + foreach ($taskLists as $task) { + $task->archivedTask(Carbon::now(), true); + } + } + + /** + * 处理已完成未归档的任务(项目自定义) + */ + private function projectAutoArchived() + { + // 获取设置了自定义归档的项目的任务 + $prefix = \DB::getTablePrefix(); + $taskLists = ProjectTask::select('project_tasks.*') + ->join('projects', 'projects.id', '=', 'project_tasks.project_id') + ->whereNotNull('project_tasks.complete_at') + ->where('project_tasks.archived_userid', 0) + ->whereNull('project_tasks.archived_at') + ->where('projects.archive_method', 'custom') + ->whereRaw("DATEDIFF(NOW(), {$prefix}project_tasks.complete_at) >= {$prefix}projects.archive_days") + ->with(['project' => function ($query) { + $query->select('id', 'archive_days'); + }]) + ->take(100) + ->get(); + + /** @var ProjectTask $task */ + foreach ($taskLists as $task) { + $task->archivedTask(Carbon::now(), true); } } diff --git a/database/migrations/2024_12_01_104400_add_archive_fields_to_pre_projects_table.php b/database/migrations/2024_12_01_104400_add_archive_fields_to_pre_projects_table.php new file mode 100644 index 000000000..029142865 --- /dev/null +++ b/database/migrations/2024_12_01_104400_add_archive_fields_to_pre_projects_table.php @@ -0,0 +1,42 @@ +after('personal', function ($table) { + $table->string('archive_method', 20)->nullable()->default('system')->comment('自动归档方式'); + $table->integer('archive_days')->nullable()->default(30)->comment('自动归档天数'); + }); + $table->index('archive_method'); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('projects', function (Blueprint $table) { + $table->dropIndex('idx_projects_archive_method'); + $table->dropColumn([ + 'archive_method', + 'archive_days' + ]); + }); + } +} diff --git a/language/original-api.txt b/language/original-api.txt index 96c264c1f..8044eacd3 100644 --- a/language/original-api.txt +++ b/language/original-api.txt @@ -770,3 +770,7 @@ webhook地址最长仅支持255个字符。 此功能仅管理员可用 此功能仅指定用户可用 此功能已禁止使用 + +自动归档天数设置错误,范围:(*) +修改归档方式 +修改自动归档天数 diff --git a/language/original-web.txt b/language/original-web.txt index 5476cecb4..cd2383959 100644 --- a/language/original-web.txt +++ b/language/original-web.txt @@ -1833,3 +1833,5 @@ WiFi签到延迟时长为±1分钟。 例如:你是一个人开发的AI助手 仅支持 http 代理 例如:http://proxy.com 或 https://proxy.com + +系统默认 diff --git a/resources/assets/js/pages/manage/components/ProjectPanel.vue b/resources/assets/js/pages/manage/components/ProjectPanel.vue index 03c16ed23..b4256e50b 100644 --- a/resources/assets/js/pages/manage/components/ProjectPanel.vue +++ b/resources/assets/js/pages/manage/components/ProjectPanel.vue @@ -338,6 +338,21 @@ + + + {{$L('系统默认')}} + {{$L('自定义')}} + + + +
@@ -1270,8 +1285,12 @@ export default { projectDropdown(name) { switch (name) { case "setting": - this.$set(this.settingData, 'name', this.projectData.name); - this.$set(this.settingData, 'desc', this.projectData.desc); + Object.assign(this.settingData, { + name: this.projectData.name, + desc: this.projectData.desc, + archive_method: this.projectData.archive_method, + archive_days: this.projectData.archive_days + }); this.settingShow = true; this.$nextTick(() => { this.$refs.projectName.focus() @@ -1280,13 +1299,7 @@ export default { break; case "permissions": - // this.$set(this.settingData, 'name', this.projectData.name); - // this.$set(this.settingData, 'desc', this.projectData.desc); this.permissionShow = true; - // this.$nextTick(() => { - // this.$refs.projectName.focus() - // setTimeout(this.$refs.projectDesc.resizeTextarea, 0) - // }); break; case "user": @@ -1556,7 +1569,11 @@ export default { } else { this.goBack(); } - } + }, + + formArchived(value) { + this.settingData = { ...this.settingData, archive_method: value }; + }, } } diff --git a/resources/assets/js/pages/manage/setting/components/SystemSetting.vue b/resources/assets/js/pages/manage/setting/components/SystemSetting.vue index 995cf10e0..349e0659e 100644 --- a/resources/assets/js/pages/manage/setting/components/SystemSetting.vue +++ b/resources/assets/js/pages/manage/setting/components/SystemSetting.vue @@ -92,7 +92,7 @@ {{$L('天')}}
-
{{$L('任务完成 (*) 天后自动归档。', formDatum.archived_day)}}
+
{{$L('任务完成 (*) 天后自动归档。', formDatum.archived_day || 'n')}}