You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
teamwk/www2/static/work1.html

457 lines
16 KiB

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>识别系统</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
padding: 20px;
background-color: #f8f8f8;
color: #333;
}
h1 {
text-align: center;
color: #009688;
}
p {
color: #666;
}
ul {
list-style-type: square;
margin-left: 20px;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: center;
}
th {
background-color: #f2f2f2;
}
img {
max-width: 100%;
height: auto;
margin-top: 20px;
}
.module {
padding: 10px;
margin: 10px;
border: 1px solid #009688;
background-color: #e0f2f1;
cursor: pointer;
transition: background-color 0.3s;
}
.module:hover {
background-color: #b2dfdb;
}
.return-btn {
display: block;
margin-top: 10px;
padding: 10px;
background-color: #138b5b;
color: #fff;
text-align: center;
text-decoration: none;
cursor: pointer;
border-radius: 5px;
}
.return-btn:hover {
background-color: #517900;
}
.link_button {
margin: 10px 5%;
padding: 10px 18px;
color: #fff;
font-size: 14px;
font-weight: bold;
border-radius: 4px;
background: #08fd6a;
text-decoration: none;
top: 20px;
position: relative;
width: 600px;
}
.custom-file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
background-color: #f1f1f1;
color: #333;
border-radius: 4px;
font-size: 16px;
}
.custom-file-upload:hover {
background-color: #e1e1e1;
}
.chart-container {
display: flex;
align-items: center;
justify-content: center;
}
#uploadChart {
max-width: 1000px;
max-height: 600px;
}
a {
color: #000;
text-decoration: none;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {//从后端获取用户名
var params = new URLSearchParams(window.location.search);
var username = params.get('username');
if (username) {
document.getElementById('username1').textContent = username;
}
});
document.addEventListener('DOMContentLoaded', function () {//从后端获取这个用户的身份user/admin
var params = new URLSearchParams(window.location.search);
if (userId === 'admin') {
document.getElementById('managementBtn').style.display = 'block'; // 显示后台管理按钮
} else {
document.getElementById('managementBtn').style.display = 'none'; // 隐藏后台管理按钮
}
});
</script>
</head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<body>
<!-- 把后端获取的用户名显示在欢迎标题上 -->
<h1>欢迎您,尊敬的 <span id="username1"></span></h1>
<p>欢迎访问识别系统!</p>
<!-- 按钮列表 -->
<div id="moduleSelection">
<div class="module" onclick="openModule('reservation')">识别查询</div>
<div class="module" onclick="openModule('management')" id="managementBtn">后台管理</div>
<div class="module" onclick="logout()" id="managementBtn">退出登录</div>
</div>
<div id="reservation" style="display: none;">
<h2>识别模块</h2>
<p>在这里上传你的图片进行识别。</p>
<form id="uploadForm" enctype="multipart/form-data">
<label for="fileInput" class="custom-file-upload">
<input type="file" id="fileInput" name="image" accept="image/*">
选择文件
</label>
<button class="return-btn" type="button" onclick="uploadImage()">上传并识别</button>
</form>
<a href="#" class="return-btn" onclick="goBack()">返回</a>
</div>
<div id="management" style="display: none;">
<h2>系统后台数据查询与管理模块</h2>
<table width="90%" class="table" id="userTable">
<tr>
<th>用户名</th>
<th>密码</th>
<th>身份</th>
<th>邮箱</th>
<th>上传次数</th>
<th>操作</th>
</tr>
</table>
<h1>查询用户上传次数</h1>
<div>
<label for="username">用户名:</label>
<input type="text" id="username">
<button onclick="searchUser()">查询</button>
</div>
<div id="result"></div>
<h1>上传文件统计</h1>
<div>
<div class="chart-container">
<canvas id="uploadChart" width="800" height="400"></canvas>
</div>
</div>
<script>
function logout() {
fetch(`/logout`).then(() => {
window.location.href = '/welcome.html'
})
}
let userId;
function searchUser() {
const username = document.getElementById('username').value;
fetch(`/api/user-images-count?username=${encodeURIComponent(username)}`)
.then(response => response.json())
.then(data => {
const resultDiv = document.getElementById('result');
if (data.error) {
resultDiv.innerText = data.error;
} else {
resultDiv.innerText = `${username} 上传了 ${data.imageCount} 张图片`;
}
})
.catch(error => {
console.error('Error:', error);
document.getElementById('result').innerText = '查询过程中发生错误';
});
}
let chartInstance;
function renderChart() {
fetch('/api/userUploads')
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('uploadChart').getContext('2d');
const labels = data.map(item => item.username);
const values = data.map(item => item.upload_count);
if (chartInstance) {
chartInstance.destroy();
}
chartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: '上传文件数量',
data: values,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
});
}
document.addEventListener('DOMContentLoaded', function () {
const userTable = document.getElementById('userTable');
fetch('/api/users')
.then(response => response.json())
.then(users => {
users.forEach(user => {
const row = userTable.insertRow();
row.innerHTML = `
<td><input type="text" value="${user.name}" data-oldname="${user.name}" /></td>
<td><input type="text" value="${user.passwd}" /></td>
<td>${user.id}</td>
<td><input type="text" value="${user.msg}" /></td>
<td>${user.imageCount}</td>
<td>
<button onclick="updateUser(this)">更新</button>
<button onclick="deleteUser(this)">删除</button>
</td>
`;
});
});
renderChart()
});
function updateUser(button) {
const row = button.parentElement.parentElement;
const name = row.cells[0].children[0].value;
const passwd = row.cells[1].children[0].value;
const id = row.cells[2].children[0].value;
const msg = row.cells[3].children[0].value;
const oldName = row.cells[0].children[0].getAttribute('data-oldname');
fetch('/api/updateUser', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ name, passwd, id, msg, oldName })
})
.then(response => response.json())
.then(data => {
alert(data.message);
});
}
function deleteUser(button) {
const row = button.parentElement.parentElement;
const name = row.cells[0].children[0].value;
fetch('/api/deleteUser', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ name })
})
.then(response => response.json())
.then(data => {
alert(data.message);
if (data.message === '用户删除成功') {
row.remove();
}
});
}
</script>
<a href="#" class="return-btn" onclick="goBack()">返回模块选择</a>
</div>
<!-- 页尾的一些用户友好内容 -->
<h2>联系我们</h2>
<p>如有任何关于系统的疑问或建议,请联系我们:</p>
<address>
电子邮件:<a href="mailto:aa893824054@163.com">aa893824054@163.com</a><br>
电话184-7635-1355
</address>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<script>
async function calculateHash(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function(event) {
const wordArray = CryptoJS.lib.WordArray.create(event.target.result);
const hash = CryptoJS.SHA256(wordArray);
resolve(hash.toString(CryptoJS.enc.Hex));
};
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}
function getHostname() {
var hostname = window.location.hostname;
console.log("当前页面的主机名是:" + hostname);
}
getHostname(); // 调用函数来获取主机名
// var port_count = 0 //(只有使用顺序分配策略时候才取消注释)
async function uploadImage() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
var urlParams = new URLSearchParams(window.location.search);
var username = urlParams.get('username');
var ports=[8084, 8085, 8086, 8087,8088]//识别功能端口组,一个口代表一个识别服务器
var randomPort = ports[Math.floor(Math.random() * ports.length)];// 从端口数组中随机选择一个端口
var host = window.location.hostname; // 获取当前页面的主机名
if (!file) {
alert('请选择一个文件');
return;
}
try {
const hashHex = await calculateHash(file);
console.log('文件哈希值:', hashHex);
const formData = new FormData(document.getElementById("uploadForm"));
fetch('http://' + host + ':' + randomPort + '/api/upload?user_name=' + username + '&fileHash=' + hashHex, {//随机分配策略
// fetch('http://' + host + ':' + ports[port_count] + '/api/upload?user_name=' + username + '&fileHash=' + hashHex, {//顺序分配策略
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
alert("识别结果: " + data.fileName);
renderChart();
// port_count = (port_count + 1) % ports.length;// 更新索引以循环使用端口数组(顺序分配时使用,用随机策略时要注释掉)
})
.catch(error => console.error('Error:', error));
} catch (error) {
console.error('Error calculating hash:', error);
alert('计算文件哈希值时发生错误');
}
}
function openModule(moduleId) {//打开模块的功能
var modules = document.getElementsByClassName('module');
for (var i = 0; i < modules.length; i++) {
modules[i].style.display = 'none';
}
document.getElementById('moduleSelection').style.display = 'none';
document.getElementById(moduleId).style.display = 'block';
}
document.addEventListener('DOMContentLoaded', function () {//监听程序,用来解决:点击返回按钮后重新出现“后台管理”按钮的问题
var params = new URLSearchParams(window.location.search);
if (username) {
}
updateManagementButtonDisplay(userId);
})
fetch('/user-info')
.then(response => {
if (!response.ok) {
throw new Error('未登录');
}
return response.json();
})
.then(data => {
document.getElementById('username1').textContent = data.username;
userId = data.id
username = data.username
updateManagementButtonDisplay(userId);
})
.catch(error => {
alert(error.message);
window.location.href = 'welcome.html';
});
function updateManagementButtonDisplay(userId) {//根据身份设定“后台管理”按钮是否隐藏
if (userId === 'admin') {
document.getElementById('managementBtn').style.display = 'block';
} else {
document.getElementById('managementBtn').style.display = 'none';
}
}
function goBack() {//返回功能同时也是“不断监测id来决定是否隐藏后台管理按钮”的功能的组成部分
var modules = document.getElementsByClassName('module');
for (var i = 0; i < modules.length; i++) {
modules[i].style.display = 'block';
}
document.getElementById("moduleSelection").style.display = 'block';
document.getElementById("reservation").style.display = 'none';
document.getElementById("management").style.display = 'none';
var params = new URLSearchParams(window.location.search);
updateManagementButtonDisplay(userId);
}
</script>
</body>
</html>