|
|
@@ -272,8 +272,17 @@ export class Dashboard implements OnInit, OnDestroy {
|
|
|
phases: [],
|
|
|
expectedEndDate: deadline,
|
|
|
|
|
|
- isStalled: false, // 暂无数据
|
|
|
- isModification: false, // 暂无数据
|
|
|
+ // 🔥 修复:从 data 字段读取停滞期/改图期状态和原因信息(防止云函数覆盖)
|
|
|
+ isStalled: p.data?.isStalled === true,
|
|
|
+ isModification: p.data?.isModification === true,
|
|
|
+ stagnationReasonType: p.data?.stagnationReasonType,
|
|
|
+ stagnationCustomReason: p.data?.stagnationCustomReason,
|
|
|
+ modificationReasonType: p.data?.modificationReasonType,
|
|
|
+ modificationCustomReason: p.data?.modificationCustomReason,
|
|
|
+ estimatedResumeDate: p.data?.estimatedResumeDate ? new Date(p.data.estimatedResumeDate) : undefined,
|
|
|
+ reasonNotes: p.data?.reasonNotes,
|
|
|
+ markedAt: p.data?.markedAt ? new Date(p.data.markedAt) : undefined,
|
|
|
+ markedBy: p.data?.markedBy,
|
|
|
|
|
|
isOverdue: isOverdue,
|
|
|
overdueDays: isOverdue ? Math.abs(daysLeft) : 0,
|
|
|
@@ -1510,13 +1519,20 @@ export class Dashboard implements OnInit, OnDestroy {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- createTodoFromEvent(event: UrgentEvent): void {
|
|
|
+ /**
|
|
|
+ * 🔥 将紧急事件转为待办问题(持久化到数据库)
|
|
|
+ */
|
|
|
+ async createTodoFromEvent(event: UrgentEvent): Promise<void> {
|
|
|
const now = new Date();
|
|
|
+
|
|
|
+ // 1. 创建本地任务对象(用于立即显示)
|
|
|
+ const tempId = `urgent-todo-${event.id}-${now.getTime()}`;
|
|
|
const newTask: TodoTaskFromIssue = {
|
|
|
- id: `urgent-todo-${event.id}-${now.getTime()}`,
|
|
|
+ id: tempId,
|
|
|
title: `【紧急】${event.title}`,
|
|
|
description: event.description,
|
|
|
- priority: event.urgencyLevel === 'critical' ? 'urgent' : event.urgencyLevel === 'high' ? 'high' : 'medium',
|
|
|
+ priority: event.urgencyLevel === 'critical' ? 'urgent' :
|
|
|
+ event.urgencyLevel === 'high' ? 'high' : 'medium',
|
|
|
type: 'feedback',
|
|
|
status: 'open',
|
|
|
projectId: event.projectId,
|
|
|
@@ -1529,8 +1545,110 @@ export class Dashboard implements OnInit, OnDestroy {
|
|
|
dueDate: event.deadline,
|
|
|
tags: [...(event.labels || []), '来自紧急事件']
|
|
|
};
|
|
|
+
|
|
|
+ // 2. 立即添加到内存(优先显示给用户)
|
|
|
this.todoTasksFromIssues = [newTask, ...this.todoTasksFromIssues];
|
|
|
- this.resolveUrgentEvent(event);
|
|
|
+ this.cdr.markForCheck();
|
|
|
+
|
|
|
+ // 3. 🔥 保存到数据库(关键修复)
|
|
|
+ try {
|
|
|
+ console.log('💾 [待办问题] 开始保存到数据库...', {
|
|
|
+ projectId: event.projectId,
|
|
|
+ title: newTask.title
|
|
|
+ });
|
|
|
+
|
|
|
+ // 获取当前用户的 Profile ID
|
|
|
+ const cid = localStorage.getItem("company");
|
|
|
+ if (!cid) {
|
|
|
+ throw new Error('无法获取公司ID');
|
|
|
+ }
|
|
|
+
|
|
|
+ const wwAuth = new WxworkAuth({ cid });
|
|
|
+ const profile = await wwAuth.currentProfile();
|
|
|
+ const creatorId = profile?.id;
|
|
|
+
|
|
|
+ if (!creatorId) {
|
|
|
+ throw new Error('无法获取当前用户ID');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建 ProjectIssue 对象
|
|
|
+ const ProjectIssue = Parse.Object.extend('ProjectIssue');
|
|
|
+ const issueObj = new ProjectIssue();
|
|
|
+
|
|
|
+ issueObj.set('project', {
|
|
|
+ __type: 'Pointer',
|
|
|
+ className: 'Project',
|
|
|
+ objectId: event.projectId
|
|
|
+ });
|
|
|
+ issueObj.set('title', newTask.title);
|
|
|
+ issueObj.set('description', newTask.description || '');
|
|
|
+ issueObj.set('priority', newTask.priority);
|
|
|
+ issueObj.set('issueType', newTask.type);
|
|
|
+ issueObj.set('status', '待处理'); // 使用中文状态
|
|
|
+ issueObj.set('creator', {
|
|
|
+ __type: 'Pointer',
|
|
|
+ className: 'Profile',
|
|
|
+ objectId: creatorId
|
|
|
+ });
|
|
|
+
|
|
|
+ // 设置关联信息
|
|
|
+ if (newTask.relatedStage) {
|
|
|
+ issueObj.set('relatedStage', newTask.relatedStage);
|
|
|
+ }
|
|
|
+ if (newTask.dueDate) {
|
|
|
+ issueObj.set('dueDate', newTask.dueDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置 data 字段
|
|
|
+ issueObj.set('data', {
|
|
|
+ tags: newTask.tags || [],
|
|
|
+ comments: [],
|
|
|
+ relatedStage: newTask.relatedStage,
|
|
|
+ sourceEvent: {
|
|
|
+ eventId: event.id,
|
|
|
+ eventType: 'urgent',
|
|
|
+ convertedAt: new Date(),
|
|
|
+ convertedBy: creatorId
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ issueObj.set('isDeleted', false);
|
|
|
+
|
|
|
+ // 保存到数据库
|
|
|
+ const saved = await issueObj.save();
|
|
|
+
|
|
|
+ console.log('✅ [待办问题] 保存成功:', saved.id);
|
|
|
+
|
|
|
+ // 4. 更新内存中的任务ID(从临时ID改为真实ID)
|
|
|
+ this.todoTasksFromIssues = this.todoTasksFromIssues.map(task => {
|
|
|
+ if (task.id === tempId) {
|
|
|
+ return {
|
|
|
+ ...task,
|
|
|
+ id: saved.id // 使用数据库返回的真实ID
|
|
|
+ };
|
|
|
+ }
|
|
|
+ return task;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 5. 标记紧急事件为已处理
|
|
|
+ this.resolveUrgentEvent(event);
|
|
|
+
|
|
|
+ console.log('✅ [待办问题] 紧急事件已转为待办问题');
|
|
|
+ window?.fmode?.alert('已成功转为待办问题');
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('❌ [待办问题] 保存失败:', error);
|
|
|
+
|
|
|
+ // 保存失败,从内存中移除(避免误导用户)
|
|
|
+ this.todoTasksFromIssues = this.todoTasksFromIssues.filter(
|
|
|
+ task => task.id !== tempId
|
|
|
+ );
|
|
|
+
|
|
|
+ const errorMsg = error instanceof Error ? error.message : '未知错误';
|
|
|
+ window?.fmode?.alert(`保存失败:${errorMsg}\n请重试`);
|
|
|
+ } finally {
|
|
|
+ this.cdr.markForCheck();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 待办任务操作(由子组件触发)
|