460 lines
22 KiB
HTML
460 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>项目启动 - OA系统</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||
<!-- 统一布局样式 -->
|
||
<link rel="stylesheet" href="unified-layout.css">
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body {
|
||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
|
||
background: #f0f2f5;
|
||
overflow: hidden;
|
||
}
|
||
.layout-container {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.navbar {
|
||
height: 50px;
|
||
background: #fff;
|
||
border-bottom: 1px solid #e6e6e6;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 20px;
|
||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||
}
|
||
.navbar-left {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
.logo {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
color: #409EFF;
|
||
}
|
||
.nav-menu { display: flex; gap: 8px; }
|
||
.nav-item { padding: 8px 16px; cursor: pointer; border-radius: 4px; }
|
||
.nav-item:hover {
|
||
background: #ecf5ff;
|
||
color: #409EFF;
|
||
}
|
||
background: #409EFF; }
|
||
.navbar-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
}
|
||
.main-container {
|
||
flex: 1;
|
||
display: flex;
|
||
overflow: hidden;
|
||
}
|
||
.app-main {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: #f0f2f5;
|
||
}
|
||
.sidebar {
|
||
width: 210px;
|
||
background: #fff;
|
||
border-right: 1px solid #e6e6e6;
|
||
overflow-y: auto;
|
||
}
|
||
.el-menu {
|
||
border-right: none;
|
||
}
|
||
.menu-item { padding: 12px 24px; cursor: pointer; }
|
||
.menu-item.active {
|
||
background: #409EFF;
|
||
color: #fff;
|
||
}
|
||
.content {
|
||
flex: 1;
|
||
padding: 20px;
|
||
overflow-y: auto;
|
||
background: #fff;
|
||
margin: 10px;
|
||
border-radius: 4px;
|
||
}
|
||
.page-header { margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid #f0f0f0; }
|
||
.page-title { font-size: 20px; font-weight: 500; }
|
||
.form-card { background: white; border-radius: 4px; padding: 24px; }
|
||
.form-section { margin-bottom: 24px; }
|
||
.form-section-title { font-size: 16px; font-weight: 500; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid #f0f0f0; }
|
||
.form-row { display: flex; gap: 16px; margin-bottom: 16px; }
|
||
.form-item { flex: 1; }
|
||
.form-label { display: block; margin-bottom: 8px; color: #333; font-size: 14px; }
|
||
.form-label .required { color: #ff4d4f; }
|
||
.form-input, .form-select { width: 100%; padding: 8px 12px; border: 1px solid #d9d9d9; border-radius: 4px; }
|
||
.staff-table { width: 100%; border-collapse: collapse; margin-top: 16px; }
|
||
.staff-table th, .staff-table td { padding: 12px; text-align: left; border: 1px solid #f0f0f0; }
|
||
.staff-table th { background: #fafafa; }
|
||
.btn { padding: 8px 24px; border: none; border-radius: 4px; cursor: pointer; }
|
||
.btn-primary { background: #409EFF; color: white; }
|
||
.btn-default { background: white; color: #333; border: 1px solid #d9d9d9; }
|
||
.form-actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 24px; padding-top: 24px; border-top: 1px solid #f0f0f0; }
|
||
.fee-calculation { background: #f5f7fa; padding: 16px; border-radius: 4px; margin-top: 16px; }
|
||
.fee-formula { font-size: 12px; color: #666; margin-top: 8px; }
|
||
.formula-note { background: #fff7e6; padding: 12px; border-radius: 4px; margin-top: 16px; font-size: 12px; color: #d46b08; }
|
||
.formula-note-title { font-weight: 500; margin-bottom: 8px; }
|
||
</style>
|
||
<!-- Vue.js -->
|
||
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
|
||
<!-- Element UI JS -->
|
||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||
</head>
|
||
<body>
|
||
<div id="app">
|
||
|
||
<div class="layout-container">
|
||
<div class="navbar">
|
||
<div class="navbar-left">
|
||
<div class="logo">OA系统</div>
|
||
<div class="nav-menu">
|
||
<div class="nav-item" onclick="window.location.href='project-initiation.html'">商机管理</div>
|
||
<div class="nav-item active">过程管理</div>
|
||
<div class="nav-item" onclick="window.location.href='finance-invoice.html'">财务管理</div>
|
||
<div class="nav-item" onclick="window.location.href='report-project-detail.html'">报表管理</div>
|
||
</div>
|
||
</div>
|
||
<div class="navbar-right">
|
||
<span style="color: #303133;">张三</span><span style="color: #909399; margin: 0 8px;">|</span>
|
||
<a href="profile.html" style="color: #409EFF; text-decoration: none;">个人中心</a>
|
||
<span>|</span>
|
||
<a href="login.html" style="color: #409EFF; text-decoration: none;">退出</a>
|
||
</div>
|
||
</div>
|
||
<div class="main-container">
|
||
<div class="sidebar">
|
||
<div class="menu-item active">启动申请</div>
|
||
<div class="menu-item" onclick="window.location.href='output-submit.html'">成果提交</div>
|
||
<div class="menu-item" onclick="window.location.href='progress-query.html'">进度查询</div>
|
||
</div>
|
||
<div class="content">
|
||
<div class="page-header">
|
||
<div class="page-title">项目启动申请</div>
|
||
</div>
|
||
<div class="form-card">
|
||
<form id="startForm">
|
||
<div class="form-section">
|
||
<div class="form-section-title">关联项目</div>
|
||
<div class="form-row">
|
||
<div class="form-item">
|
||
<label class="form-label">
|
||
<span class="required">*</span>关联立项项目
|
||
</label>
|
||
<select id="projectSelect" class="form-select" required onchange="onProjectChange()">
|
||
<option value="">请选择项目</option>
|
||
<option value="25-1" data-type="工程咨询" data-count="0">25-1 - XX工程项目(工程咨询)</option>
|
||
<option value="25-2" data-type="跟踪审计" data-count="1">25-2 - YY工程项目(跟踪审计)</option>
|
||
<option value="25-3" data-type="结算审计、概算编制及审核、清单控制价编制及审核" data-count="0">25-3 - ZZ工程项目(结算审计)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">启动编号</label>
|
||
<input type="text" id="startNumber" class="form-input" value="" readonly placeholder="选择项目后自动生成">
|
||
<div style="font-size: 12px; color: #999; margin-top: 4px;">规则:立项编号+项目类型数字+启动序号</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-section">
|
||
<div class="form-section-title">费用计算</div>
|
||
<div class="fee-calculation">
|
||
<div class="form-row">
|
||
<div class="form-item">
|
||
<label class="form-label">基础金额(元)</label>
|
||
<input type="number" id="baseAmount" class="form-input" placeholder="根据文件计算的基础金额" oninput="calculateFee()">
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">折扣率</label>
|
||
<input type="number" id="discountRate" class="form-input" placeholder="0-1之间的小数" min="0" max="1" step="0.01" value="1" oninput="calculateFee()">
|
||
</div>
|
||
</div>
|
||
<div id="adjustmentFactors" style="display: none;">
|
||
<div class="form-row">
|
||
<div class="form-item">
|
||
<label class="form-label">专业调整系数</label>
|
||
<input type="number" id="professionalFactor" class="form-input" placeholder="专业调整系数" min="0" step="0.01" value="1" oninput="calculateFee()">
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">工程复杂程度调整系数</label>
|
||
<input type="number" id="complexityFactor" class="form-input" placeholder="工程复杂程度调整系数" min="0" step="0.01" value="1" oninput="calculateFee()">
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">高程调整系数</label>
|
||
<input type="number" id="elevationFactor" class="form-input" placeholder="高程调整系数" min="0" step="0.01" value="1" oninput="calculateFee()">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-item">
|
||
<label class="form-label">最终费用(元)</label>
|
||
<input type="text" id="finalFee" class="form-input" value="0" readonly style="background: #f5f5f5; font-weight: 500; color: #409EFF; font-size: 16px;">
|
||
</div>
|
||
</div>
|
||
<div id="formulaNote" class="formula-note" style="display: none;">
|
||
<div class="formula-note-title">计算公式说明:</div>
|
||
<div id="formulaText"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-section">
|
||
<div class="form-section-title">人员分工</div>
|
||
<table class="staff-table">
|
||
<thead>
|
||
<tr>
|
||
<th>执业工程师</th>
|
||
<th>工作内容</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="staffTableBody">
|
||
<tr>
|
||
<td>
|
||
<select class="form-select">
|
||
<option>张三</option>
|
||
<option>李四</option>
|
||
<option>王五</option>
|
||
</select>
|
||
</td>
|
||
<td>
|
||
<select id="workContent0" class="form-select work-content-select" multiple style="height: 60px;">
|
||
<option>请先选择关联项目</option>
|
||
</select>
|
||
</td>
|
||
<td>
|
||
<button type="button" class="btn btn-default" onclick="removeStaff(this)">删除</button>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<button type="button" class="btn btn-default" onclick="addStaff()" style="margin-top: 12px;">+ 添加人员</button>
|
||
</div>
|
||
<div class="form-actions">
|
||
<button type="button" class="btn btn-default" onclick="resetForm()">重置</button>
|
||
<button type="submit" class="btn btn-primary">提交审核</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script src="common.js"></script>
|
||
<script src="unified-layout.js"></script>
|
||
<script>
|
||
initUnifiedLayout('process');
|
||
// 项目类型数字映射
|
||
const projectTypeMap = {
|
||
'结算审计、概算编制及审核、清单控制价编制及审核': '1',
|
||
'工程咨询': '2',
|
||
'跟踪审计': '3',
|
||
'项目管理': '4',
|
||
'工程监理': '5'
|
||
};
|
||
|
||
// 工作内容映射
|
||
const workContentMap = {
|
||
'结算审计、概算编制及审核、清单控制价编制及审核': ['计量', '计价', '对账', '出报告'],
|
||
'工程咨询': ['文本', '估算', '出报告'],
|
||
'跟踪审计': ['现场跟踪', '进度款审核'],
|
||
'项目管理': ['项目协助甲方报批报建', '项目实施过程中管控'],
|
||
'工程监理': ['现场跟踪', '进度审核']
|
||
};
|
||
|
||
// 计算公式说明
|
||
const formulaMap = {
|
||
'工程咨询': '依据鄂价房字[2001]107号文计算 × 折扣率',
|
||
'工程造价': '依据鄂价工服规[2012]149号文计算 × 折扣率',
|
||
'工程监理': '依据发改价格[2007]670号文计算 × 专业调整系数 × 工程复杂程度调整系数 × 高程调整系数 × 折扣率',
|
||
'工程设计': '依据计价格[2002]10号文计算 × 折扣率',
|
||
'工程代建': '依据财建[2016]504号文计算 × 折扣率',
|
||
'招标代理': '依据鄂建文〔2023〕35号文计算 × 折扣率'
|
||
};
|
||
|
||
// 项目选择变化事件
|
||
function onProjectChange() {
|
||
const select = document.getElementById('projectSelect');
|
||
const selectedOption = select.options[select.selectedIndex];
|
||
|
||
if (!selectedOption.value) {
|
||
document.getElementById('startNumber').value = '';
|
||
updateWorkContentOptions(null);
|
||
return;
|
||
}
|
||
|
||
const projectNumber = selectedOption.value;
|
||
const serviceType = selectedOption.getAttribute('data-type');
|
||
const startCount = parseInt(selectedOption.getAttribute('data-count') || '0');
|
||
|
||
// 生成启动编号
|
||
const typeNum = projectTypeMap[serviceType] || '0';
|
||
const nextStartNum = startCount + 1;
|
||
const startNumber = `${projectNumber}-${typeNum}-${nextStartNum}`;
|
||
document.getElementById('startNumber').value = startNumber;
|
||
|
||
// 更新工作内容选项
|
||
updateWorkContentOptions(serviceType);
|
||
|
||
// 更新费用计算公式
|
||
updateFeeFormula(serviceType);
|
||
}
|
||
|
||
// 更新工作内容选项
|
||
function updateWorkContentOptions(serviceType) {
|
||
const workContentSelects = document.querySelectorAll('.work-content-select');
|
||
const options = serviceType ? workContentMap[serviceType] : [];
|
||
|
||
workContentSelects.forEach(select => {
|
||
select.innerHTML = '';
|
||
if (options.length > 0) {
|
||
options.forEach(option => {
|
||
const opt = document.createElement('option');
|
||
opt.value = option;
|
||
opt.textContent = option;
|
||
select.appendChild(opt);
|
||
});
|
||
} else {
|
||
const opt = document.createElement('option');
|
||
opt.textContent = '请先选择关联项目';
|
||
select.appendChild(opt);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 更新费用计算公式
|
||
function updateFeeFormula(serviceType) {
|
||
const formulaNote = document.getElementById('formulaNote');
|
||
const formulaText = document.getElementById('formulaText');
|
||
const adjustmentFactors = document.getElementById('adjustmentFactors');
|
||
|
||
if (serviceType === '工程监理') {
|
||
adjustmentFactors.style.display = 'block';
|
||
formulaText.textContent = formulaMap['工程监理'] || '';
|
||
} else {
|
||
adjustmentFactors.style.display = 'none';
|
||
// 根据服务类型匹配公式
|
||
let formula = '';
|
||
if (serviceType === '工程咨询') {
|
||
formula = formulaMap['工程咨询'];
|
||
} else if (serviceType.includes('结算') || serviceType.includes('概算') || serviceType.includes('清单')) {
|
||
formula = formulaMap['工程造价'];
|
||
} else {
|
||
formula = '请选择服务类型查看计算公式';
|
||
}
|
||
formulaText.textContent = formula;
|
||
}
|
||
|
||
if (formulaText.textContent) {
|
||
formulaNote.style.display = 'block';
|
||
} else {
|
||
formulaNote.style.display = 'none';
|
||
}
|
||
|
||
// 重新计算费用
|
||
calculateFee();
|
||
}
|
||
|
||
// 计算费用
|
||
function calculateFee() {
|
||
const baseAmount = parseFloat(document.getElementById('baseAmount').value) || 0;
|
||
const discountRate = parseFloat(document.getElementById('discountRate').value) || 1;
|
||
const select = document.getElementById('projectSelect');
|
||
const selectedOption = select.options[select.selectedIndex];
|
||
const serviceType = selectedOption ? selectedOption.getAttribute('data-type') : '';
|
||
|
||
let finalFee = 0;
|
||
|
||
if (baseAmount > 0) {
|
||
if (serviceType === '工程监理') {
|
||
const professionalFactor = parseFloat(document.getElementById('professionalFactor').value) || 1;
|
||
const complexityFactor = parseFloat(document.getElementById('complexityFactor').value) || 1;
|
||
const elevationFactor = parseFloat(document.getElementById('elevationFactor').value) || 1;
|
||
finalFee = baseAmount * professionalFactor * complexityFactor * elevationFactor * discountRate;
|
||
} else {
|
||
finalFee = baseAmount * discountRate;
|
||
}
|
||
}
|
||
|
||
document.getElementById('finalFee').value = finalFee.toLocaleString('zh-CN', {
|
||
minimumFractionDigits: 2,
|
||
maximumFractionDigits: 2
|
||
});
|
||
}
|
||
|
||
// 添加人员
|
||
let staffCount = 1;
|
||
function addStaff() {
|
||
const tbody = document.getElementById('staffTableBody');
|
||
const row = document.createElement('tr');
|
||
const select = document.getElementById('projectSelect');
|
||
const selectedOption = select.options[select.selectedIndex];
|
||
const serviceType = selectedOption ? selectedOption.getAttribute('data-type') : '';
|
||
const options = serviceType ? workContentMap[serviceType] : [];
|
||
|
||
let workContentOptions = '';
|
||
if (options.length > 0) {
|
||
options.forEach(option => {
|
||
workContentOptions += `<option value="${option}">${option}</option>`;
|
||
});
|
||
} else {
|
||
workContentOptions = '<option>请先选择关联项目</option>';
|
||
}
|
||
|
||
row.innerHTML = `
|
||
<td>
|
||
<select class="form-select">
|
||
<option>张三</option>
|
||
<option>李四</option>
|
||
<option>王五</option>
|
||
</select>
|
||
</td>
|
||
<td>
|
||
<select id="workContent${staffCount}" class="form-select work-content-select" multiple style="height: 60px;">
|
||
${workContentOptions}
|
||
</select>
|
||
</td>
|
||
<td>
|
||
<button type="button" class="btn btn-default" onclick="removeStaff(this)">删除</button>
|
||
</td>
|
||
`;
|
||
tbody.appendChild(row);
|
||
staffCount++;
|
||
}
|
||
|
||
function removeStaff(btn) {
|
||
btn.closest('tr').remove();
|
||
}
|
||
|
||
function resetForm() {
|
||
CommonUtils.confirm('确认重置表单?', () => {
|
||
document.getElementById('startForm').reset();
|
||
document.getElementById('startNumber').value = '';
|
||
document.getElementById('finalFee').value = '0';
|
||
document.getElementById('formulaNote').style.display = 'none';
|
||
document.getElementById('adjustmentFactors').style.display = 'none';
|
||
updateWorkContentOptions(null);
|
||
});
|
||
}
|
||
|
||
document.getElementById('startForm').addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
CommonUtils.confirm('确认提交启动申请?', () => {
|
||
CommonUtils.showMessage('提交成功!等待审核');
|
||
setTimeout(() => window.location.href = 'progress-query.html', 1000);
|
||
});
|
||
});
|
||
// initUnifiedLayout('process'); // 已在上面调用
|
||
</script>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
|