feat: 发布任务页面增加保存草稿功能

This commit is contained in:
Your Name 2026-01-17 10:40:24 +08:00
parent 1a74426e56
commit 8789143501
3 changed files with 113 additions and 5 deletions

View File

@ -48,6 +48,7 @@ public class PipelineTaskDTO {
private Long receiverId; // 指定接收人ID(assigned模式使用)
private List<String> productBarcodes; // 商品条码列表(已验证库存)
private String previewImage; // 预览图URL
private Boolean asDraft; // 是否保存为草稿(不触发审核流程)
/**
* 子任务项DTO

View File

@ -360,11 +360,21 @@ public class TaskService {
}
}
// 【两级审核流程】初始化审核状态
initApprovalStatus(task);
// 🔥 是否保存为草稿(不触发审核流程)
boolean asDraft = dto.getAsDraft() != null && dto.getAsDraft();
if (asDraft) {
// 草稿模式:保持草稿状态,不初始化审核流程
task.setStatus("draft");
task.setApprovalStatus("draft");
log.info("保存为草稿模式,不触发审核流程");
} else {
// 【两级审核流程】初始化审核状态
initApprovalStatus(task);
}
taskMapper.insert(task);
log.info("主任务创建成功,ID: {}, 任务编号: {}", task.getId(), task.getTaskNo());
log.info("主任务创建成功,ID: {}, 任务编号: {}, 草稿模式: {}", task.getId(), task.getTaskNo(), asDraft);
// **步骤1:按接单部门和设计师自动分组**
// 遍历任务类型列表,根据接单部门和设计师分组
@ -643,8 +653,10 @@ public class TaskService {
log.info("流水线任务创建完成,主任务ID: {}, 子任务数: {}, 部门数: {}",
task.getId(), groupedItems.size(), deptToGroups.size());
// 【两级审核流程】发送审核通知给部门负责人
sendApprovalNotification(task);
// 【两级审核流程】发送审核通知给部门负责人(草稿模式不发送)
if (!asDraft) {
sendApprovalNotification(task);
}
return task.getId();
}

View File

@ -539,6 +539,14 @@
<a-button size="large" @click="handleCancel">
取消
</a-button>
<a-button
size="large"
:loading="savingDraft"
@click="handleSaveDraft"
>
<Icon name="save" size="sm" style="margin-right: 4px;" />
保存草稿
</a-button>
<a-button
type="primary"
size="large"
@ -591,6 +599,7 @@ const formRef = ref<FormInstance>()
// 提交状态
const submitting = ref(false)
const savingDraft = ref(false)
const loading = ref(false)
// 团队积分余额
@ -1365,6 +1374,92 @@ const handleCancel = () => {
router.back()
}
// 保存草稿
const handleSaveDraft = async () => {
savingDraft.value = true
try {
// 基本验证:至少需要标题
if (!formData.title || formData.title.trim() === '') {
message.warning('请至少填写任务标题')
savingDraft.value = false
return
}
// 构建附件URL(如果有上传的文件)
const attachmentUrls = fileList.value
.filter(file => {
return file.status === 'done' && (
file.response?.fileUrl ||
file.response?.data?.[0] ||
file.url
)
})
.map(file => {
return file.response?.fileUrl ||
file.response?.data?.[0] ||
file.url ||
''
})
.filter(url => url)
const attachmentUrl = attachmentUrls.length > 0 ? attachmentUrls.join(',') : formData.attachmentUrl
// 获取有效的任务类型(允许部分填写)
const validTaskTypes = formData.taskTypes.filter(item => item.taskTypeId)
// 构建草稿数据
const draftData = {
title: formData.title,
isPipeline: true,
pipelineMode: 'sequential',
items: validTaskTypes.map((item, index) => ({
taskTypeId: item.taskTypeId!,
quantity: item.quantity || 1,
sortOrder: index + 1,
selectedDesignerId: item.selectedDesignerId || undefined,
selectedDeptId: item.selectedDeptId || undefined
})),
brandId: formData.brandId || undefined,
categoryId: formData.categoryId || undefined,
platformId: formData.platformId || undefined,
spuInfo: formData.spuInfo || undefined,
taskSubType: formData.taskSubType || undefined,
attachmentUrl: attachmentUrl || undefined,
previewImage: formData.previewImage || undefined,
releaseType: formData.releaseType || 'recruitment',
asDraft: true // 标记为草稿
}
let response
if (editMode.value && taskId.value) {
// 编辑模式:更新草稿
response = await taskApi.updateTask(taskId.value, { ...draftData, status: 'draft' })
} else {
// 新建模式:创建草稿
response = await taskApi.createPipelineTask(draftData)
}
if (response.code === 200) {
message.success('草稿保存成功')
// 如果是新建,更新为编辑模式
if (!editMode.value && response.data?.id) {
router.replace({
path: '/tasks/create',
query: { taskId: response.data.id, mode: 'edit' }
})
}
} else {
message.error(response.msg || '保存草稿失败')
}
} catch (error: any) {
console.error('保存草稿失败:', error)
message.error(error.msg || error.message || '保存草稿失败')
} finally {
savingDraft.value = false
}
}
// 提交
const handleSubmit = async () => {
if (!formRef.value) return