2025.9.16日软件工程学习日志
今日设计了测试项目的html页面
`
石家庄铁道大学 - 科技成果信息填报系统
2025年秋季学期 - 软件需求与分析课程测试
<div class="message success" id="successMessage"></div>
<div class="message error" id="errorMessage"></div>
<div class="form-section">
<h2>基本信息</h2>
<div class="result-id" id="resultIdDisplay">成果编号将自动生成</div>
<div class="form-group">
<label for="resultName">成果名称 *</label>
<input type="text" id="resultName" required>
</div>
<div class="form-group">
<label>成果类型 *</label>
<div class="radio-group">
<label><input type="radio" name="resultType" value="基础研究成果" required> 基础研究成果</label>
<label><input type="radio" name="resultType" value="应用研究成果"> 应用研究成果</label>
<label><input type="radio" name="resultType" value="发展工作成果"> 发展工作成果</label>
</div>
</div>
</div>
<div class="form-section">
<h2>详细内容</h2>
<div class="form-group">
<label for="overview">成果概述 * <span class="char-count" id="overviewCount">0/500</span></label>
<textarea id="overview" required maxlength="500"></textarea>
</div>
<div class="form-group">
<label>成果关键字</label>
<div id="keywordsContainer">
<div class="keyword-input">
<input type="text" class="keyword" placeholder="输入关键字">
<button type="button" class="btn btn-secondary" onclick="addKeywordField()">+</button>
</div>
</div>
</div>
<div class="form-group">
<label for="completionTime">完成时间 *</label>
<input type="date" id="completionTime" required>
</div>
<div class="form-group">
<label for="innovation">成果创新点</label>
<textarea id="innovation"></textarea>
</div>
<div class="form-group">
<label for="detail">成果详述 * <span class="char-count" id="detailCount">0/3000</span></label>
<textarea id="detail" required maxlength="3000"></textarea>
</div>
</div>
<div class="form-section">
<h2>分类信息</h2>
<div class="form-group">
<label>学科分类</label>
<div id="subjectsContainer">
<div class="keyword-input">
<input type="text" class="subject" placeholder="输入学科分类">
<button type="button" class="btn btn-secondary" onclick="addSubjectField()">+</button>
</div>
</div>
</div>
<div class="form-group">
<label for="industry">产业分类 *</label>
<select id="industry" required>
<option value="">请选择产业分类</option>
<option value="农业">农业</option>
<option value="工业">工业</option>
<option value="服务业">服务业</option>
<option value="信息技术产业">信息技术产业</option>
<option value="文化产业">文化产业</option>
<option value="能源产业">能源产业</option>
<option value="交通运输业">交通运输业</option>
<option value="建筑业">建筑业</option>
<option value="金融业">金融业</option>
<option value="医疗健康产业">医疗健康产业</option>
</select>
</div>
</div>
<div class="actions">
<button type="button" class="btn" onclick="saveData()">保存成果</button>
<button type="button" class="btn btn-secondary" onclick="loadData()">查看成果列表</button>
<button type="button" class="btn btn-danger" onclick="clearForm()">清空表单</button>
</div>
<div id="dataDisplay" style="display: none;">
<div class="form-section">
<h2>已保存的科技成果</h2>
<table class="data-table">
<thead>
<tr>
<th>成果编号</th>
<th>成果名称</th>
<th>成果类型</th>
<th>完成时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="dataTableBody">
<!-- 数据将通过JavaScript动态填充 -->
</tbody>
</table>
</div>
</div>
</div>
<script>
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
// 设置字符计数监听
document.getElementById('overview').addEventListener('input', updateCharCount);
document.getElementById('detail').addEventListener('input', updateCharCount);
// 初始化日期为今天
const today = new Date().toISOString().split('T')[0];
document.getElementById('completionTime').value = today;
});
// 更新字符计数
function updateCharCount() {
const overview = document.getElementById('overview');
const detail = document.getElementById('detail');
const overviewCount = document.getElementById('overviewCount');
const detailCount = document.getElementById('detailCount');
overviewCount.textContent = `${overview.value.length}/500`;
detailCount.textContent = `${detail.value.length}/3000`;
if (overview.value.length > 450) {
overviewCount.classList.add('warning');
} else {
overviewCount.classList.remove('warning');
}
if (detail.value.length > 2850) {
detailCount.classList.add('warning');
} else {
detailCount.classList.remove('warning');
}
}
// 添加关键字输入框
function addKeywordField() {
const container = document.getElementById('keywordsContainer');
const newInput = document.createElement('div');
newInput.className = 'keyword-input';
newInput.innerHTML = `
<input type="text" class="keyword" placeholder="输入关键字">
<button type="button" class="btn btn-danger" onclick="removeField(this)">-</button>
`;
container.appendChild(newInput);
}
// 添加学科分类输入框
function addSubjectField() {
const container = document.getElementById('subjectsContainer');
const newInput = document.createElement('div');
newInput.className = 'keyword-input';
newInput.innerHTML = `
<input type="text" class="subject" placeholder="输入学科分类">
<button type="button" class="btn btn-danger" onclick="removeField(this)">-</button>
`;
container.appendChild(newInput);
}
// 移除输入框
function removeField(button) {
const container = button.parentElement;
container.remove();
}
// 生成成果编号
function generateResultId() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
// 在实际应用中,顺序号应从数据库获取最新值
// 这里使用随机数模拟
const sequence = String(Math.floor(Math.random() * 1000)).padStart(3, '0');
return `${year}-${month}-${day}-${sequence}`;
}
// 显示消息
function showMessage(type, text) {
const messageEl = document.getElementById(type + 'Message');
messageEl.textContent = text;
messageEl.style.display = 'block';
// 5秒后隐藏消息
setTimeout(() => {
messageEl.style.display = 'none';
}, 5000);
}
// 收集表单数据
function collectFormData() {
const resultId = generateResultId();
// 收集关键字
const keywords = [];
document.querySelectorAll('.keyword').forEach(input => {
if (input.value.trim() !== '') {
keywords.push(input.value.trim());
}
});
// 收集学科分类
const subjects = [];
document.querySelectorAll('.subject').forEach(input => {
if (input.value.trim() !== '') {
subjects.push(input.value.trim());
}
});
// 获取选中的成果类型
let resultType = '';
document.querySelectorAll('input[name="resultType"]').forEach(radio => {
if (radio.checked) {
resultType = radio.value;
}
});
return {
resultId: resultId,
name: document.getElementById('resultName').value,
type: resultType,
overview: document.getElementById('overview').value,
keywords: keywords,
completionTime: document.getElementById('completionTime').value,
innovation: document.getElementById('innovation').value,
detail: document.getElementById('detail').value,
subjects: subjects,
industry: document.getElementById('industry').value
};
}
// 保存数据到HBase
function saveData() {
const formData = collectFormData();
// 验证必填字段
if (!formData.name || !formData.type || !formData.overview ||
!formData.detail || !formData.completionTime || !formData.industry) {
showMessage('error', '请填写所有必填字段(标有*的字段)');
return;
}
// 在实际应用中,这里应该通过AJAX调用后端API
// 将数据保存到HBase数据库
// 模拟保存成功
document.getElementById('resultIdDisplay').textContent = `成果编号:${formData.resultId}`;
showMessage('success', `成果【${formData.name}】保存成功!`);
// 在实际应用中,这里应该将数据发送到后端
console.log('保存的数据:', formData);
// 将数据也保存到localStorage用于演示
let existingData = JSON.parse(localStorage.getItem('achievements') || '[]');
existingData.push(formData);
localStorage.setItem('achievements', JSON.stringify(existingData));
}
// 从HBase加载数据
function loadData() {
// 在实际应用中,这里应该通过AJAX调用后端API
// 从HBase数据库获取所有数据
// 从localStorage获取演示数据
const data = JSON.parse(localStorage.getItem('achievements') || '[]');
const tableBody = document.getElementById('dataTableBody');
tableBody.innerHTML = '';
if (data.length === 0) {
tableBody.innerHTML = '<tr><td colspan="5" style="text-align: center;">暂无数据</td></tr>';
} else {
data.forEach(item => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${item.resultId}</td>
<td>${item.name}</td>
<td>${item.type}</td>
<td>${item.completionTime}</td>
<td>
<button class="btn" onclick="viewDetail('${item.resultId}')">查看</button>
<button class="btn btn-secondary" onclick="editData('${item.resultId}')">编辑</button>
<button class="btn btn-danger" onclick="deleteData('${item.resultId}')">删除</button>
</td>
`;
tableBody.appendChild(row);
});
}
document.getElementById('dataDisplay').style.display = 'block';
}
// 查看详情
function viewDetail(resultId) {
// 在实际应用中,这里应该通过AJAX调用后端API
// 从HBase数据库获取指定ID的详细数据
// 从localStorage获取演示数据
const data = JSON.parse(localStorage.getItem('achievements') || '[]');
const item = data.find(d => d.resultId === resultId);
if (item) {
alert(`成果详情:\n名称:${item.name}\n类型:${item.type}\n概述:${item.overview}\n关键字:${item.keywords.join(', ')}\n完成时间:${item.completionTime}\n创新点:${item.innovation}\n学科分类:${item.subjects.join(', ')}\n产业分类:${item.industry}`);
}
}
// 编辑数据
function editData(resultId) {
// 在实际应用中,这里应该通过AJAX调用后端API
// 从HBase数据库获取指定ID的数据并填充表单
// 从localStorage获取演示数据
const data = JSON.parse(localStorage.getItem('achievements') || '[]');
const item = data.find(d => d.resultId === resultId);
if (item) {
// 填充表单
document.getElementById('resultName').value = item.name;
// 设置成果类型单选按钮
document.querySelectorAll('input[name="resultType"]').forEach(radio => {
radio.checked = (radio.value === item.type);
});
document.getElementById('overview').value = item.overview;
// 清空现有关键字字段并添加新字段
const keywordsContainer = document.getElementById('keywordsContainer');
keywordsContainer.innerHTML = '';
item.keywords.forEach((keyword, index) => {
const newInput = document.createElement('div');
newInput.className = 'keyword-input';
if (index === item.keywords.length - 1) {
newInput.innerHTML = `
<input type="text" class="keyword" value="${keyword}" placeholder="输入关键字">
<button type="button" class="btn btn-secondary" onclick="addKeywordField()">+</button>
`;
} else {
newInput.innerHTML = `
<input type="text" class="keyword" value="${keyword}" placeholder="输入关键字">
<button type="button" class="btn btn-danger" onclick="removeField(this)">-</button>
`;
}
keywordsContainer.appendChild(newInput);
});
document.getElementById('completionTime').value = item.completionTime;
document.getElementById('innovation').value = item.innovation;
document.getElementById('detail').value = item.detail;
// 清空现有学科分类字段并添加新字段
const subjectsContainer = document.getElementById('subjectsContainer');
subjectsContainer.innerHTML = '';
item.subjects.forEach((subject, index) => {
const newInput = document.createElement('div');
newInput.className = 'keyword-input';
if (index === item.subjects.length - 1) {
newInput.innerHTML = `
<input type="text" class="subject" value="${subject}" placeholder="输入学科分类">
<button type="button" class="btn btn-secondary" onclick="addSubjectField()">+</button>
`;
} else {
newInput.innerHTML = `
<input type="text" class="subject" value="${subject}" placeholder="输入学科分类">
<button type="button" class="btn btn-danger" onclick="removeField(this)">-</button>
`;
}
subjectsContainer.appendChild(newInput);
});
document.getElementById('industry').value = item.industry;
document.getElementById('resultIdDisplay').textContent = `成果编号:${item.resultId}`;
showMessage('success', `已加载成果【${item.name}】的数据,请修改后保存`);
}
}
// 删除数据
function deleteData(resultId) {
if (confirm('确定要删除这条成果记录吗?此操作不可恢复。')) {
// 在实际应用中,这里应该通过AJAX调用后端API
// 从HBase数据库删除指定ID的数据
// 从localStorage删除演示数据
let data = JSON.parse(localStorage.getItem('achievements') || '[]');
data = data.filter(d => d.resultId !== resultId);
localStorage.setItem('achievements', JSON.stringify(data));
showMessage('success', '成果记录已删除');
loadData(); // 刷新列表
}
}
// 清空表单
function clearForm() {
if (confirm('确定要清空表单吗?所有未保存的数据将丢失。')) {
document.getElementById('resultName').value = '';
document.querySelectorAll('input[name="resultType"]').forEach(radio => {
radio.checked = false;
});
document.getElementById('overview').value = '';
document.getElementById('keywordsContainer').innerHTML = `
<div class="keyword-input">
<input type="text" class="keyword" placeholder="输入关键字">
<button type="button" class="btn btn-secondary" onclick="addKeywordField()">+</button>
</div>
`;
const today = new Date().toISOString().split('T')[0];
document.getElementById('completionTime').value = today;
document.getElementById('innovation').value = '';
document.getElementById('detail').value = '';
document.getElementById('subjectsContainer').innerHTML = `
<div class="keyword-input">
<input type="text" class="subject" placeholder="输入学科分类">
<button type="button" class="btn btn-secondary" onclick="addSubjectField()">+</button>
</div>
`;
document.getElementById('industry').selectedIndex = 0;
document.getElementById('resultIdDisplay').textContent = '成果编号将自动生成';
updateCharCount();
}
}
</script>
`