搭建作业文件服务器

apt install npm
apt install nodejs
mkdir file-server
cd file-server
npm init -y
npm install express multer mysql2
npm install uuid
npm install bcryptjs
mysql -u root

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;

nano server.js

const express = require('express');
const multer = require('multer');
const path = require('path');
const mysql = require('mysql2');
const bcrypt = require('bcryptjs');  // 用于密码加密
const bodyParser = require('body-parser');

const cors = require('cors');
app.use(cors({
  origin: '*', // 暂时允许所有来源
  methods: ['GET', 'POST'], // 允许的 HTTP 方法
  allowedHeaders: ['Content-Type'], // 允许的请求头
}));

const app = express();
const port = 817;
// 提供 public 文件夹下的静态文件
app.use(express.static('public'));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 文件存储配置
const assignmentStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/assignments/');
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname));
  }
});

const submissionStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/submissions/');
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname));
  }
});

const assignmentUpload = multer({ storage: assignmentStorage });
const submissionUpload = multer({ storage: submissionStorage });

// 数据库连接
const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '123456',  // 根据数据库配置修改密码
  database: 'file_server'
});

db.connect((err) => {
  if (err) {
    console.error('数据库连接失败:', err);
    return;
  }
  console.log('数据库连接成功');
});

// 登录接口:验证用户身份
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // 查询用户信息
  const query = 'SELECT * FROM users WHERE username = ?';
  db.query(query, [username], (err, results) => {
    if (err) {
      return res.status(500).send('数据库查询失败');
    }

    if (results.length === 0) {
      return res.status(404).send('用户不存在');
    }

    const user = results[0];
    // 使用 bcrypt 验证密码
    bcrypt.compare(password, user.password, (err, match) => {
      if (err || !match) {
        return res.status(401).send('密码错误');
      }

      // 返回用户 ID 和角色信息
      res.send({
        userId: user.id,
        role: user.role
      });
    });
  });
});

app.get('/files/assignments', (req, res) => {
  db.query("SELECT filename, file_path FROM files WHERE type='assignment'", (err, results) => {
    if (err) return res.status(500).send('查询失败');
    res.send(results);
  });
});

app.get('/files/submissions', (req, res) => {
  db.query("SELECT filename, file_path FROM files WHERE type='submission'", (err, results) => {
    if (err) return res.status(500).send('查询失败');
    res.send(results);
  });
});

app.get('/download', (req, res) => {
  const filePath = req.query.filePath;
  res.download(filePath, (err) => {
    if (err) res.status(500).send('下载失败');
  });
});


// 上传作业题目接口(教师)
app.post('/upload/assignment', assignmentUpload.single('file'), (req, res) => {
  const userId = req.body.userId;
  
  // 验证用户是否为教师
  const query = 'SELECT role FROM users WHERE id = ?';
  db.query(query, [userId], (err, results) => {
    if (err || results.length === 0) {
      return res.status(500).send('用户验证失败');
    }

    const userRole = results[0].role;
    if (userRole !== 'teacher') {
      return res.status(403).send('仅教师可以上传作业题目');
    }

    const { originalname, path, size } = req.file;

    const insertQuery = 'INSERT INTO files (user_id, filename, file_path, size, type) VALUES (?, ?, ?, ?, ?)';
    db.query(insertQuery, [userId, originalname, path, size, 'assignment'], (err, result) => {
      if (err) {
        return res.status(500).send('作业题目上传失败');
      }
      res.send('作业题目上传成功');
    });
  });
});


// 上传作业提交接口(学生)
app.post('/upload/submission', submissionUpload.single('file'), (req, res) => {
  const userId = req.body.userId;
  
  // 验证用户是否为学生
  const query = 'SELECT role FROM users WHERE id = ?';
  db.query(query, [userId], (err, results) => {
    if (err || results.length === 0) {
      return res.status(500).send('用户验证失败');
    }

    const userRole = results[0].role;
    if (userRole !== 'student') {
      return res.status(403).send('仅学生可以上传作业');
    }

    const { originalname, path, size } = req.file;

    const insertQuery = 'INSERT INTO files (user_id, filename, file_path, size, type) VALUES (?, ?, ?, ?, ?)';
    db.query(insertQuery, [userId, originalname, path, size, 'submission'], (err, result) => {
      if (err) {
        return res.status(500).send('作业提交失败');
      }
      res.send('作业提交成功');
    });
  });
});

// 启动服务器
app.listen(port,'0.0.0.0',() => {
  console.log(`服务器启动,监听端口 ${port}`);
});




mkdir uploads
mkdir -p uploads/assignments
mkdir -p uploads/submissions
apt install mysql-client-core-8.0
apt install mysql-server
mysql -u root -p

CREATE DATABASE file_server;

USE file_server;

-- 创建用户表
CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(100) NOT NULL,
  password VARCHAR(255) NOT NULL
);

-- 创建文件表
CREATE TABLE files (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  filename VARCHAR(255) NOT NULL,
  file_path VARCHAR(255) NOT NULL,
  size INT NOT NULL,
  upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  type ENUM('assignment', 'submission') NOT NULL,  -- 类型:作业题目或提交文件
  FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 修改 users 表,添加角色字段
ALTER TABLE users ADD COLUMN role ENUM('teacher', 'student') NOT NULL;

-- 更新用户角色 (假设前10个用户中,1-5 为教师,6-10 为学生)
UPDATE users SET role = 'teacher' WHERE id BETWEEN 1 AND 10;
UPDATE users SET role = 'student' WHERE id BETWEEN 11 AND 15;

USE file_server;

-- 插入十个用户,前五个为教师,后五个为学生
INSERT INTO users (username, password, role) VALUES
('user1', 'password1', 'student'),
('user2', 'password2', 'student'),
('user3', 'password3', 'student'),
('user4', 'password4', 'student'),
('user5', 'password5', 'student'),
('user6', 'password6', 'student'),
('user7', 'password7', 'student'),
('user8', 'password8', 'student'),
('user9', 'password9', 'student'),
('user11', 'password11', 'teacher'),
('user10', 'password10', 'student');

mkdir public
cd public
nano login.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>用户登录</title>
</head>
<body>
  <h2>用户登录</h2>
  <form id="loginForm">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username" required>
    <br>
    <label for="password">密码:</label>
    <input type="password" id="password" name="password" required>
    <br>
    <button type="submit">登录</button>
  </form>
  
  <div id="roleSection" style="display:none;">
    <h3>选择操作</h3>
    <div id="teacherUpload" style="display:none;">
      <button onclick="window.location.href='/upload/assignment-upload.html'">上传作业题目</button>
      <button onclick="window.location.href='/download/teacher-download.html'">下载学生答案</button>
    </div>
    <div id="studentUpload" style="display:none;">
      <button onclick="window.location.href='/upload/submission-upload.html'">提交作业</button>
      <button onclick="window.location.href='/download/student-download.html'">下载作业题目</button>
    </div>
  </div>

  <script>
    const loginForm = document.getElementById('loginForm');
    const roleSection = document.getElementById('roleSection');
    const teacherUpload = document.getElementById('teacherUpload');
    const studentUpload = document.getElementById('studentUpload');

    loginForm.addEventListener('submit', async (event) => {
      event.preventDefault();

      const username = document.getElementById('username').value;
      const password = document.getElementById('password').value;

      const response = await fetch('/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, password })
      });

      if (response.ok) {
        const data = await response.json();
        roleSection.style.display = 'block';
        loginForm.style.display = 'none';

        if (data.role === 'teacher') {
          teacherUpload.style.display = 'block';
        } else if (data.role === 'student') {
          studentUpload.style.display = 'block';
        }
      } else {
        alert('登录失败,请检查用户名和密码');
      }
    });
  </script>
</body>
</html>

mkdir upload
cd upload
nano assignment-upload.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>上传作业题目</title>
</head>
<body>
  <h2>上传作业题目</h2>
  <form action="http://10.34.67.251:817/upload/assignment" method="post" enctype="multipart/form-data">
    <label for="file">选择作业文件:</label>
    <input type="file" name="file" required>
    <br>
    <label for="userId">用户 ID:</label>
    <input type="text" name="userId" required>
    <br>
    <button type="submit">上传作业题目</button>
  </form>
</body>
</html>

nano submission-upload.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>提交作业</title>
</head>
<body>
  <h2>提交作业</h2>
  <form action="http://10.34.67.251:817/upload/submission" method="post" enctype="multipart/form-data">
    <label for="file">选择作业文件:</label>
    <input type="file" name="file" required>
    <br>
    <label for="userId">用户 ID:</label>
    <input type="text" name="userId" required>
    <br>
    <button type="submit">提交作业</button>
  </form>
</body>
</html>

mkdir download/
nano student-download.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>下载作业题目</title>
</head>
<body>
  <h2>下载作业题目</h2>
  <ul id="fileList"></ul>
  <script>
    async function fetchFiles() {
      const response = await fetch('/files/assignments');
      const files = await response.json();
      const fileList = document.getElementById('fileList');
      files.forEach(file => {
        const li = document.createElement('li');
        li.innerHTML = `<a href="/download?filePath=${file.file_path}">${file.filename}</a>`;
        fileList.appendChild(li);
      });
    }
    fetchFiles();
  </script>
</body>
</html>

nano teacher-download.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>下载学生答案</title>
</head>
<body>
  <h2>下载学生答案</h2>
  <ul id="fileList"></ul>
  <script>
    async function fetchFiles() {
      const response = await fetch('/files/submissions');
      const files = await response.json();
      const fileList = document.getElementById('fileList');
      files.forEach(file => {
        const li = document.createElement('li');
        li.innerHTML = `<a href="/download?filePath=${file.file_path}">${file.filename}</a>`;
        fileList.appendChild(li);
      });
    }
    fetchFiles();
  </script>
</body>
</html>

nano encryptPasswords.js

const bcrypt = require('bcryptjs');
const mysql = require('mysql2');

// 创建数据库连接
const db = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '123456',  // 请根据您的数据库配置修改密码
  database: 'file_server'
});

// 获取所有用户的密码并加密
const encryptPasswords = async () => {
  db.query('SELECT id, password FROM users', async (err, results) => {
    if (err) {
      console.error('查询用户失败:', err);
      return;
    }

    for (const user of results) {
      // 对密码进行加密
      const hashedPassword = await bcrypt.hash(user.password, 10);
      
      // 更新数据库中的密码为加密后的密码
      db.query('UPDATE users SET password = ? WHERE id = ?', [hashedPassword, user.id], (updateErr, updateResult) => {
        if (updateErr) {
          console.error('更新密码失败:', updateErr);
        } else {
          console.log(`用户 ID: ${user.id} 密码已更新`);
        }
      });
    }
  });
};

// 调用函数
encryptPasswords();

node encryptPasswords.js
node server.js

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇