Jelajahi Sumber

AI: 增强版会友信息考勤打卡系统

D8D AI 1 tahun lalu
induk
melakukan
bb730030e8

+ 7 - 4
package.json

@@ -2,15 +2,18 @@
   "name": "member-attendance-system",
   "version": "1.0.0",
   "description": "会友信息考勤打卡系统",
-  "main": "server.js",
+  "main": "server/index.js",
   "scripts": {
-    "start": "node server.js",
-    "dev": "nodemon server.js"
+    "start": "node server/index.js",
+    "dev": "nodemon server/index.js"
   },
   "dependencies": {
     "express": "^4.17.1",
     "cors": "^2.8.5",
-    "body-parser": "^1.19.0"
+    "body-parser": "^1.19.0",
+    "mongoose": "^6.0.12",
+    "dotenv": "^10.0.0",
+    "mqtt": "^4.2.8"
   },
   "devDependencies": {
     "nodemon": "^2.0.14"

+ 10 - 0
server/models/Device.js

@@ -0,0 +1,10 @@
+const mongoose = require('mongoose');
+
+const DeviceSchema = new mongoose.Schema({
+  deviceId: { type: String, required: true, unique: true },
+  name: { type: String, required: true },
+  status: { type: String, enum: ['online', 'offline'], default: 'offline' },
+  lastSeen: { type: Date }
+});
+
+module.exports = mongoose.model('Device', DeviceSchema);

+ 11 - 0
server/models/Member.js

@@ -0,0 +1,11 @@
+const mongoose = require('mongoose');
+
+const MemberSchema = new mongoose.Schema({
+  name: { type: String, required: true },
+  phone: { type: String },
+  email: { type: String },
+  joinDate: { type: Date, default: Date.now },
+  attendance: [{ type: Date }]
+});
+
+module.exports = mongoose.model('Member', MemberSchema);

+ 34 - 0
server/routes/attendance.js

@@ -0,0 +1,34 @@
+const express = require('express');
+const router = express.Router();
+const Member = require('../models/Member');
+
+// 记录考勤
+router.post('/', async (req, res) => {
+  const { memberId, date } = req.body;
+  try {
+    const member = await Member.findById(memberId);
+    if (!member) {
+      return res.status(404).json({ message: '会员不存在' });
+    }
+    member.attendance.push(date);
+    await member.save();
+    res.json(member);
+  } catch (err) {
+    res.status(500).json({ message: err.message });
+  }
+});
+
+// 获取会员考勤记录
+router.get('/:memberId', async (req, res) => {
+  try {
+    const member = await Member.findById(req.params.memberId);
+    if (!member) {
+      return res.status(404).json({ message: '会员不存在' });
+    }
+    res.json(member.attendance);
+  } catch (err) {
+    res.status(500).json({ message: err.message });
+  }
+});
+
+module.exports = router;

+ 48 - 0
server/routes/devices.js

@@ -0,0 +1,48 @@
+const express = require('express');
+const router = express.Router();
+const Device = require('../models/Device');
+
+// 获取所有设备
+router.get('/', async (req, res) => {
+  try {
+    const devices = await Device.find();
+    res.json(devices);
+  } catch (err) {
+    res.status(500).json({ message: err.message });
+  }
+});
+
+// 添加新设备
+router.post('/', async (req, res) => {
+  const device = new Device({
+    deviceId: req.body.deviceId,
+    name: req.body.name
+  });
+
+  try {
+    const newDevice = await device.save();
+    res.status(201).json(newDevice);
+  } catch (err) {
+    res.status(400).json({ message: err.message });
+  }
+});
+
+// 更新设备状态
+router.patch('/:deviceId', async (req, res) => {
+  try {
+    const device = await Device.findOne({ deviceId: req.params.deviceId });
+    if (!device) {
+      return res.status(404).json({ message: '设备不存在' });
+    }
+    if (req.body.status) {
+      device.status = req.body.status;
+    }
+    device.lastSeen = new Date();
+    const updatedDevice = await device.save();
+    res.json(updatedDevice);
+  } catch (err) {
+    res.status(400).json({ message: err.message });
+  }
+});
+
+module.exports = router;

+ 80 - 0
server/routes/members.js

@@ -0,0 +1,80 @@
+const express = require('express');
+const router = express.Router();
+const Member = require('../models/Member');
+
+// 获取所有会员
+router.get('/', async (req, res) => {
+  try {
+    const members = await Member.find();
+    res.json(members);
+  } catch (err) {
+    res.status(500).json({ message: err.message });
+  }
+});
+
+// 添加新会员
+router.post('/', async (req, res) => {
+  const member = new Member({
+    name: req.body.name,
+    phone: req.body.phone,
+    email: req.body.email
+  });
+
+  try {
+    const newMember = await member.save();
+    res.status(201).json(newMember);
+  } catch (err) {
+    res.status(400).json({ message: err.message });
+  }
+});
+
+// 获取特定会员
+router.get('/:id', getMember, (req, res) => {
+  res.json(res.member);
+});
+
+// 更新会员信息
+router.patch('/:id', getMember, async (req, res) => {
+  if (req.body.name != null) {
+    res.member.name = req.body.name;
+  }
+  if (req.body.phone != null) {
+    res.member.phone = req.body.phone;
+  }
+  if (req.body.email != null) {
+    res.member.email = req.body.email;
+  }
+  try {
+    const updatedMember = await res.member.save();
+    res.json(updatedMember);
+  } catch (err) {
+    res.status(400).json({ message: err.message });
+  }
+});
+
+// 删除会员
+router.delete('/:id', getMember, async (req, res) => {
+  try {
+    await res.member.remove();
+    res.json({ message: '会员已删除' });
+  } catch (err) {
+    res.status(500).json({ message: err.message });
+  }
+});
+
+async function getMember(req, res, next) {
+  let member;
+  try {
+    member = await Member.findById(req.params.id);
+    if (member == null) {
+      return res.status(404).json({ message: '找不到会员' });
+    }
+  } catch (err) {
+    return res.status(500).json({ message: err.message });
+  }
+
+  res.member = member;
+  next();
+}
+
+module.exports = router;