From 03860a6dce2cc756219c18254c2f5808d302a3c0 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Wed, 24 Sep 2025 20:00:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ProjectController 中新增 tag__sort 方法,支持项目标签的排序 - 更新 ProjectTag 模型,添加排序字段 - 新增数据库迁移以添加标签排序字段 - 更新前端组件,支持拖拽调整标签顺序 - 优化样式以提升用户体验 --- .../Controllers/Api/ProjectController.php | 55 +++++++++++ app/Models/ProjectTag.php | 2 + ..._201032_add_sort_to_project_tags_table.php | 57 +++++++++++ .../components/ProjectTaskTag/index.vue | 97 ++++++++++++++++--- .../project-task-template-and-tag.scss | 40 ++++++++ 5 files changed, 240 insertions(+), 11 deletions(-) create mode 100644 database/migrations/2025_09_24_201032_add_sort_to_project_tags_table.php diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index a82268353..88f53bb17 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -3244,11 +3244,65 @@ class ProjectController extends AbstractController 'color' => $color ] ]); + $maxSort = ProjectTag::where('project_id', $projectId)->max('sort'); + $data['sort'] = is_numeric($maxSort) ? intval($maxSort) + 1 : 0; $tag = ProjectTag::create($data); } return Base::retSuccess('保存成功', $tag); } + /** + * @api {post} api/project/tag/sort 52.1 标签排序 + * + * @apiDescription 需要token身份(限:项目负责人) + * @apiVersion 1.0.0 + * @apiGroup project + * @apiName tag__sort + * + * @apiParam {Number} project_id 项目ID + * @apiParam {Array} list 标签ID列表,按新顺序排列 + * + * @apiSuccess {Number} ret 返回状态码(1正确、0错误) + * @apiSuccess {String} msg 返回信息(错误描述) + * @apiSuccess {Object} data 返回数据 + */ + public function tag__sort() + { + User::auth(); + $projectId = intval(Request::input('project_id')); + $list = Base::json2array(Request::input('list')); + if ($projectId <= 0 || !is_array($list)) { + return Base::retError('参数错误'); + } + $project = Project::userProject($projectId, true, true); + $index = 0; + $handled = []; + foreach ($list as $tagId) { + $tagId = intval($tagId); + if ($tagId <= 0) continue; + $updated = ProjectTag::where('project_id', $projectId) + ->where('id', $tagId) + ->update(['sort' => $index]); + if ($updated) { + $handled[] = $tagId; + $index++; + } + } + $others = ProjectTag::where('project_id', $projectId) + ->when(!empty($handled), function ($query) use ($handled) { + $query->whereNotIn('id', $handled); + }) + ->orderBy('sort') + ->orderByDesc('id') + ->pluck('id'); + foreach ($others as $tagId) { + ProjectTag::where('id', $tagId)->update(['sort' => $index]); + $index++; + } + $project->addLog("调整标签排序"); + return Base::retSuccess('排序已保存'); + } + /** * @api {get} api/project/tag/delete 52. 删除标签 * @@ -3329,6 +3383,7 @@ class ProjectController extends AbstractController return Base::retError('参数错误'); } $tags = ProjectTag::where('project_id', $projectId) + ->orderBy('sort') ->orderByDesc('id') ->get(); return Base::retSuccess('success', $tags); diff --git a/app/Models/ProjectTag.php b/app/Models/ProjectTag.php index d7ca55df0..46ee84e9f 100644 --- a/app/Models/ProjectTag.php +++ b/app/Models/ProjectTag.php @@ -10,6 +10,7 @@ namespace App\Models; * @property string $name 标签名称 * @property string|null $desc 标签描述 * @property string|null $color 颜色 + * @property int $sort 排序 * @property int $userid 创建人 * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at @@ -49,6 +50,7 @@ class ProjectTag extends AbstractModel 'name', 'desc', 'color', + 'sort', 'userid' ]; diff --git a/database/migrations/2025_09_24_201032_add_sort_to_project_tags_table.php b/database/migrations/2025_09_24_201032_add_sort_to_project_tags_table.php new file mode 100644 index 000000000..dfe3c1020 --- /dev/null +++ b/database/migrations/2025_09_24_201032_add_sort_to_project_tags_table.php @@ -0,0 +1,57 @@ +unsignedInteger('sort')->default(0)->after('color')->comment('排序'); + $added = true; + } + }); + + if ($added) { + \App\Models\ProjectTag::query() + ->select('project_id') + ->distinct() + ->orderBy('project_id') + ->chunk(100, function ($projectIds) { + foreach ($projectIds as $project) { + $tags = \App\Models\ProjectTag::query() + ->where('project_id', $project->project_id) + ->orderByDesc('id') + ->get(['id']); + $index = 0; + foreach ($tags as $tag) { + \App\Models\ProjectTag::where('id', $tag->id)->update(['sort' => $index++]); + } + } + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('project_tags', function (Blueprint $table) { + if (Schema::hasColumn('project_tags', 'sort')) { + $table->dropColumn('sort'); + } + }); + } +} diff --git a/resources/assets/js/pages/manage/components/ProjectTaskTag/index.vue b/resources/assets/js/pages/manage/components/ProjectTaskTag/index.vue index e9e940bac..fdc4a4b03 100644 --- a/resources/assets/js/pages/manage/components/ProjectTaskTag/index.vue +++ b/resources/assets/js/pages/manage/components/ProjectTaskTag/index.vue @@ -8,6 +8,14 @@
+ @@ -19,8 +27,27 @@
{{$L('当前项目暂无任务标签')}}
-
-
+ +
+
+ +
@@ -28,11 +55,13 @@
{{ item.desc }}
-
- -
@@ -42,7 +71,7 @@
-
+
@@ -51,7 +80,8 @@