From 55303689ea4ae22dd0ca72b198a04c1804093965 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 26 Dec 2025 02:39:49 +0000 Subject: [PATCH] feat: support configurable default priority --- app/Http/Controllers/Api/SystemController.php | 15 +--- app/Models/ProjectTask.php | 16 ++++ app/Models/Setting.php | 64 +++++++++++++++ database/seeders/SettingsTableSeeder.php | 2 +- .../js/pages/manage/components/TaskAdd.vue | 3 +- .../pages/manage/components/TaskAddSimple.vue | 3 +- .../setting/components/SystemTaskPriority.vue | 79 +++++++++++++------ resources/assets/sass/pages/page-setting.scss | 24 ++++++ 8 files changed, 168 insertions(+), 38 deletions(-) diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index eb23698be..22724a168 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -697,27 +697,16 @@ class SystemController extends AbstractController if ($type == 'save') { User::auth('admin'); $list = Request::input('list'); - $array = []; if (empty($list) || !is_array($list)) { return Base::retError('参数错误'); } - foreach ($list AS $item) { - if (empty($item['name']) || empty($item['color']) || empty($item['priority'])) { - continue; - } - $array[] = [ - 'name' => $item['name'], - 'color' => $item['color'], - 'days' => intval($item['days']), - 'priority' => intval($item['priority']), - ]; - } + $array = Setting::normalizeTaskPriorityList($list); if (empty($array)) { return Base::retError('参数为空'); } $setting = Base::setting('priority', $array); } else { - $setting = Base::setting('priority'); + $setting = Setting::normalizeTaskPriorityList(Base::setting('priority')); } // return Base::retSuccess($type == 'save' ? '保存成功' : 'success', $setting); diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 21d0eee46..6bd16fb94 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -418,6 +418,22 @@ class ProjectTask extends AbstractModel } // $retPre = $parent_id ? '子任务' : '任务'; + + // 优先级:主任务在缺省时按系统默认补齐,并尽量补全 name/color + if ($parent_id == 0) { + $priorityList = Setting::normalizeTaskPriorityList(Base::setting('priority')); + if ($p_level > 0) { + $matched = reset(array_filter($priorityList, fn($item) => intval($item['priority']) === $p_level)) ?: null; + } else { + $matched = Setting::getDefaultTaskPriorityItem($priorityList); + } + if ($matched) { + $p_level = $p_level > 0 ? $p_level : intval($matched['priority']); + $p_name = $p_name ?: $matched['name']; + $p_color = $p_color ?: $matched['color']; + } + } + $task = self::createInstance([ 'parent_id' => $parent_id, 'project_id' => $project_id, diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 88a942d50..abf234ba2 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -106,6 +106,70 @@ class Setting extends AbstractModel return $value; } + /** + * 规范任务优先级设置(确保字段完整且仅有一个默认项) + * @param mixed $list + * @return array + */ + public static function normalizeTaskPriorityList($list) + { + if (!is_array($list)) { + return []; + } + $normalized = []; + $defaultIndex = null; + foreach ($list as $item) { + if (!is_array($item)) { + continue; + } + $name = trim((string)($item['name'] ?? '')); + $color = trim((string)($item['color'] ?? '')); + $priority = intval($item['priority'] ?? 0); + if ($name === '' || $color === '' || $priority <= 0) { + continue; + } + $days = intval($item['days'] ?? 0); + $isDefault = !empty($item['is_default']) || !empty($item['default']); + if ($defaultIndex === null && $isDefault) { + $defaultIndex = count($normalized); + } + $normalized[] = [ + 'name' => $name, + 'color' => $color, + 'days' => $days, + 'priority' => $priority, + 'is_default' => $isDefault ? 1 : 0, + ]; + } + if (!empty($normalized)) { + $defaultIndex = $defaultIndex ?? 0; + foreach ($normalized as $i => $row) { + $normalized[$i]['is_default'] = $i === $defaultIndex ? 1 : 0; + } + } + return array_values($normalized); + } + + /** + * 获取默认任务优先级(来自 settings.priority) + * @param array|null $list + * @return array|null + */ + public static function getDefaultTaskPriorityItem($list = null) + { + $list = $list ?? Base::setting('priority'); + $list = self::normalizeTaskPriorityList($list); + if (empty($list)) { + return null; + } + foreach ($list as $item) { + if (!empty($item['is_default'])) { + return $item; + } + } + return $list[0]; + } + /** * 是否开启 AI 助手 * @return bool diff --git a/database/seeders/SettingsTableSeeder.php b/database/seeders/SettingsTableSeeder.php index de2105eb4..d89d07e34 100644 --- a/database/seeders/SettingsTableSeeder.php +++ b/database/seeders/SettingsTableSeeder.php @@ -37,7 +37,7 @@ class SettingsTableSeeder extends Seeder array ( 'name' => 'priority', 'desc' => '', - 'setting' => '[{"name":"\\u91cd\\u8981\\u4e14\\u7d27\\u6025","color":"#ED4014","days":1,"priority":1},{"name":"\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#F16B62","days":3,"priority":2},{"name":"\\u7d27\\u6025\\u4e0d\\u91cd\\u8981","color":"#19C919","days":5,"priority":3},{"name":"\\u4e0d\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#2D8CF0","days":0,"priority":4}]', + 'setting' => '[{"name":"\\u91cd\\u8981\\u4e14\\u7d27\\u6025","color":"#ED4014","days":1,"priority":1,"is_default":1},{"name":"\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#F16B62","days":3,"priority":2,"is_default":0},{"name":"\\u7d27\\u6025\\u4e0d\\u91cd\\u8981","color":"#19C919","days":5,"priority":3,"is_default":0},{"name":"\\u4e0d\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#2D8CF0","days":0,"priority":4,"is_default":0}]', 'created_at' => seeders_at('2021-07-01 08:04:30'), 'updated_at' => seeders_at('2021-07-01 09:20:26'), ), diff --git a/resources/assets/js/pages/manage/components/TaskAdd.vue b/resources/assets/js/pages/manage/components/TaskAdd.vue index fab33aac5..9990d6f07 100644 --- a/resources/assets/js/pages/manage/components/TaskAdd.vue +++ b/resources/assets/js/pages/manage/components/TaskAdd.vue @@ -392,7 +392,8 @@ export default { } // 优先级 if (this.taskPriority.length > 0) { - await this.choosePriority(this.taskPriority[0]); + const defaultItem = this.taskPriority.find(item => item.is_default === 1) || this.taskPriority[0]; + await this.choosePriority(defaultItem); } }, diff --git a/resources/assets/js/pages/manage/components/TaskAddSimple.vue b/resources/assets/js/pages/manage/components/TaskAddSimple.vue index e31ac4533..70d91d289 100644 --- a/resources/assets/js/pages/manage/components/TaskAddSimple.vue +++ b/resources/assets/js/pages/manage/components/TaskAddSimple.vue @@ -270,7 +270,8 @@ export default { if (this.taskPriority.length === 0 || this.addData.p_name) { return; } - this.choosePriority(this.taskPriority[0], false); + const defaultItem = this.taskPriority.find(item => item.is_default === 1) || this.taskPriority[0]; + this.choosePriority(defaultItem, false); } } } diff --git a/resources/assets/js/pages/manage/setting/components/SystemTaskPriority.vue b/resources/assets/js/pages/manage/setting/components/SystemTaskPriority.vue index d249a014c..ad92b6748 100644 --- a/resources/assets/js/pages/manage/setting/components/SystemTaskPriority.vue +++ b/resources/assets/js/pages/manage/setting/components/SystemTaskPriority.vue @@ -1,8 +1,9 @@