perf: 添加项目任务标签功能

This commit is contained in:
kuaifan 2024-12-08 23:24:56 +08:00
parent bca0410a08
commit 24c5200a90
5 changed files with 72 additions and 33 deletions

View File

@ -1239,6 +1239,7 @@ class ProjectController extends AbstractController
$headings[] = Doo::translate('父级任务ID');
$headings[] = Doo::translate('所属项目');
$headings[] = Doo::translate('任务标题');
$headings[] = Doo::translate('任务标签');
$headings[] = Doo::translate('任务开始时间');
$headings[] = Doo::translate('任务结束时间');
$headings[] = Doo::translate('完成时间');
@ -1259,7 +1260,7 @@ class ProjectController extends AbstractController
'style' => 'font-weight: bold;padding-bottom: 4px;',
];
//
$builder = ProjectTask::select(['project_tasks.*', 'project_task_users.userid as ownerid'])
$builder = ProjectTask::with(['taskTag'])->select(['project_tasks.*', 'project_task_users.userid as ownerid'])
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_id')
->where('project_task_users.owner', 1)
->whereIn('project_task_users.userid', $userid)
@ -1341,6 +1342,9 @@ class ProjectController extends AbstractController
$task->parent_id ?: '-',
Base::filterEmoji($task->project?->name) ?: '-',
Base::filterEmoji($task->name),
$task->taskTag->map(function ($tag) {
return Base::filterEmoji($tag->name);
})->join(', ') ?: '-',
$task->start_at ?: '-',
$task->end_at ?: '-',
$task->complete_at ?: '-',
@ -1463,6 +1467,7 @@ class ProjectController extends AbstractController
$headings[] = Doo::translate('父级任务ID');
$headings[] = Doo::translate('所属项目');
$headings[] = Doo::translate('任务标题');
$headings[] = Doo::translate('任务标签');
$headings[] = Doo::translate('任务开始时间');
$headings[] = Doo::translate('任务结束时间');
$headings[] = Doo::translate('任务计划用时');
@ -1471,7 +1476,8 @@ class ProjectController extends AbstractController
$headings[] = Doo::translate('创建人');
$data = [];
//
ProjectTask::whereNull('complete_at')
ProjectTask::with(['taskTag'])
->whereNull('complete_at')
->whereNotNull('end_at')
->where('end_at', '<=', Carbon::now())
->orderBy('end_at')
@ -1502,11 +1508,14 @@ class ProjectController extends AbstractController
$task->parent_id ?: '-',
Base::filterEmoji($task->project?->name) ?: '-',
Base::filterEmoji($task->name),
$task->taskTag->map(function ($tag) {
return Base::filterEmoji($tag->name);
})->join(', ') ?: '-',
$task->start_at ?: '-',
$task->end_at ?: '-',
$planTime,
$overTime,
implode("", $ownerNames),
implode(', ', $ownerNames),
Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})",
];
}

View File

@ -58,6 +58,12 @@ import Tags from "./tags.vue";
export default {
name: "TaskTagAdd",
components: {Tags},
props: {
projectId: {
type: [Number, String],
required: true
}
},
data() {
return {
loadIng: 0,
@ -89,11 +95,25 @@ export default {
}
},
methods: {
onOpen(tag) {
onOpen(tag = null) {
if (tag === null) {
tag = this.getEmptyTag()
}
this.editingTag = { ...tag }
this.showEditModal = true
},
//
getEmptyTag() {
return {
id: null,
project_id: this.projectId,
name: '',
desc: '',
color: ''
}
},
//
async handleSave() {
if (!this.editingTag.name) {
@ -118,7 +138,7 @@ export default {
const results = await Promise.all(savePromises)
$A.messageSuccess(results.length === 1 ? results[0].msg : '全部保存成功')
this.showEditModal = false
this.$emit('on-save')
this.$emit('on-save', results)
} catch (error) {
$A.messageError(error.msg || '保存失败')
}

View File

@ -7,7 +7,7 @@
<Loading v-if="loadIng > 0"/>
</div>
<div class="actions">
<Button type="primary" icon="md-add" @click="handleAdd">
<Button type="primary" icon="md-add" @click="handleAdd(null)">
{{$L('新建标签')}}
</Button>
</div>
@ -16,7 +16,7 @@
<div class="content">
<div v-if="!tags.length" class="empty">
<div class="empty-text">{{$L('当前项目暂无任务标签')}}</div>
<Button type="primary" icon="md-add" @click="handleAdd">{{$L('新建标签')}}</Button>
<Button type="primary" icon="md-add" @click="handleAdd(null)">{{$L('新建标签')}}</Button>
</div>
<div v-else class="template-list">
<div v-for="item in tags" :key="item.id" class="tag-item">
@ -27,7 +27,7 @@
<div v-if="item.desc" class="tag-desc">{{ item.desc }}</div>
</div>
<div class="tag-actions">
<Button @click="handleEdit(item)" type="primary">
<Button @click="handleAdd(item)" type="primary">
{{$L('编辑')}}
</Button>
<Button @click="handleDelete(item)" type="error">
@ -38,8 +38,8 @@
</div>
</div>
<!-- 编辑标签弹窗 -->
<TaskTagAdd ref="addTag" @on-save="loadTags"/>
<!-- 标签添加/编辑 -->
<TaskTagAdd ref="addTag" :project-id="projectId" @on-save="loadTags"/>
</div>
</template>
@ -73,17 +73,6 @@ export default {
this.loadTags()
},
methods: {
//
getEmptyTag() {
return {
id: null,
project_id: this.projectId,
name: '',
desc: '',
color: ''
}
},
//
async loadTags() {
this.loadIng++
@ -103,13 +92,8 @@ export default {
}
},
//
handleAdd() {
this.$refs.addTag.onOpen(this.getEmptyTag())
},
//
handleEdit(tag) {
//
handleAdd(tag) {
this.$refs.addTag.onOpen(tag)
},

View File

@ -48,7 +48,7 @@
<script>
export default {
name: "TaskSelect",
name: "TaskTagSelect",
props: {
value: {
type: Array,

View File

@ -153,11 +153,12 @@
</div>
<div class="item-content tags">
<EPopover v-model="tagShow" class="tags-select" placement="bottom">
<TagSelect
<TaskTagSelect
v-model="tagValue"
:data-sources="tagData"
:loading="tagLoad > 0"
:max="10"/>
:max="10"
@add="onTagAdd"/>
<div slot="reference">
<TaskTag :tags="getTag">
<li v-if="getTag.length === 0" slot="end" class="add-icon"></li>
@ -547,6 +548,8 @@
<Button @click="historyShow=false">{{$L('关闭')}}</Button>
</div>
</Modal>
<!--标签添加-->
<TaskTagAdd ref="addTag" :project-id="taskDetail.project_id" @on-save="onTagAddSave"/>
</div>
</template>
@ -561,19 +564,21 @@ import TaskMenu from "./TaskMenu";
import ChatInput from "./ChatInput";
import UserSelect from "../../../components/UserSelect.vue";
import TaskTag from "./ProjectTaskTag/tags.vue";
import TagSelect from "./ProjectTaskTag/select.vue";
import TaskTagSelect from "./ProjectTaskTag/select.vue";
import TaskExistTips from "./TaskExistTips.vue";
import TEditorTask from "../../../components/TEditorTask.vue";
import TaskContentHistory from "./TaskContentHistory.vue";
import TaskTagAdd from "./ProjectTaskTag/add.vue";
export default {
name: "TaskDetail",
components: {
TaskTagAdd,
TaskContentHistory,
TEditorTask,
UserSelect,
TaskTag,
TagSelect,
TaskTagSelect,
TaskExistTips,
ChatInput,
TaskMenu,
@ -1988,6 +1993,27 @@ export default {
onTaskQuick(time, type) {
this.$set(this.delayTaskForm, 'time', Math.round(time * 100) / 100)
this.$set(this.delayTaskForm, 'type', type)
},
onTagAdd() {
//
this.tagValue = this.getTag;
this.tagBakValue = $A.cloneJSON(this.tagValue);
//
this.tagShow = false
this.$refs.addTag.onOpen(null)
},
onTagAddSave(result) {
const current = this.tagValue;
const addData = result.filter(({data}) => data && data.id > 0).map(({data}) => data);
// 使
const mergedTags = [
...addData,
...current.filter(tag => !addData.some(newTag => newTag.name === tag.name))
];
//
this.updateData('tag', mergedTags);
}
}
}