feat: 任务分类页面增加草稿箱功能(需求部门可见)
This commit is contained in:
parent
166bf76ede
commit
1a74426e56
@ -2114,6 +2114,122 @@
|
||||
/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<!-- 草稿箱标签页(仅需求部门用户可见) -->
|
||||
<a-tab-pane key="drafts" v-if="showDraftTab">
|
||||
<template #tab>
|
||||
<span>草稿箱 <span class="tab-count">({{ draftsTotal }})</span></span>
|
||||
</template>
|
||||
<div class="search-filter-bar chart-card">
|
||||
<div class="search-row">
|
||||
<a-input-search
|
||||
v-model:value="draftsFilters.keyword"
|
||||
placeholder="搜索草稿任务..."
|
||||
style="width: 300px;"
|
||||
@search="loadDraftTasks"
|
||||
allow-clear
|
||||
/>
|
||||
<div class="filter-group">
|
||||
<span class="filter-label">排序:</span>
|
||||
<a-select v-model:value="draftsFilters.sortBy" style="width: 120px;" @change="loadDraftTasks">
|
||||
<a-select-option value="latest">最新创建</a-select-option>
|
||||
<a-select-option value="oldest">最早创建</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="stats-info">
|
||||
<span class="stat-item">共 <span class="stat-value">{{ draftsTotal }}</span> 个草稿</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 草稿列表 -->
|
||||
<div v-if="draftsLoading" class="loading-container">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="draftTaskList.length === 0" class="empty-state chart-card">
|
||||
<Icon name="file" size="3xl" color="#666" />
|
||||
<p>暂无草稿任务</p>
|
||||
<p class="empty-hint">发布任务时可以保存为草稿,稍后继续编辑</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="task-grid">
|
||||
<div
|
||||
v-for="task in draftTaskList"
|
||||
:key="task.id"
|
||||
class="task-card chart-card"
|
||||
@click="handleEditDraftTask(task)"
|
||||
>
|
||||
<!-- 草稿标签 -->
|
||||
<div class="task-badge-container">
|
||||
<span class="task-badge draft-badge">草稿</span>
|
||||
</div>
|
||||
|
||||
<!-- 任务标题 -->
|
||||
<div class="task-header">
|
||||
<h3 class="task-title">{{ task.title || '未命名任务' }}</h3>
|
||||
</div>
|
||||
|
||||
<!-- 任务信息 -->
|
||||
<div class="task-details">
|
||||
<div class="detail-item" v-if="task.taskNo">
|
||||
<span class="icon"><Icon name="hash" size="sm" color="#31f08b" /></span>
|
||||
<span>{{ task.taskNo }}</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="task.brandName">
|
||||
<span class="icon"><Icon name="tag" size="sm" color="#31f08b" /></span>
|
||||
<span>品牌: {{ task.brandName }}</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="task.categoryName">
|
||||
<span class="icon"><Icon name="folder" size="sm" color="#31f08b" /></span>
|
||||
<span>类目: {{ task.categoryName }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="icon"><Icon name="clock" size="sm" color="#31f08b" /></span>
|
||||
<span>创建: {{ formatDate(task.createTime) }}</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="task.updateTime">
|
||||
<span class="icon"><Icon name="edit" size="sm" color="#31f08b" /></span>
|
||||
<span>最后编辑: {{ formatDate(task.updateTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="task-actions" style="margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(49, 240, 139, 0.2);">
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.stop="handleEditDraftTask(task)"
|
||||
style="flex: 1;">
|
||||
<Icon name="edit" size="sm" style="margin-right: 4px;" />
|
||||
继续编辑
|
||||
</a-button>
|
||||
<a-button
|
||||
type="default"
|
||||
danger
|
||||
size="small"
|
||||
@click.stop="handleDeleteDraft(task)"
|
||||
style="width: 80px;">
|
||||
<Icon name="trash" size="sm" style="margin-right: 4px;" />
|
||||
删除
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div v-if="draftsTotal > 0" class="pagination">
|
||||
<a-pagination
|
||||
v-model:current="draftsPagination.page"
|
||||
v-model:page-size="draftsPagination.pageSize"
|
||||
:total="draftsTotal"
|
||||
:show-size-changer="false"
|
||||
@change="handleDraftsPageChange"
|
||||
/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
|
||||
@ -2803,6 +2919,9 @@ const handleDeptViewChange = (deptId: number | null) => {
|
||||
case 'review':
|
||||
loadReviewTasks()
|
||||
break
|
||||
case 'drafts':
|
||||
loadDraftTasks()
|
||||
break
|
||||
}
|
||||
}, 0) // 使用 setTimeout 确保 effectiveDeptType 已更新
|
||||
}
|
||||
@ -2838,6 +2957,18 @@ const publishedLoading = ref(false)
|
||||
const publishedTaskList = ref<Task[]>([])
|
||||
const publishedTotal = ref(0)
|
||||
|
||||
// 草稿箱状态
|
||||
const draftsLoading = ref(false)
|
||||
const draftTaskList = ref<Task[]>([])
|
||||
const draftsTotal = ref(0)
|
||||
|
||||
// 是否显示草稿箱tab(仅需求部门用户可见)
|
||||
const showDraftTab = computed(() => {
|
||||
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
|
||||
// 需求部门用户或管理员可以看到草稿箱
|
||||
return userDeptType.value === 'demand' || userInfo.isAdmin === 1 || userInfo.isAdmin === true
|
||||
})
|
||||
|
||||
// 进行中任务状态
|
||||
const inProgressLoading = ref(false)
|
||||
const inProgressTaskList = ref<Task[]>([])
|
||||
@ -3033,6 +3164,12 @@ const publishedFilters = reactive({
|
||||
maxScore: undefined as number | undefined
|
||||
})
|
||||
|
||||
// 草稿箱筛选条件
|
||||
const draftsFilters = reactive({
|
||||
keyword: undefined as string | undefined,
|
||||
sortBy: 'latest' as 'latest' | 'oldest'
|
||||
})
|
||||
|
||||
// 进行中任务筛选条件
|
||||
const inProgressFilters = reactive({
|
||||
keyword: undefined as string | undefined,
|
||||
@ -4395,6 +4532,12 @@ const publishedPagination = reactive({
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 草稿箱分页
|
||||
const draftsPagination = reactive({
|
||||
page: 1,
|
||||
pageSize: 12
|
||||
})
|
||||
|
||||
// 进行中任务分页
|
||||
const inProgressPagination = reactive({
|
||||
page: 1,
|
||||
@ -4437,6 +4580,76 @@ const handlePublishedPageChange = (page: number) => {
|
||||
loadPublishedTasks()
|
||||
}
|
||||
|
||||
// 加载草稿箱任务
|
||||
const loadDraftTasks = async () => {
|
||||
draftsLoading.value = true
|
||||
try {
|
||||
const response = await taskApi.getMyTasks({
|
||||
role: 'publisher',
|
||||
status: 'draft', // 只查询草稿状态的任务
|
||||
keyword: draftsFilters.keyword || undefined,
|
||||
page: draftsPagination.page,
|
||||
pageSize: draftsPagination.pageSize,
|
||||
sortBy: draftsFilters.sortBy
|
||||
})
|
||||
|
||||
if (response.code === 200) {
|
||||
draftTaskList.value = response.data.records || []
|
||||
draftsTotal.value = response.data.total || 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载草稿任务失败:', error)
|
||||
message.error('加载草稿失败')
|
||||
} finally {
|
||||
draftsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 草稿箱分页变化
|
||||
const handleDraftsPageChange = (page: number) => {
|
||||
draftsPagination.page = page
|
||||
loadDraftTasks()
|
||||
}
|
||||
|
||||
// 编辑草稿任务
|
||||
const handleEditDraftTask = (task: any) => {
|
||||
router.push({
|
||||
path: '/tasks/create',
|
||||
query: { taskId: task.id, mode: 'edit' }
|
||||
})
|
||||
}
|
||||
|
||||
// 删除草稿任务
|
||||
const handleDeleteDraft = async (task: any) => {
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: `确定要删除草稿"${task.title || '未命名任务'}"吗?删除后无法恢复。`,
|
||||
okText: '确认删除',
|
||||
cancelText: '取消',
|
||||
okType: 'danger',
|
||||
onOk: () => resolve(),
|
||||
onCancel: () => reject()
|
||||
})
|
||||
})
|
||||
|
||||
const response = await taskApi.deleteTask(task.id)
|
||||
if (response.code === 200) {
|
||||
message.success('草稿已删除')
|
||||
loadDraftTasks()
|
||||
loadAllTabCounts()
|
||||
} else {
|
||||
message.error(response.msg || '删除失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error) {
|
||||
console.error('删除草稿失败:', error)
|
||||
message.error(error.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置已完成任务筛选条件
|
||||
const handleCompletedFiltersReset = () => {
|
||||
completedFilters.keyword = undefined
|
||||
@ -5913,6 +6126,17 @@ const loadAllTabCounts = async () => {
|
||||
}).catch(() => {})
|
||||
)
|
||||
|
||||
// 6. 草稿箱数量(仅需求部门用户)
|
||||
if (showDraftTab.value) {
|
||||
promises.push(
|
||||
taskApi.getMyTasks({ role: 'publisher', status: 'draft', page: 1, pageSize: 1 }).then(res => {
|
||||
if (res.code === 200 && res.data && res.data.total !== undefined) {
|
||||
draftsTotal.value = res.data.total
|
||||
}
|
||||
}).catch(() => {})
|
||||
)
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
} catch (error) {
|
||||
console.error('加载Tab数量统计失败:', error)
|
||||
@ -6472,6 +6696,26 @@ onUnmounted(() => {
|
||||
color: $color-success;
|
||||
}
|
||||
|
||||
// 草稿标签样式
|
||||
.task-badge-container {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.task-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 12px;
|
||||
border-radius: $radius-small;
|
||||
font-size: $font-size-xs;
|
||||
font-weight: $font-weight-medium;
|
||||
}
|
||||
|
||||
.draft-badge {
|
||||
background: rgba(255, 193, 7, 0.15);
|
||||
border: 1px solid rgba(255, 193, 7, 0.4);
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.badge-high-score {
|
||||
background: rgba(49, 240, 139, 0.1);
|
||||
border: 1px solid rgba(49, 240, 139, 0.2);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user