2026-05-15 12:25:08 +08:00
|
|
|
const express = require('express');
|
|
|
|
|
const db = require('../db');
|
|
|
|
|
const router = express.Router();
|
|
|
|
|
|
|
|
|
|
router.get('/', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.query(
|
|
|
|
|
'SELECT id, name, description, phases, is_system, created_at, updated_at FROM project_type_templates ORDER BY is_system DESC, created_at ASC'
|
|
|
|
|
);
|
|
|
|
|
res.json({ success: true, data: result.rows });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取模板列表失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '获取模板列表失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.get('/:id', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.query(
|
|
|
|
|
'SELECT id, name, description, phases, is_system, created_at, updated_at FROM project_type_templates WHERE id = $1',
|
|
|
|
|
[req.params.id]
|
|
|
|
|
);
|
|
|
|
|
if (result.rows.length === 0) {
|
|
|
|
|
return res.status(404).json({ success: false, message: '模板不存在' });
|
|
|
|
|
}
|
|
|
|
|
res.json({ success: true, data: result.rows[0] });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取模板详情失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '获取模板详情失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.post('/', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { name, description, phases } = req.body;
|
|
|
|
|
if (!name) {
|
|
|
|
|
return res.status(400).json({ success: false, message: '模板名称不能为空' });
|
|
|
|
|
}
|
|
|
|
|
if (!phases || !Array.isArray(phases) || phases.length === 0) {
|
|
|
|
|
return res.status(400).json({ success: false, message: '模板阶段不能为空' });
|
|
|
|
|
}
|
|
|
|
|
const result = await db.query(
|
|
|
|
|
'INSERT INTO project_type_templates (name, description, phases, is_system) VALUES ($1, $2, $3, false) RETURNING id',
|
|
|
|
|
[name, description || '', JSON.stringify(phases)]
|
|
|
|
|
);
|
|
|
|
|
res.json({ success: true, message: '模板创建成功', data: { id: result.rows[0].id } });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('创建模板失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '创建模板失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.put('/:id', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
const existing = await db.query('SELECT is_system FROM project_type_templates WHERE id = $1', [id]);
|
|
|
|
|
if (existing.rows.length === 0) {
|
|
|
|
|
return res.status(404).json({ success: false, message: '模板不存在' });
|
|
|
|
|
}
|
|
|
|
|
const { name, description, phases } = req.body;
|
|
|
|
|
const updates = [];
|
|
|
|
|
const values = [];
|
|
|
|
|
let paramIndex = 1;
|
|
|
|
|
if (name !== undefined) { updates.push(`name = $${paramIndex++}`); values.push(name); }
|
|
|
|
|
if (description !== undefined) { updates.push(`description = $${paramIndex++}`); values.push(description); }
|
|
|
|
|
if (phases !== undefined) { updates.push(`phases = $${paramIndex++}`); values.push(JSON.stringify(phases)); }
|
|
|
|
|
if (updates.length === 0) {
|
|
|
|
|
return res.status(400).json({ success: false, message: '没有更新数据' });
|
|
|
|
|
}
|
|
|
|
|
updates.push('updated_at = NOW()');
|
|
|
|
|
values.push(id);
|
|
|
|
|
await db.query(`UPDATE project_type_templates SET ${updates.join(', ')} WHERE id = $${paramIndex}`, values);
|
|
|
|
|
res.json({ success: true, message: '模板更新成功' });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('更新模板失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '更新模板失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.delete('/:id', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
const existing = await db.query('SELECT is_system FROM project_type_templates WHERE id = $1', [id]);
|
|
|
|
|
if (existing.rows.length === 0) {
|
|
|
|
|
return res.status(404).json({ success: false, message: '模板不存在' });
|
|
|
|
|
}
|
|
|
|
|
if (existing.rows[0].is_system) {
|
|
|
|
|
return res.status(403).json({ success: false, message: '系统预设模板不可删除' });
|
|
|
|
|
}
|
|
|
|
|
await db.query('DELETE FROM project_type_templates WHERE id = $1', [id]);
|
|
|
|
|
res.json({ success: true, message: '模板删除成功' });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('删除模板失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '删除模板失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.post('/:id/copy', async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
const { name } = req.body;
|
|
|
|
|
const existing = await db.query('SELECT name, description, phases FROM project_type_templates WHERE id = $1', [id]);
|
|
|
|
|
if (existing.rows.length === 0) {
|
|
|
|
|
return res.status(404).json({ success: false, message: '模板不存在' });
|
|
|
|
|
}
|
|
|
|
|
const src = existing.rows[0];
|
|
|
|
|
const result = await db.query(
|
|
|
|
|
'INSERT INTO project_type_templates (name, description, phases, is_system) VALUES ($1, $2, $3, false) RETURNING id',
|
2026-06-13 12:44:48 +08:00
|
|
|
[name || `${src.name} (副本)`, src.description, JSON.stringify(src.phases)]
|
2026-05-15 12:25:08 +08:00
|
|
|
);
|
|
|
|
|
res.json({ success: true, message: '模板复制成功', data: { id: result.rows[0].id } });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('复制模板失败:', error);
|
|
|
|
|
res.status(500).json({ success: false, message: '复制模板失败' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
module.exports = router;
|