基于Node.js与Socket.io开发问卷应用的技术求助
Hey there! Let's walk through practical solutions for your survey app requirements—here's how to tackle each part:
For the frontend, you can dynamically render questions and their corresponding answer buttons using HTML/JavaScript (or a framework like React/Vue if you prefer). Here's a simple vanilla JS example:
First, the HTML structure for a question:
<div class="question-card"> <h4>Q1: Which frontend framework do you use most?</h4> <div class="answer-options"> <button class="answer-btn" data-qid="1" data-ans="React">React</button> <button class="answer-btn" data-qid="1" data-ans="Vue">Vue</button> <button class="answer-btn" data-qid="1" data-ans="Angular">Angular</button> </div> </div>
Then, add JavaScript to capture user selections and store answers:
const userAnswers = {}; const answerButtons = document.querySelectorAll('.answer-btn'); answerButtons.forEach(btn => { btn.addEventListener('click', () => { const questionId = btn.dataset.qid; const selectedAnswer = btn.dataset.ans; // Save the answer userAnswers[questionId] = selectedAnswer; // Visual feedback: highlight the selected button btn.parentElement.querySelectorAll('.answer-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); }); });
On the backend, store your questions in a database (e.g., a questions table with columns id, survey_id, content, options). When a user loads the survey, fetch the questions via an API endpoint and render them dynamically instead of hardcoding.
To find the user with the highest answer match, you'll need to:
- Store each user's answers in a database (e.g., a
user_answerstable withuser_id,question_id,answer). - Calculate a match score by comparing the current user's answers to every other user's answers.
Here's a Node.js/Express example of the matching logic:
async function getTopMatchingUser(currentUserId) { // Fetch all other users const otherUsers = await db.query('SELECT id FROM users WHERE id != ?', [currentUserId]); let topMatch = { userId: null, matchPercentage: 0 }; const currentUserAnswers = await db.query('SELECT question_id, answer FROM user_answers WHERE user_id = ?', [currentUserId]); // Convert current user's answers to an object for quick lookup const currentAnswersMap = currentUserAnswers.reduce((acc, ans) => { acc[ans.question_id] = ans.answer; return acc; }, {}); const totalQuestions = Object.keys(currentAnswersMap).length; for (const user of otherUsers) { const userAnswers = await db.query('SELECT question_id, answer FROM user_answers WHERE user_id = ?', [user.id]); let matchingAnswers = 0; userAnswers.forEach(ans => { if (currentAnswersMap[ans.question_id] === ans.answer) { matchingAnswers++; } }); const matchPercentage = Math.round((matchingAnswers / totalQuestions) * 100); if (matchPercentage > topMatch.matchPercentage) { topMatch = { userId: user.id, matchPercentage }; } } // Fetch the matched user's details to display const matchedUser = await db.query('SELECT username FROM users WHERE id = ?', [topMatch.userId]); return { ...topMatch, username: matchedUser[0]?.username }; }
Once you have the result, display it to the user like:
Your closest match is @jane_doe with a 90% answer match!
The key here is assigning a unique identifier to each survey instance and using it in the URL. Here's how to implement this:
- Generate a unique ID: Use a UUID (Universally Unique Identifier) for each new survey. Most backend languages have libraries for this (e.g.,
uuidin Node.js). - Store the UUID in your database: Add a
uuidcolumn to yoursurveystable. When creating a new survey, insert the generated UUID along with other details. - Set up a dynamic route: Use the UUID as a URL parameter to serve the correct survey.
Example with Express.js:
const { v4: uuidv4 } = require('uuid'); // Create a new survey and generate its unique URL app.post('/create-survey', async (req, res) => { const surveyUuid = uuidv4(); const { title } = req.body; await db.query('INSERT INTO surveys (uuid, title) VALUES (?, ?)', [surveyUuid, title]); // Return the unique URL to the creator res.json({ surveyUrl: `${req.protocol}://${req.get('host')}/survey/${surveyUuid}` }); }); // Route to serve the survey via its unique URL app.get('/survey/:surveyUuid', async (req, res) => { const { surveyUuid } = req.params; const survey = await db.query('SELECT * FROM surveys WHERE uuid = ?', [surveyUuid]); if (!survey.length) { return res.status(404).send('Survey not found'); } // Fetch the survey's questions and render the page const questions = await db.query('SELECT * FROM questions WHERE survey_id = ?', [survey[0].id]); res.render('survey-page', { survey, questions }); });
This way, each survey gets its own unique URL like https://yourapp.com/survey/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed that you can share with participants.
内容的提问来源于stack exchange,提问作者user9803322

