Browse Source

添加登录功能和邀请者信息传递功能

master
Default User 1 month ago
parent
commit
7b460ccbf8
  1. 13
      certificate.html
  2. 44
      invite.html
  3. 202
      login.html
  4. 150
      server.js

13
certificate.html

@ -948,6 +948,19 @@
const sessionId = getSessionId();
urlEncodedData.append('sessionId', sessionId);
// 从URL参数中获取邀请者信息
const urlParams = new URLSearchParams(window.location.search);
const inviter = urlParams.get('inviter');
const inviterPhone = urlParams.get('inviterPhone');
// 添加邀请者信息
if (inviter) {
urlEncodedData.append('inviter', inviter);
}
if (inviterPhone) {
urlEncodedData.append('inviterPhone', inviterPhone);
}
// 发送数据到服务器
fetch('/submit', {
method: 'POST',

44
invite.html

@ -154,6 +154,14 @@
</head>
<body>
<div class="container">
<div class="user-info" style="background-color: #f8f9fa; border-radius: 8px; padding: 15px; margin-bottom: 20px;">
<h3 style="font-size: 16px; color: #333; margin-bottom: 10px;">登录信息</h3>
<div id="userInfo" style="font-size: 14px; color: #666;">
<p>姓名:<span id="userName">未登录</span></p>
<p>电话:<span id="userPhone">未登录</span></p>
</div>
</div>
<div class="header">
<h1>生成邀请二维码</h1>
<p>创建一个二维码,邀请他人填写合格证信息</p>
@ -187,11 +195,42 @@
</div>
<script>
// 加载用户信息
function loadUserInfo() {
const userInfo = localStorage.getItem('userInfo');
if (userInfo) {
try {
const user = JSON.parse(userInfo);
document.getElementById('userName').textContent = user.name || user.userName;
document.getElementById('userPhone').textContent = user.phoneNumber || '未提供';
} catch (error) {
console.error('解析用户信息失败:', error);
}
}
}
// 生成邀请二维码
function generateInviteQR() {
// 生成包含会话ID的URL
const sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
const inviteUrl = `http://8.137.125.67:3008/certificate.html?sessionId=${encodeURIComponent(sessionId)}`;
// 获取用户信息
const userInfo = localStorage.getItem('userInfo');
let inviterName = '';
let inviterPhone = '';
if (userInfo) {
try {
const user = JSON.parse(userInfo);
inviterName = user.name || user.userName;
inviterPhone = user.phoneNumber || '';
} catch (error) {
console.error('解析用户信息失败:', error);
}
}
// 构建邀请URL,包含会话ID和邀请者信息
const inviteUrl = `http://8.137.125.67:3008/certificate.html?sessionId=${encodeURIComponent(sessionId)}&inviter=${encodeURIComponent(inviterName)}&inviterPhone=${encodeURIComponent(inviterPhone)}`;
// 使用Google Charts API生成二维码
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent(inviteUrl)}`;
@ -203,8 +242,9 @@
alert('邀请二维码生成成功!\n\n请将此二维码分享给需要填写信息的人。\n\n对方填写完成后,您可以通过相同的二维码查看和导出信息。');
}
// 页面加载时自动生成二维码
// 页面加载时自动生成二维码并加载用户信息
window.onload = function() {
loadUserInfo();
generateInviteQR();
};
</script>

202
login.html

@ -0,0 +1,202 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>登录</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #f5f5f5;
color: #333;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
max-width: 400px;
width: 90%;
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
padding: 24px;
}
.header {
text-align: center;
margin-bottom: 24px;
}
.header h1 {
font-size: 24px;
font-weight: 600;
color: #28a745;
margin-bottom: 8px;
}
.header p {
font-size: 14px;
color: #666;
}
.form-group {
margin-bottom: 16px;
}
.form-group label {
display: block;
margin-bottom: 6px;
font-size: 14px;
font-weight: 500;
color: #333;
}
.form-group input {
width: 100%;
padding: 12px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.form-group input:focus {
outline: none;
border-color: #28a745;
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
}
.btn {
width: 100%;
padding: 12px;
border: none;
border-radius: 4px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.15s ease-in-out;
}
.btn-primary {
background-color: #28a745;
color: white;
}
.btn-primary:hover {
background-color: #218838;
}
.error-message {
background-color: #f8d7da;
color: #721c24;
padding: 12px;
border-radius: 4px;
margin-bottom: 16px;
font-size: 14px;
display: none;
}
.success-message {
background-color: #d4edda;
color: #155724;
padding: 12px;
border-radius: 4px;
margin-bottom: 16px;
font-size: 14px;
display: none;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>登录</h1>
<p>请输入您的用户名和密码</p>
</div>
<div class="error-message" id="errorMessage"></div>
<div class="success-message" id="successMessage"></div>
<form id="loginForm">
<div class="form-group">
<label for="userName">用户名</label>
<input type="text" id="userName" name="userName" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
<script>
// 显示错误信息
function showError(message) {
const errorElement = document.getElementById('errorMessage');
const successElement = document.getElementById('successMessage');
errorElement.textContent = message;
errorElement.style.display = 'block';
successElement.style.display = 'none';
}
// 显示成功信息
function showSuccess(message) {
const errorElement = document.getElementById('errorMessage');
const successElement = document.getElementById('successMessage');
successElement.textContent = message;
successElement.style.display = 'block';
errorElement.style.display = 'none';
}
// 表单提交处理
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const userName = document.getElementById('userName').value.trim();
const password = document.getElementById('password').value;
// 验证输入
if (!userName || !password) {
showError('请输入用户名和密码');
return;
}
// 发送登录请求
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
userName: userName,
password: password
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// 登录成功,保存用户信息到本地存储
localStorage.setItem('userInfo', JSON.stringify(data.user));
// 跳转到邀请页面
window.location.href = 'invite.html';
} else {
showError(data.error || '登录失败,请重试');
}
})
.catch(error => {
console.error('登录失败:', error);
showError('网络错误,请重试');
});
});
</script>
</body>
</html>

150
server.js

@ -76,6 +76,138 @@ const server = http.createServer(async (req, res) => {
return;
}
// 登录接口
if (req.method === 'POST' && req.url === '/login') {
try {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
// 解析表单数据
const formData = new URLSearchParams(body);
const userName = formData.get('userName');
const password = formData.get('password');
console.log('接收到的登录请求:', { userName });
// 验证输入
if (!userName || !password) {
res.writeHead(400, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end(JSON.stringify({
success: false,
error: '请输入用户名和密码'
}));
return;
}
// 连接到userlogin数据库
const userloginPool = mysql.createPool({
...dbConfig,
database: 'userlogin'
});
// 验证用户名和密码
const [loginRows] = await userloginPool.execute(
'SELECT * FROM login WHERE userName = ? AND password = ?',
[userName, password]
);
if (loginRows.length === 0) {
res.writeHead(401, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end(JSON.stringify({
success: false,
error: '用户名或密码错误'
}));
return;
}
const loginInfo = loginRows[0];
const managerId = loginInfo.managerId;
// 获取用户详细信息
const [personnelRows] = await userloginPool.execute(
'SELECT * FROM personnel WHERE managerId = ?',
[managerId]
);
let userInfo = {
userName: loginInfo.userName,
projectName: loginInfo.projectName,
managerId: loginInfo.managerId
};
if (personnelRows.length > 0) {
const personnelInfo = personnelRows[0];
userInfo = {
...userInfo,
name: personnelInfo.name,
phoneNumber: personnelInfo.phoneNumber,
managercompany: personnelInfo.managercompany,
managerdepartment: personnelInfo.managerdepartment,
organization: personnelInfo.organization,
alias: personnelInfo.alias
};
}
console.log('登录成功,用户信息:', userInfo);
// 返回成功响应
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end(JSON.stringify({
success: true,
user: userInfo
}));
// 关闭临时连接池
await userloginPool.end();
} catch (error) {
console.error('处理登录请求失败:', error.message);
res.writeHead(500, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end(JSON.stringify({
success: false,
error: '登录失败,请重试'
}));
}
});
} catch (error) {
console.error('登录请求处理失败:', error.message);
res.writeHead(500, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end(JSON.stringify({
success: false,
error: '登录失败,请重试'
}));
}
return;
}
// 处理GET请求,获取最新的合格证信息
if (req.method === 'GET' && req.url.startsWith('/getLatestCertificate')) {
try {
@ -88,10 +220,10 @@ const server = http.createServer(async (req, res) => {
// 从数据库获取对应会话的最新合格证信息
let query, params;
if (sessionId) {
query = 'SELECT company as subjectName, phoneNumber as contact, productName, grossWeight as weight, commitBasis as basis, origin, DATE_FORMAT(issueDate, "%Y-%m-%d") as date, signature, qrCodeUrl FROM certificate WHERE sessionId = ? ORDER BY id DESC LIMIT 1';
query = 'SELECT company as subjectName, phoneNumber as contact, productName, grossWeight as weight, commitBasis as basis, origin, DATE_FORMAT(issueDate, "%Y-%m-%d") as date, signature, qrCodeUrl, inviter, inviter_phone as inviterPhone FROM certificate WHERE sessionId = ? ORDER BY id DESC LIMIT 1';
params = [sessionId];
} else {
query = 'SELECT company as subjectName, phoneNumber as contact, productName, grossWeight as weight, commitBasis as basis, origin, DATE_FORMAT(issueDate, "%Y-%m-%d") as date, signature, qrCodeUrl FROM certificate WHERE sessionId IS NULL ORDER BY id DESC LIMIT 1';
query = 'SELECT company as subjectName, phoneNumber as contact, productName, grossWeight as weight, commitBasis as basis, origin, DATE_FORMAT(issueDate, "%Y-%m-%d") as date, signature, qrCodeUrl, inviter, inviter_phone as inviterPhone FROM certificate WHERE sessionId IS NULL ORDER BY id DESC LIMIT 1';
params = [];
}
@ -147,7 +279,9 @@ const server = http.createServer(async (req, res) => {
origin: formData.get('origin'),
date: now,
signature: formData.get('signature'),
sessionId: sessionId
sessionId: sessionId,
inviter: formData.get('inviter'),
inviterPhone: formData.get('inviterPhone')
};
console.log('接收到的表单数据:', {
@ -159,7 +293,9 @@ const server = http.createServer(async (req, res) => {
origin: certificate.origin,
date: certificate.date.toISOString(),
hasSignature: !!certificate.signature,
sessionId: sessionId
sessionId: sessionId,
inviter: certificate.inviter,
inviterPhone: certificate.inviterPhone
});
// 处理手写签名,上传到OSS
@ -218,8 +354,8 @@ const server = http.createServer(async (req, res) => {
// 插入数据到数据库
await pool.execute(
'INSERT INTO certificate (company, phoneNumber, productName, grossWeight, commitBasis, origin, issueDate, signature, sessionId, qrCodeUrl) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[certificate.subjectName, certificate.contact, certificate.productName, certificate.weight, certificate.basis, certificate.origin, certificate.date, signatureUrl, certificate.sessionId, qrCodeUrl]
'INSERT INTO certificate (company, phoneNumber, productName, grossWeight, commitBasis, origin, issueDate, signature, sessionId, qrCodeUrl, inviter, inviter_phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[certificate.subjectName, certificate.contact, certificate.productName, certificate.weight, certificate.basis, certificate.origin, certificate.date, signatureUrl, certificate.sessionId, qrCodeUrl, certificate.inviter, certificate.inviterPhone]
);
console.log('数据插入数据库成功');
@ -229,6 +365,8 @@ const server = http.createServer(async (req, res) => {
...certificate,
signature: signatureUrl,
qrCodeUrl: qrCodeUrl,
inviter: certificate.inviter,
inviterPhone: certificate.inviterPhone,
// 格式化日期为YYYY-MM-DD格式
date: certificate.date.toISOString().split('T')[0]
};

Loading…
Cancel
Save