SCRUM6
昨天的成就:
昨天将整个合同档案模块完成,合同管理功能可以添加合同,档案管理模块可以查看个人档案。
相关代码:
// 加载档案管理内容
function loadProfileManagement(container) {
container.innerHTML = `
<div class="profile-management">
<h3 style="font-size: 1.5rem;">档案管理</h3>
<div id="profileContent"></div>
</div>
`;
// 获取当前用户信息
fetch('/api/user/archive-info')
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data => {
const profileContent = document.getElementById('profileContent');
profileContent.innerHTML = `
<p><strong>用户ID:</strong>${data.userId || '无'}</p>
<p><strong>职级:</strong>${data.permissionLevel || '无'}</p>
<p><strong>职位:</strong>${data.position || '无'}</p>
<p><strong>所属部门:</strong>${data.departmentName || '无'}</p>
<p><strong>身高:</strong>${data.height || '无'}</p>
<p><strong>体重:</strong>${data.weight || '无'}</p>
<p><strong>视力:</strong>${data.vision || '无'}</p>
<p><strong>绩效:</strong>${data.performanceScore || '无'}</p>
`;
})
.catch(error => {
console.error('获取用户信息出错:', error);
document.getElementById('profileContent').innerHTML = '<p style="color: red; font-size: 1.2rem;">获取用户信息失败,请刷新重试</p>';
});
}
// 加载合同管理内容
function loadContractManagement(container) {
// 获取当前用户ID和权限等级
fetch('/api/user/current-user-info')
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data => {
const userId = data.userId;
const permissionLevel = data.permissionLevel;
const departmentId = data.departmentId;
container.innerHTML = `
<div class="contract-management">
<h3 style="font-size: 1.5rem;">合同管理</h3>
<div id="contractContent"></div>
${permissionLevel === 3 && departmentId === 4 ? '<button onclick="showCreateContractForm()">创建合同</button>' : ''}
</div>
`;
// 获取当前用户的所有合同
fetch(`/api/contract/user/${userId}`)
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(contracts => {
const contractContent = document.getElementById('contractContent');
if (contracts.length === 0) {
contractContent.innerHTML = '<p style="font-size: 1.2rem; color: #666;">您没有任何合同记录。</p>';
return;
}
let contractsHtml = '<ul style="list-style-type: none; padding: 0;">';
contracts.forEach(contract => {
contractsHtml += `
<li style="padding: 10px; border-bottom: 1px solid #eee; font-size: 1.1rem;">
<p><strong>合同编号:</strong>${contract.contractNumber || '无'}</p>
<p><strong>合同类型:</strong>${contract.contractType || '无'}</p>
<p><strong>开始日期:</strong>${contract.startDate || '无'}</p>
<p><strong>结束日期:</strong>${contract.endDate || '无'}</p>
<p><strong>合同内容:</strong>${contract.contractNumber || '无'}</p>
<p><strong>状态:</strong>${contract.contractType || '无'}</p>
</li>
`;
});
contractsHtml += '</ul>';
contractContent.innerHTML = contractsHtml;
})
.catch(error => {
console.error('获取合同信息出错:', error);
document.getElementById('contractContent').innerHTML = '<p style="color: red; font-size: 1.2rem;">获取合同信息失败,请刷新重试</p>';
});
})
.catch(error => {
console.error('获取用户信息出错:', error);
container.innerHTML = '<p style="color: red; font-size: 1.2rem;">获取用户信息失败,请刷新重试</p>';
});
}
// 显示创建合同表单
function showCreateContractForm() {
// 获取所有用户作为合同对象的选项
fetch('/api/user/all')
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(users => {
const contractContent = document.getElementById('contractContent');
let usersHtml = '<label for="contractTargetUserId">合同对象:</label><br>';
usersHtml += '<select id="contractTargetUserId" name="contractTargetUserId" required>';
users.forEach(user => {
usersHtml += `<option value="${user.id}">${user.position} - ${user.id}</option>`;
});
usersHtml += '</select><br><br>';
contractContent.innerHTML = `
<form id="createContractForm">
<label for="contractNumber">合同编号:</label>
<input type="text" id="contractNumber" name="contractNumber" required><br><br>
<label for="contractType">合同类型:</label>
<input type="text" id="contractType" name="contractType" required><br><br>
<label for="startDate">开始日期:</label>
<input type="date" id="startDate" name="startDate" required><br><br>
<label for="endDate">结束日期:</label>
<input type="date" id="endDate" name="endDate" required><br><br>
<label for="contractContent">合同内容:</label>
<textarea id="contractContent" name="contractContent" required></textarea><br><br>
${usersHtml}
<button type="button" onclick="submitCreateContractForm()">提交</button>
</form>
`;
})
.catch(error => {
console.error('获取用户信息出错:', error);
alert('获取用户信息失败,请重试');
});
}
// 提交创建合同表单
function submitCreateContractForm() {
const contractNumber = document.getElementById('contractNumber').value;
const contractType = document.getElementById('contractType').value;
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const contractContent = document.getElementById('contractContent').value;
const contractTargetUserId = document.getElementById('contractTargetUserId').value;
fetch('/api/contract/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
contractNumber: contractNumber,
contractType: contractType,
startDate: startDate, // 确保日期格式为 yyyy-MM-dd
endDate: endDate, // 确保日期格式为 yyyy-MM-dd
contractContent: contractContent,
targetUserId: parseInt(contractTargetUserId) // 确保传递的是数字类型
})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data => {
alert('合同创建成功!');
// 刷新页面以显示新合同
location.reload();
})
.catch(error => {
console.error('创建合同失败:', error);
alert('创建合同失败,请重试');
});
}
遇到的困难:
在创建合同管理功能时,遇到过如下问题:
1,Spring Data JPA 在尝试创建 entityManagerFactory 时,发现 contract 表中的物理列 target_user_id 被映射到多个逻辑列名称(target_user_id 和 targetUserId)。这通常是因为在实体类中,同一个物理列被映射了两次,一次是通过 @JoinColumn 注解,另一次是通过实体类中的字段。
2,Contract 实体类中的 targetUser 字段没有正确地从 JSON 请求体中解析出来,导致 getTargetUser() 返回了 null,进而调用 getId() 方法时抛出了 NullPointerException。
3,ContractController 中,尝试将一个 String 类型的对象强制转换为 java.sql.Date 类型,导致了 ClassCastException。
4,ResponseEntity.status(400).body() 方法返回的类型与方法的返回类型不匹配。createContract 方法的返回类型是 ResponseEntity
这些在查看日志和使用开发者工具查看后检测,修改,都解决了。
今天的任务:
将组员已经写好的另一个模块合并起来,这样整个项目的web端就大概完成了。