canEdit 限制)project-detail.component.html修改内容:
badge-action 按钮$eventtitle 提示修改前:
<div class="status-badge stalled" (click)="cancelStagnation()">
...
<div class="badge-action">
<svg>...</svg>
</div>
</div>
修改后:
<div class="status-badge stalled">
...
<div class="badge-action" (click)="cancelStagnation($event)" title="点击取消停滞期">
<svg>...</svg>
</div>
</div>
project-detail.component.ts修改内容:
event?: Eventevent.stopPropagation() 和 event.preventDefault()canEdit 权限检查delete 而不是 undefined 清除字段修改前:
async cancelStagnation() {
if (!this.project || !this.canEdit) return;
// ... 清除字段
data.stagnationReasonType = undefined;
// ...
}
修改后:
async cancelStagnation(event?: Event) {
// 阻止事件冒泡
if (event) {
event.stopPropagation();
event.preventDefault();
}
if (!this.project) {
console.warn('❌ 项目数据不存在');
return;
}
// 确认对话框
const confirmed = confirm('确定要取消该项目的停滞期状态吗?');
if (!confirmed) return;
try {
console.log('🔄 [取消停滞期] 开始取消...');
const data = this.project.get('data') || {};
// 清除停滞期相关字段
data.isStalled = false;
delete data.stagnationReasonType;
delete data.stagnationCustomReason;
delete data.estimatedResumeDate;
delete data.reasonNotes;
delete data.markedAt;
delete data.markedBy;
this.project.set('data', data);
await this.project.save();
console.log('✅ 停滞期标记已取消');
window?.fmode?.alert('停滞期标记已取消');
await this.loadData();
} catch (err) {
console.error('❌ 取消停滞期失败:', err);
window?.fmode?.alert('操作失败,请重试');
}
}
project-detail.component.scss修改内容:
.badge-action 添加完整的交互样式.stalled 徽章整体的点击样式修改前:
.badge-action {
.icon {
width: 20px;
height: 20px;
color: #94a3b8;
transition: color 0.2s;
}
&:hover .icon {
color: #ef4444;
}
}
&.stalled {
border-left: 4px solid #8b5cf6;
cursor: pointer; // ❌ 移除
&:active {
transform: translateX(-4px) scale(0.98); // ❌ 移除
}
}
修改后:
.badge-action {
cursor: pointer; // ✅ 新增
padding: 4px; // ✅ 新增
border-radius: 4px; // ✅ 新增
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
.icon {
width: 20px;
height: 20px;
color: #94a3b8;
transition: color 0.2s;
pointer-events: none; // ✅ 防止拦截点击
}
&:hover {
background: rgba(239, 68, 68, 0.1); // ✅ 悬停背景
.icon {
color: #ef4444;
}
}
&:active {
transform: scale(0.95); // ✅ 点击反馈
}
}
&.stalled {
border-left: 4px solid #8b5cf6;
// ✅ 移除了 cursor: pointer 和 &:active
}
文件:stage-delivery.component.ts
实现位置:onFileUploaded() 方法(第441-490行)
逻辑:
async onFileUploaded(event) {
if (event.fileCount > 0 && this.project) {
const projectData = this.project.get('data') || {};
// 检查是否处于改图期
if (projectData.isModification === true) {
console.log('🎨 [改图期] 上传文件后自动取消改图期标记');
// 清除改图期相关字段
projectData.isModification = false;
projectData.modificationReasonType = undefined;
projectData.modificationCustomReason = undefined;
this.project.set('data', projectData);
await this.project.save(); // ✅ 立即保存
console.log('✅ [改图期] 改图期标记已保存到数据库');
}
}
}
触发场景:
文件:stage-delivery-execution.component.ts
实现位置:confirmSpace() 方法(第975-983行)
逻辑:
async confirmSpace(spaceId: string) {
try {
const data = this.project.get('data') || {};
// ... 空间确认逻辑
// 确认交付清单时自动取消改图期标记
if (data.isModification === true) {
console.log('🎨 [改图期] 确认交付清单,自动取消改图期标记');
data.isModification = false;
delete data.modificationReasonType;
delete data.modificationCustomReason;
console.log('✅ [改图期] 改图期标记已取消');
}
this.project.set('data', data);
await this.project.save(); // ✅ 保存
} catch (error) {
console.error('确认空间失败:', error);
}
}
触发场景:
步骤:
isStalled = false预期日志:
🔄 [取消停滞期] 开始取消...
✅ 停滞期标记已取消
步骤:
预期日志:
🎨 [改图期] 检测到项目处于改图期,上传文件后自动取消改图期标记
✅ [改图期] 改图期标记已准备取消,等待保存
✅ [改图期] 改图期标记已保存到数据库
步骤:
isModification = false预期日志:
🎨 [改图期] 确认交付清单,自动取消改图期标记
✅ [改图期] 改图期标记已取消
// 查询所有停滞期/改图期项目
const query = new Parse.Query('Project');
const projects = await query.find();
projects.forEach(p => {
const data = p.get('data') || {};
if (data.isStalled || data.isModification) {
console.log('📋 项目:', p.get('title'));
console.log(' - ID:', p.id);
console.log(' - 停滞期:', data.isStalled);
console.log(' - 改图期:', data.isModification);
console.log(' - 停滞原因:', data.stagnationReasonType);
console.log(' - 改图原因:', data.modificationReasonType);
console.log(' ---');
}
});
// 替换为实际项目ID
const projectId = 'YOUR_PROJECT_ID';
const query = new Parse.Query('Project');
const project = await query.get(projectId);
const data = project.get('data') || {};
console.log('🔍 项目数据验证:');
console.log(' - 停滞期:', data.isStalled);
console.log(' - 改图期:', data.isModification);
console.log(' - 完整data:', data);
排查步骤:
排查步骤:
project.get('data').isModification 的值原因:数据库保存失败 解决:
project-detail.component.html
project-detail.component.ts
cancelStagnation() 方法project-detail.component.scss
.badge-action 交互样式stage-delivery.component.ts
stage-delivery-execution.component.ts
创建日期:2024-12-08
版本:v1.0
状态:✅ 已修复