1. 设置项目结构
questionnaire-system/
client/ // 前端应用
src/
components/ // React组件
pages/ // 页面
App.js
index.js
server/ // 后端服务
routes/ // 路由
models/ // 数据模型
app.js
package.json
2. 启动前端应用
在client
目录下,创建React应用并启动它:
npx create-react-app .
npm start
3. 设置Express后端
在server
目录下,设置Express后端:
npm init -y
npm install express mongoose body-parser cors
在server/app.js
中设置Express应用:
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
app.use(cors());
app.use(bodyParser.json());
// 设置数据库连接
mongoose.connect("mongodb://localhost/questionnaire", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "数据库连接错误"));
db.once("open", function () {
console.log("数据库连接成功");
});
// 设置路由
const authRoutes = require("./routes/auth");
const questionnaireRoutes = require("./routes/questionnaire");
app.use("/auth", authRoutes);
app.use("/questionnaire", questionnaireRoutes);
app.listen(5000, () => {
console.log("后端服务已启动,端口5000");
});
4. 创建Express路由
在server/routes
目录下,创建路由文件,例如auth.js
和questionnaire.js
,以处理用户身份验证和问卷操作。
创建auth.js
用于用户身份验证:
const express = require("express");
const router = express.Router();
// 处理用户注册
router.post("/register", (req, res) => {
// 实现用户注册逻辑
});
// 处理用户登录
router.post("/login", (req, res) => {
// 实现用户登录逻辑
});
// 处理用户注销
router.post("/logout", (req, res) => {
// 实现用户注销逻辑
});
module.exports = router;
创建questionnaire.js
用于问卷操作:
const express = require("express");
const router = express.Router();
// 处理创建问卷
router.post("/create", (req, res) => {
// 实现创建问卷逻辑
});
// 处理发布问卷
router.post("/publish", (req, res) => {
// 实现发布问卷逻辑
});
// 处理填写问卷
router.post("/submit", (req, res) => {
// 实现填写问卷逻辑
});
// 处理查看问卷结果
router.get("/results/:id", (req, res) => {
const questionnaireId = req.params.id;
// 实现查看问卷结果逻辑
});
module.exports = router;
5. 创建数据模型
在server/models
目录下,创建Mongoose模型来定义用户、问卷等数据结构。
在server/models
目录下,创建一个名为User.js
的文件来定义用户数据模型:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
// 其他用户相关字段
});
const User = mongoose.model("User", userSchema);
module.exports = User;
然后,创建一个名为Questionnaire.js
的文件来定义问卷数据模型:
const mongoose = require("mongoose");
const questionnaireSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
description: String,
questions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Question",
},
],
// 其他问卷相关字段
});
const Questionnaire = mongoose.model("Questionnaire", questionnaireSchema);
module.exports = Questionnaire;
在Express应用的server/app.js
文件中,确保您已经连接了MongoDB数据库
mongoose.connect("mongodb://localhost/questionnaire", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
6. 设置React组件和页面
在前端应用中,创建React组件和页面来实现问卷设计、问卷发布、问卷填写、账户管理等功能。
在前端应用中,您需要创建React组件和页面来实现不同的功能,包括问卷设计、问卷发布、问卷填写和账户管理。以下是一个项目结构:
client/
src/
components/
Auth/ // 用户身份验证相关组件
Questionnaire/ // 问卷相关组件
Account/ // 账户管理相关组件
pages/
Home.js // 主页
Login.js // 登录页
Register.js // 注册页
CreateQuestionnaire.js // 创建问卷页
FillQuestionnaire.js // 填写问卷页
AccountSettings.js // 账户设置页
App.js // 主应用组件
index.js // 渲染应用
CreateQuestionnaire.js 代码
import React, { useState } from "react";
function CreateQuestionnaire() {
const [questionnaire, setQuestionnaire] = useState({
title: "",
description: "",
questions: [],
});
const addQuestion = () => {
// 在状态中添加新问题
const newQuestion = {
text: "",
options: [],
};
setQuestionnaire((prev) => ({
...prev,
questions: [...prev.questions, newQuestion],
}));
};
const handleQuestionChange = (index, field, value) => {
// 更新特定问题的字段
setQuestionnaire((prev) => {
const updatedQuestions = [...prev.questions];
updatedQuestions[index][field] = value;
return { ...prev, questions: updatedQuestions };
});
};
const saveQuestionnaire = () => {
// 将问卷数据发送到后端保存
// 可以使用Fetch或Axios发送POST请求
console.log("保存问卷数据:", questionnaire);
};
return (
Create Questionnaire
setQuestionnaire({ ...questionnaire, title: e.target.value })}
/>
Questions
{questionnaire.questions.map((question, index) => (
handleQuestionChange(index, "text", e.target.value)}
/>
))}
);
}
export default CreateQuestionnaire;
7. 实现问卷设计和发布
允许用户创建问卷,并将问卷保存到数据库。允许用户发布问卷链接。
const express = require("express");
const router = express.Router();
const Questionnaire = require("../models/Questionnaire");
// 创建问卷
router.post("/create", async (req, res) => {
const { title, description, questions } = req.body;
try {
const newQuestionnaire = new Questionnaire({
title,
description,
questions,
});
const savedQuestionnaire = await newQuestionnaire.save();
res.json({ questionnaireId: savedQuestionnaire._id });
} catch (error) {
res.status(500).json({ error: "问卷保存失败" });
}
});
// ...其他问卷相关路由
module.exports = router;
8. 实现问卷填写和收集
用户可以填写问卷,并将答案保存到数据库。
前端实现:
下面是FillQuestionnaire.js
组件的更新,以包括保存答案到后端的功能。
import React, { useState } from "react";
import axios from "axios";
function FillQuestionnaire({ questionnaireId }) {
const [answers, setAnswers] = useState([]);
const [questionnaire, setQuestionnaire] = useState(null);
// 从后端获取问卷数据
useEffect(() => {
axios.get(`/api/questionnaire/${questionnaireId}`).then((response) => {
setQuestionnaire(response.data);
});
}, [questionnaireId]);
const handleAnswerChange = (questionIndex, answer) => {
// 更新答案
const updatedAnswers = [...answers];
updatedAnswers[questionIndex] = answer;
setAnswers(updatedAnswers);
};
const submitAnswers = () => {
// 将答案数据发送到后端保存
axios
.post(`/api/questionnaire/submit/${questionnaireId}`, { answers })
.then((response) => {
console.log("答案提交成功", response.data);
// 可以进行其他操作,如重定向到感谢页面
})
.catch((error) => {
console.error("答案提交失败", error);
});
};
return (
{questionnaire && (
{questionnaire.title}
{questionnaire.description}
)}
);
}
export default FillQuestionnaire;
后端实现:
以下是一个简化的后端路由 server/routes/questionnaire.js
:
const express = require("express");
const router = express.Router();
const Questionnaire = require("../models/Questionnaire");
// 提交问卷答案
router.post("/submit/:questionnaireId", async (req, res) => {
const questionnaireId = req.params.questionnaireId;
const answers = req.body.answers;
try {
const questionnaire = await Questionnaire.findById(questionnaireId);
if (!questionnaire) {
return res.status(404).json({ error: "问卷不存在" });
}
// 将答案与问卷关联,保存到数据库
// 您可以根据实际需求设计数据库结构来存储答案数据
res.json({ message: "答案保存成功" });
} catch (error) {
res.status(500).json({ error: "答案保存失败" });
}
});
// ...其他问卷相关路由
module.exports = router;