fix: 修复多个问题
1. 修复部门负责人看不到任务关联信息(品牌、类目、平台) - TaskService.getTaskById增加fillTaskRelatedInfo方法填充所有关联信息 2. 修复调整任务类型数量时积分同步显示 - 审核弹窗添加预估积分实时计算和显示 3. 修复流水线任务拆分后母任务不再显示在任务大厅 - TaskMapper添加is_pipeline=0条件 4. 修复驳回任务显示'草稿'问题 - 驳回时保存rejectReason到数据库 - 前端正确判断并显示'已驳回'状态 5. 修复重新编辑被驳回任务时数据丢失问题 - loadTaskForEdit完善所有字段加载 - 显示驳回原因提示用户修改 - 添加remark字段到formData 6. 修复进行中任务卡片缺少'指定'标签显示
This commit is contained in:
parent
3ba4a5f7f7
commit
571388f414
@ -36,7 +36,7 @@ public interface TaskMapper extends BaseMapper<Task> {
|
||||
"LEFT JOIN category c ON t.category_id = c.id " +
|
||||
"LEFT JOIN platform p ON t.platform_id = p.id " +
|
||||
"LEFT JOIN sys_user approver ON t.current_approver_id = approver.id " +
|
||||
"WHERE t.status = 'pending' AND t.release_type = 'recruitment' AND t.approval_status = 'approved' AND t.deleted = 0" +
|
||||
"WHERE t.status = 'pending' AND t.release_type = 'recruitment' AND t.approval_status = 'approved' AND t.deleted = 0 AND (t.is_pipeline = 0 OR t.is_pipeline IS NULL)" +
|
||||
"<if test='taskTypeId != null'> AND t.task_type_id = #{taskTypeId}</if>" +
|
||||
"<if test='demandTypeId != null'> AND t.demand_type_id = #{demandTypeId}</if>" +
|
||||
"<if test='brandId != null'> AND t.brand_id = #{brandId}</if>" +
|
||||
|
||||
@ -170,6 +170,7 @@ public class TaskApprovalService {
|
||||
|
||||
task.setApprovalStatus("rejected_by_demand");
|
||||
task.setStatus("draft");
|
||||
task.setRejectReason(reason); // 保存驳回原因
|
||||
task.setCurrentApproverId(null);
|
||||
task.setCurrentApproverRole(null);
|
||||
taskMapper.updateById(task);
|
||||
@ -461,6 +462,7 @@ public class TaskApprovalService {
|
||||
|
||||
task.setApprovalStatus("rejected_by_receiving");
|
||||
task.setStatus("draft");
|
||||
task.setRejectReason(reason); // 保存驳回原因
|
||||
task.setCurrentApproverId(demandDept.getLeaderId());
|
||||
task.setCurrentApproverRole("demand_leader");
|
||||
taskMapper.updateById(task);
|
||||
|
||||
@ -12,6 +12,9 @@ import com.designhub.exception.BusinessException;
|
||||
import com.designhub.mapper.TaskAuditLogMapper;
|
||||
import com.designhub.mapper.TaskAssignLogMapper;
|
||||
import com.designhub.mapper.TaskMapper;
|
||||
import com.designhub.mapper.BrandMapper;
|
||||
import com.designhub.mapper.CategoryMapper;
|
||||
import com.designhub.mapper.PlatformMapper;
|
||||
import com.designhub.vo.DashboardStatsVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -40,6 +43,9 @@ public class TaskService {
|
||||
private final TaskMapper taskMapper;
|
||||
private final TaskAuditLogMapper taskAuditLogMapper;
|
||||
private final TaskAssignLogMapper taskAssignLogMapper;
|
||||
private final BrandMapper brandMapper;
|
||||
private final CategoryMapper categoryMapper;
|
||||
private final PlatformMapper platformMapper;
|
||||
private final TeamScorePoolService teamScorePoolService;
|
||||
private final ConfigService configService;
|
||||
private final DelayPenaltyService delayPenaltyService;
|
||||
@ -723,8 +729,76 @@ public class TaskService {
|
||||
if (task == null) {
|
||||
throw new BusinessException(ResultCode.TASK_NOT_EXIST);
|
||||
}
|
||||
|
||||
// 填充关联信息
|
||||
fillTaskRelatedInfo(task);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充任务关联信息(品牌、类目、平台、发布人等)
|
||||
*/
|
||||
private void fillTaskRelatedInfo(Task task) {
|
||||
// 填充品牌名称
|
||||
if (task.getBrandId() != null) {
|
||||
Brand brand = brandMapper.selectById(task.getBrandId());
|
||||
if (brand != null) {
|
||||
task.setBrandName(brand.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充类目名称
|
||||
if (task.getCategoryId() != null) {
|
||||
Category category = categoryMapper.selectById(task.getCategoryId());
|
||||
if (category != null) {
|
||||
task.setCategoryName(category.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充平台名称
|
||||
if (task.getPlatformId() != null) {
|
||||
Platform platform = platformMapper.selectById(task.getPlatformId());
|
||||
if (platform != null) {
|
||||
task.setPlatformName(platform.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充发布人名称
|
||||
if (task.getPublisherId() != null) {
|
||||
User publisher = userService.getUserById(task.getPublisherId());
|
||||
if (publisher != null) {
|
||||
task.setPublisherName(publisher.getRealName() != null ? publisher.getRealName() : publisher.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充发布人部门名称
|
||||
if (task.getPublisherDeptId() != null) {
|
||||
Department dept = departmentService.getDepartmentById(task.getPublisherDeptId());
|
||||
if (dept != null) {
|
||||
task.setPublisherDeptName(dept.getDeptName());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充接收人名称
|
||||
if (task.getReceiverId() != null) {
|
||||
User receiver = userService.getUserById(task.getReceiverId());
|
||||
if (receiver != null) {
|
||||
task.setReceiverName(receiver.getRealName() != null ? receiver.getRealName() : receiver.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充当前审核人名称
|
||||
if (task.getCurrentApproverId() != null) {
|
||||
User approver = userService.getUserById(task.getCurrentApproverId());
|
||||
if (approver != null) {
|
||||
task.setCurrentApproverName(approver.getRealName() != null ? approver.getRealName() : approver.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充子任务统计信息
|
||||
fillSubTaskStats(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
|
||||
@ -467,6 +467,7 @@ const formData = reactive({
|
||||
categoryId: undefined,
|
||||
spuInfo: '',
|
||||
attachmentUrl: '',
|
||||
remark: '', // 备注信息
|
||||
releaseType: 'default',
|
||||
// receiverId: undefined, // 已移除,改用子任务指定
|
||||
isUrgent: false
|
||||
@ -796,7 +797,7 @@ const handleSubmit = async () => {
|
||||
spuInfo: formData.spuInfo,
|
||||
taskSubType: formData.taskSubType,
|
||||
attachmentUrl: attachmentUrl,
|
||||
remark: '',
|
||||
remark: formData.remark || '',
|
||||
priority: formData.isUrgent ? 3 : 1, // 0-低 1-普通 2-高 3-紧急
|
||||
releaseType: formData.releaseType, // 发布类型
|
||||
receiverId: undefined // 主任务不设接收人,由子任务指定
|
||||
@ -1042,7 +1043,7 @@ const loadTaskForEdit = async (taskId: number) => {
|
||||
const task = response.data
|
||||
|
||||
if (task) {
|
||||
// 填充表单数据
|
||||
// 填充基本表单数据
|
||||
formData.title = task.title || ''
|
||||
formData.taskSubType = task.taskSubType || ''
|
||||
formData.brandId = task.brandId
|
||||
@ -1051,32 +1052,50 @@ const loadTaskForEdit = async (taskId: number) => {
|
||||
formData.spuInfo = task.spuInfo || ''
|
||||
formData.remark = task.remark || ''
|
||||
formData.releaseType = task.releaseType || 'recruitment'
|
||||
formData.isUrgent = task.isUrgent === 1 || task.isUrgent === true
|
||||
|
||||
// 处理任务类型
|
||||
// 处理任务类型和数量
|
||||
if (task.taskTypeIds) {
|
||||
const typeIds = task.taskTypeIds.split(',').map((id: string) => parseInt(id.trim()))
|
||||
// 尝试获取每个类型对应的数量(如果有taskItems,从中获取)
|
||||
formData.taskTypes = typeIds.map((typeId: number, index: number) => ({
|
||||
taskTypeId: typeId,
|
||||
quantity: index === 0 ? (task.quantity || 1) : 1,
|
||||
receiverId: task.receiverId
|
||||
}))
|
||||
} else if (task.taskTypeId) {
|
||||
// 兼容单任务类型
|
||||
formData.taskTypes = [{
|
||||
taskTypeId: task.taskTypeId,
|
||||
quantity: task.quantity || 1,
|
||||
receiverId: task.receiverId
|
||||
}]
|
||||
}
|
||||
|
||||
// 处理附件
|
||||
// 处理附件 - 完整加载原有附件
|
||||
if (task.attachmentUrl) {
|
||||
formData.attachmentUrl = task.attachmentUrl
|
||||
// 将附件URL转换为fileList格式
|
||||
const urls = task.attachmentUrl.split(',').filter((u: string) => u.trim())
|
||||
fileList.value = urls.map((url: string, index: number) => ({
|
||||
uid: `existing-${index}`,
|
||||
name: `附件${index + 1}`,
|
||||
status: 'done',
|
||||
url: url.trim()
|
||||
}))
|
||||
fileList.value = urls.map((url: string, index: number) => {
|
||||
const fileName = url.split('/').pop() || `附件${index + 1}`
|
||||
return {
|
||||
uid: `existing-${index}`,
|
||||
name: fileName,
|
||||
status: 'done' as const,
|
||||
url: url.trim()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
editMode.value = true
|
||||
editTaskId.value = taskId
|
||||
|
||||
// 显示驳回原因提示(如果是被驳回的任务)
|
||||
if (task.rejectReason) {
|
||||
message.warning(`驳回原因:${task.rejectReason},请修改后重新提交`)
|
||||
}
|
||||
|
||||
console.log('任务数据加载成功:', task)
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@ -800,6 +800,10 @@
|
||||
<Icon name="layers" size="sm" color="#1890ff" style="margin-right: 4px; vertical-align: middle;" />
|
||||
子任务
|
||||
</span>
|
||||
<span v-if="task.releaseType === 'assigned'" class="badge badge-assigned">
|
||||
<Icon name="target" size="sm" color="#1890ff" style="margin-right: 4px; vertical-align: middle;" />
|
||||
指定
|
||||
</span>
|
||||
<span class="badge badge-in-progress">
|
||||
<Icon name="clock" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
|
||||
进行中
|
||||
@ -1894,6 +1898,19 @@
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预估积分显示 -->
|
||||
<div class="score-summary" style="margin-top: 16px; padding: 12px; background: linear-gradient(135deg, #1a3a2a 0%, #0d1f16 100%); border-radius: 8px; border: 1px solid #31f08b33;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span style="color: #888; font-size: 14px;">预估总积分</span>
|
||||
<span style="color: #31f08b; font-size: 24px; font-weight: 600;">{{ approveEstimatedScore }} 分</span>
|
||||
</div>
|
||||
<div style="margin-top: 8px; font-size: 12px; color: #666;">
|
||||
<span v-for="(item, index) in approveTaskTypes" :key="index" style="margin-right: 12px;">
|
||||
{{ getTaskTypeName(item.typeId) }}: {{ getTaskTypeUnitScore(item.typeId) }} × {{ item.quantity }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 接单方式 -->
|
||||
@ -2389,6 +2406,20 @@ const getTaskTypeName = (typeId: number) => {
|
||||
return type?.name || '未知类型'
|
||||
}
|
||||
|
||||
// 获取任务类型单位积分
|
||||
const getTaskTypeUnitScore = (typeId: number) => {
|
||||
const type = demandTypes.value.find(t => t.id === typeId)
|
||||
return type?.unitScore || 0
|
||||
}
|
||||
|
||||
// 计算审核弹窗中的预估总积分
|
||||
const approveEstimatedScore = computed(() => {
|
||||
return approveTaskTypes.value.reduce((total, item) => {
|
||||
const unitScore = getTaskTypeUnitScore(item.typeId)
|
||||
return total + (unitScore * item.quantity)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (time: string | undefined) => {
|
||||
if (!time) return '--'
|
||||
@ -3888,10 +3919,15 @@ const handleConfigUpdate = async (event: CustomEvent) => {
|
||||
// 获取任务状态文本(增强版,支持区分驳回和草稿)
|
||||
const getTaskStatusText = (status: string, task?: any) => {
|
||||
// 如果有task对象,检查approvalStatus来区分驳回和草稿
|
||||
if (task && status === 'draft') {
|
||||
if (task) {
|
||||
// 检查是否被驳回(无论status是draft还是rejected)
|
||||
if (task.approvalStatus === 'rejected_by_demand' || task.approvalStatus === 'rejected_by_receiving') {
|
||||
return '已驳回'
|
||||
}
|
||||
// 检查status是否是rejected
|
||||
if (status === 'rejected') {
|
||||
return '已驳回'
|
||||
}
|
||||
}
|
||||
|
||||
const statusMap: Record<string, string> = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user