// 项目管理页面JavaScript let projects = []; let currentEditingProject = null; // 页面加载时初始化 document.addEventListener('DOMContentLoaded', function() { loadProjects(); setupEventListeners(); }); // 设置事件监听器 function setupEventListeners() { // 项目表单提交 const projectForm = document.getElementById('project-form'); if (projectForm) { projectForm.addEventListener('submit', handleProjectSubmit); } } // 加载项目列表 async function loadProjects() { try { const response = await apiGet('/api/projects'); projects = response.data; renderProjectsTable(); updateProjectStats(); } catch (error) { showError('加载项目失败: ' + error.message); console.error('加载项目失败:', error); } } // 渲染项目表格 function renderProjectsTable() { const tbody = document.getElementById('projects-tbody'); if (!tbody) return; if (projects.length === 0) { tbody.innerHTML = '暂无项目数据'; return; } tbody.innerHTML = projects.map(project => ` ${escapeHtml(project.project_name)} ${project.project_type === 'traditional' ? '传统项目' : 'PSI项目'} ${escapeHtml(project.customer_name)} ${project.project_type === 'traditional' ? escapeHtml(project.project_code) : escapeHtml(project.contract_number || 'PSI-PROJ')} ${project.is_active ? '活跃' : '禁用'} ${formatDate(project.start_date)} ${formatDateTime(project.created_at)} `).join(''); } // 更新项目统计 function updateProjectStats() { const totalCount = projects.length; const traditionalCount = projects.filter(p => p.project_type === 'traditional').length; const psiCount = projects.filter(p => p.project_type === 'psi').length; const totalElement = document.getElementById('total-projects-count'); const traditionalElement = document.getElementById('traditional-projects-count'); const psiElement = document.getElementById('psi-projects-count'); if (totalElement) totalElement.textContent = totalCount; if (traditionalElement) traditionalElement.textContent = traditionalCount; if (psiElement) psiElement.textContent = psiCount; } // 筛选项目 function filterProjects() { const typeFilter = document.getElementById('project-type-filter').value; let filteredProjects = projects; if (typeFilter) { filteredProjects = projects.filter(p => p.project_type === typeFilter); } renderFilteredProjects(filteredProjects); } // 渲染筛选后的项目 function renderFilteredProjects(filteredProjects) { const tbody = document.getElementById('projects-tbody'); if (!tbody) return; if (filteredProjects.length === 0) { tbody.innerHTML = '没有符合条件的项目'; return; } tbody.innerHTML = filteredProjects.map(project => ` ${escapeHtml(project.project_name)} ${project.project_type === 'traditional' ? '传统项目' : 'PSI项目'} ${escapeHtml(project.customer_name)} ${project.project_type === 'traditional' ? escapeHtml(project.project_code) : escapeHtml(project.contract_number || 'PSI-PROJ')} ${project.is_active ? '活跃' : '禁用'} ${formatDate(project.start_date)} ${formatDateTime(project.created_at)} `).join(''); } // 显示创建项目模态框 function showCreateProjectModal() { currentEditingProject = null; resetForm('project-form'); document.getElementById('modal-title').textContent = '新建项目'; // 隐藏项目类型特定字段 document.getElementById('traditional-fields').style.display = 'none'; document.getElementById('psi-fields').style.display = 'none'; showModal('create-project-modal'); } // 项目类型切换 function toggleProjectFields() { const projectType = document.getElementById('project_type').value; const traditionalFields = document.getElementById('traditional-fields'); const psiFields = document.getElementById('psi-fields'); const projectCodeField = document.getElementById('project_code'); const contractNumberField = document.getElementById('contract_number'); if (projectType === 'traditional') { traditionalFields.style.display = 'block'; psiFields.style.display = 'none'; projectCodeField.required = true; contractNumberField.required = false; } else if (projectType === 'psi') { traditionalFields.style.display = 'none'; psiFields.style.display = 'block'; projectCodeField.required = false; contractNumberField.required = true; } else { traditionalFields.style.display = 'none'; psiFields.style.display = 'none'; projectCodeField.required = false; contractNumberField.required = false; } } // 处理项目表单提交 async function handleProjectSubmit(e) { e.preventDefault(); const formData = getFormData('project-form'); try { let response; if (currentEditingProject) { // 更新项目 response = await apiPut(`/api/projects/${currentEditingProject.id}`, formData); } else { // 创建新项目 response = await apiPost('/api/projects', formData); } showSuccess(currentEditingProject ? '项目更新成功' : '项目创建成功'); closeModal('create-project-modal'); loadProjects(); // 重新加载项目列表 } catch (error) { showError(error.message); } } // 编辑项目 function editProject(projectId) { const project = projects.find(p => p.id === projectId); if (!project) { showError('项目不存在'); return; } currentEditingProject = project; document.getElementById('modal-title').textContent = '编辑项目'; // 填充表单数据 fillForm('project-form', project); // 设置项目类型并显示对应字段 document.getElementById('project_type').value = project.project_type; toggleProjectFields(); showModal('create-project-modal'); } // 删除项目 async function deleteProject(projectId) { const project = projects.find(p => p.id === projectId); if (!project) { showError('项目不存在'); return; } if (!confirm(`确定要删除项目"${project.project_name}"吗?`)) { return; } try { await apiDelete(`/api/projects/${projectId}`); showSuccess('项目删除成功'); loadProjects(); // 重新加载项目列表 } catch (error) { showError('删除项目失败: ' + error.message); } } // 显示导入模态框 function showImportModal() { showModal('import-modal'); } // 下载模板文件 function downloadTemplate(type) { let csvContent = ''; if (type === 'traditional') { csvContent = `项目名称,项目类型,客户名,项目代码,合同号,描述 CXMT 2025 MA,traditional,长鑫存储,02C-FBV,,长鑫2025年MA项目 Project Alpha,traditional,客户A,01A-DEV,,Alpha开发项目`; } else if (type === 'psi') { csvContent = `项目名称,项目类型,客户名,项目代码,合同号,描述 NexChip PSI项目,psi,NexChip,PSI-PROJ,ID00462761,NexChip客户PSI项目 Samsung项目,psi,Samsung,PSI-PROJ,SC20241201,Samsung客户项目`; } else if (type === 'mixed') { csvContent = `项目名称,项目类型,客户名,项目代码,合同号,描述 CXMT 2025 MA,traditional,长鑫存储,02C-FBV,,长鑫2025年MA项目 NexChip PSI项目,psi,NexChip,PSI-PROJ,ID00462761,NexChip客户PSI项目 Project Beta,traditional,客户B,01B-TEST,,Beta测试项目`; } downloadFile(csvContent, `项目模板_${type}.csv`, 'text/csv;charset=utf-8'); } // 导入项目 async function importProjects() { const fileInput = document.getElementById('import-file'); const file = fileInput.files[0]; if (!file) { showError('请选择CSV文件'); return; } if (!file.name.endsWith('.csv')) { showError('请选择CSV文件'); return; } const formData = new FormData(); formData.append('file', file); try { const response = await fetch('/api/projects/import', { method: 'POST', body: formData }); const result = await response.json(); if (!response.ok) { throw new Error(result.error || '导入失败'); } // 显示导入结果 showImportResult(result); closeModal('import-modal'); loadProjects(); // 重新加载项目列表 } catch (error) { showError('导入项目失败: ' + error.message); } } // 显示导入结果 function showImportResult(result) { const content = document.getElementById('import-result-content'); let html = `

导入完成

成功导入 ${result.created_count} 个项目

`; if (result.errors && result.errors.length > 0) { html += `
导入错误 (${result.errors.length} 项):
`; } content.innerHTML = html; showModal('import-result-modal'); } // HTML转义函数 function escapeHtml(text) { if (!text) return ''; const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // 添加徽章样式(如果CSS中没有定义) if (!document.querySelector('#badge-styles')) { const style = document.createElement('style'); style.id = 'badge-styles'; style.textContent = ` .badge { display: inline-block; padding: 4px 8px; font-size: 12px; font-weight: 600; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: 4px; } .badge-primary { background-color: #3498db; color: white; } .badge-secondary { background-color: #6c757d; color: white; } .badge-success { background-color: #27ae60; color: white; } .badge-danger { background-color: #e74c3c; color: white; } .btn-sm { padding: 6px 12px; font-size: 12px; } `; document.head.appendChild(style); }