|
|
@@ -1625,6 +1625,8 @@ onSearchInput(event: Event): void {
|
|
|
const projectQuery = new Parse.Query('Project');
|
|
|
projectQuery.equalTo('company', cid);
|
|
|
projectQuery.notEqualTo('isDeleted', true);
|
|
|
+ // 关键:包含 assignee 指针,避免出现 assignee.get 不是函数
|
|
|
+ projectQuery.include('assignee');
|
|
|
projectQuery.limit(100);
|
|
|
|
|
|
const projects = await projectQuery.find();
|
|
|
@@ -1637,7 +1639,7 @@ onSearchInput(event: Event): void {
|
|
|
const phaseDeadlines = data.phaseDeadlines || {};
|
|
|
|
|
|
// 获取小图对图时间
|
|
|
- const reviewDate = project.get('demoday') || project.get('reviewDate');
|
|
|
+ let reviewDate = project.get('demoday') || project.get('reviewDate');
|
|
|
|
|
|
// 获取交付时间
|
|
|
const deliveryDate = project.get('deadline') ||
|
|
|
@@ -1652,15 +1654,90 @@ onSearchInput(event: Event): void {
|
|
|
|
|
|
// 获取设计师名称
|
|
|
const assignee = project.get('assignee');
|
|
|
- const designerName = assignee?.get('name') || assignee?.get('realname') || '未分配';
|
|
|
+ let designerName: string = '未分配';
|
|
|
+ let designerId: string | undefined = undefined;
|
|
|
+ if (assignee) {
|
|
|
+ // 兼容 Parse.Object / 普通对象 / 字符串ID
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
+ const anyAssignee: any = assignee;
|
|
|
+ designerId = anyAssignee?.id || (typeof anyAssignee === 'string' ? anyAssignee : undefined);
|
|
|
+ if (typeof anyAssignee?.get === 'function') {
|
|
|
+ designerName = anyAssignee.get('name') || anyAssignee.get('realname') || anyAssignee.get('realName') || '未分配';
|
|
|
+ } else if (typeof anyAssignee === 'object') {
|
|
|
+ designerName = anyAssignee.name || anyAssignee.realname || anyAssignee.realName || '未分配';
|
|
|
+ } else if (typeof anyAssignee === 'string') {
|
|
|
+ // 如果后端直接存ID字符串,这里先显示ID占位,避免崩溃
|
|
|
+ designerName = anyAssignee;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 获取空间交付物汇总
|
|
|
const spaceDeliverableSummary = data.spaceDeliverableSummary;
|
|
|
+
|
|
|
+ // ===== 复用组长端的回退计算逻辑,补齐缺失的 reviewDate 与 phaseDeadlines =====
|
|
|
+ // 计算today,以便生成合理的回退时间
|
|
|
+ const now = new Date();
|
|
|
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
|
+
|
|
|
+ // 若 reviewDate 缺失且存在交付日期,则将其设置在项目周期60%位置(下午2点)
|
|
|
+ if (!reviewDate && deliveryDate && startDate) {
|
|
|
+ const end = new Date(deliveryDate).getTime();
|
|
|
+ const start = new Date(startDate).getTime();
|
|
|
+ const mid = start + Math.max(0, Math.floor((end - start) * 0.6));
|
|
|
+ const midDate = new Date(mid);
|
|
|
+ midDate.setHours(14, 0, 0, 0);
|
|
|
+ reviewDate = midDate;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 若缺少阶段截止时间,按交付日期向前推算(后期=交付日,渲染=交付-1天,软装=交付-2天,建模=交付-3天)
|
|
|
+ let phaseDeadlinesFallback = phaseDeadlines;
|
|
|
+ if ((!phaseDeadlinesFallback || Object.keys(phaseDeadlinesFallback).length === 0) && deliveryDate && startDate) {
|
|
|
+ const deliveryTime = new Date(deliveryDate).getTime();
|
|
|
+ const postProcessingDeadline = new Date(deliveryTime);
|
|
|
+ const renderingDeadline = new Date(deliveryTime - 1 * 24 * 60 * 60 * 1000);
|
|
|
+ const softDecorDeadline = new Date(deliveryTime - 2 * 24 * 60 * 60 * 1000);
|
|
|
+ const modelingDeadline = new Date(deliveryTime - 3 * 24 * 60 * 60 * 1000);
|
|
|
+
|
|
|
+ phaseDeadlinesFallback = {
|
|
|
+ modeling: {
|
|
|
+ startDate: new Date(startDate),
|
|
|
+ deadline: modelingDeadline,
|
|
|
+ estimatedDays: 1,
|
|
|
+ status: now.getTime() >= modelingDeadline.getTime() && now.getTime() < softDecorDeadline.getTime() ? 'in_progress' :
|
|
|
+ now.getTime() >= softDecorDeadline.getTime() ? 'completed' : 'not_started',
|
|
|
+ priority: 'high'
|
|
|
+ },
|
|
|
+ softDecor: {
|
|
|
+ startDate: modelingDeadline,
|
|
|
+ deadline: softDecorDeadline,
|
|
|
+ estimatedDays: 1,
|
|
|
+ status: now.getTime() >= softDecorDeadline.getTime() && now.getTime() < renderingDeadline.getTime() ? 'in_progress' :
|
|
|
+ now.getTime() >= renderingDeadline.getTime() ? 'completed' : 'not_started',
|
|
|
+ priority: 'medium'
|
|
|
+ },
|
|
|
+ rendering: {
|
|
|
+ startDate: softDecorDeadline,
|
|
|
+ deadline: renderingDeadline,
|
|
|
+ estimatedDays: 1,
|
|
|
+ status: now.getTime() >= renderingDeadline.getTime() && now.getTime() < postProcessingDeadline.getTime() ? 'in_progress' :
|
|
|
+ now.getTime() >= postProcessingDeadline.getTime() ? 'completed' : 'not_started',
|
|
|
+ priority: 'high'
|
|
|
+ },
|
|
|
+ postProcessing: {
|
|
|
+ startDate: renderingDeadline,
|
|
|
+ deadline: postProcessingDeadline,
|
|
|
+ estimatedDays: 1,
|
|
|
+ status: now.getTime() >= postProcessingDeadline.getTime() ? 'completed' :
|
|
|
+ now.getTime() >= renderingDeadline.getTime() ? 'in_progress' : 'not_started',
|
|
|
+ priority: 'medium'
|
|
|
+ }
|
|
|
+ } as any;
|
|
|
+ }
|
|
|
|
|
|
return {
|
|
|
projectId: project.id,
|
|
|
projectName: project.get('name') || project.get('title') || '未命名项目',
|
|
|
- designerId: assignee?.id,
|
|
|
+ designerId,
|
|
|
designerName,
|
|
|
startDate: startDate ? new Date(startDate) : new Date(),
|
|
|
endDate: deliveryDate ? new Date(deliveryDate) : new Date(),
|
|
|
@@ -1676,7 +1753,7 @@ onSearchInput(event: Event): void {
|
|
|
priority: 'medium' as const,
|
|
|
spaceName: '',
|
|
|
customerName: project.get('customerName') || '',
|
|
|
- phaseDeadlines,
|
|
|
+ phaseDeadlines: phaseDeadlinesFallback,
|
|
|
spaceDeliverableSummary
|
|
|
};
|
|
|
});
|
|
|
@@ -1701,14 +1778,14 @@ onSearchInput(event: Event): void {
|
|
|
try {
|
|
|
// 从 projectTimelineData 中提取数据
|
|
|
this.projectTimelineData.forEach(project => {
|
|
|
- // 1. 检查小图对图事件
|
|
|
+ // 1. 检查小图对图事件(与组长端一致)
|
|
|
if (project.reviewDate) {
|
|
|
const reviewTime = project.reviewDate.getTime();
|
|
|
const timeDiff = reviewTime - now.getTime();
|
|
|
const daysDiff = Math.ceil(timeDiff / oneDayMs);
|
|
|
|
|
|
- // 如果小图对图已经到期或即将到期(1天内),且不在已完成状态
|
|
|
- if (daysDiff <= 1 && project.currentStage !== 'delivery' && project.currentStage !== '已完成' && project.currentStage !== '交付完成') {
|
|
|
+ // 如果小图对图已经到期或即将到期(1天内),且不在交付完成阶段
|
|
|
+ if (daysDiff <= 1 && project.currentStage !== 'delivery') {
|
|
|
events.push({
|
|
|
id: `${project.projectId}-review`,
|
|
|
title: `小图对图截止`,
|
|
|
@@ -1724,14 +1801,14 @@ onSearchInput(event: Event): void {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 2. 检查交付事件
|
|
|
+ // 2. 检查交付事件(与组长端一致)
|
|
|
if (project.deliveryDate) {
|
|
|
const deliveryTime = project.deliveryDate.getTime();
|
|
|
const timeDiff = deliveryTime - now.getTime();
|
|
|
const daysDiff = Math.ceil(timeDiff / oneDayMs);
|
|
|
|
|
|
- // 如果交付已经到期或即将到期(1天内),且不在已完成状态
|
|
|
- if (daysDiff <= 1 && project.currentStage !== 'delivery' && project.currentStage !== '已完成' && project.currentStage !== '交付完成') {
|
|
|
+ // 如果交付已经到期或即将到期(1天内),且不在交付完成阶段
|
|
|
+ if (daysDiff <= 1 && project.currentStage !== 'delivery') {
|
|
|
const summary = project.spaceDeliverableSummary;
|
|
|
const completionRate = summary?.overallCompletionRate || 0;
|
|
|
|