导读:本期聚焦于小伙伴创作的《如何使用Golang实现在线问卷系统收集用户答卷并统计》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用Golang实现在线问卷系统收集用户答卷并统计》有用,将其分享出去将是对创作者最好的鼓励。

在线问卷系统是常见的业务场景,使用Golang实现这类系统可以充分发挥其高并发、性能稳定的优势,完整流程包含问卷定义、答卷收集、结果统计三个核心环节。

如何使用Golang实现在线问卷系统收集用户答卷并统计

核心需求与表结构设计

首先需要明确系统的基础功能:支持创建问卷、用户提交答卷、后台查看统计结果。对应的数据库表可以设计如下:

问卷表 survey

字段名类型说明
idint主键自增
titlevarchar(200)问卷标题
question_listtext问题列表JSON,包含问题类型、选项等内容
create_timedatetime创建时间

答卷表 answer

字段名类型说明
idint主键自增
survey_idint关联问卷ID
answer_contenttext答卷内容JSON,对应问题ID和选择结果
submit_timedatetime提交时间

答卷收集接口实现

使用Golang的net/http标准库可以快速开发答卷提交接口,接收前端传递的答卷数据并存储到数据库。以下是核心实现代码:

package main

import (
	"database/sql"
	"encoding/json"
	"log"
	"net/http"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

// 初始化数据库连接
func initDB() {
	var err error
	db, err = sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/survey_db")
	if err != nil {
		log.Fatal("数据库连接失败:", err)
	}
	// 设置连接池参数
	db.SetMaxOpenConns(10)
	db.SetMaxIdleConns(5)
}

// 答卷提交请求结构体
type SubmitAnswerRequest struct {
	SurveyID     int    `json:"survey_id"`
	AnswerContent string `json:"answer_content"`
}

// 答卷提交接口处理函数
func submitAnswerHandler(w http.ResponseWriter, r *http.Request) {
	// 仅允许POST请求
	if r.Method != http.MethodPost {
		http.Error(w, "仅支持POST请求", http.StatusMethodNotAllowed)
		return
	}
	// 解析请求参数
	var req SubmitAnswerRequest
	err := json.NewDecoder(r.Body).Decode(&req)
	if err != nil {
		http.Error(w, "参数解析失败", http.StatusBadRequest)
		return
	}
	// 插入答卷数据
	insertSQL := "INSERT INTO answer (survey_id, answer_content, submit_time) VALUES (?, ?, ?)"
	_, err = db.Exec(insertSQL, req.SurveyID, req.AnswerContent, time.Now())
	if err != nil {
		log.Println("答卷插入失败:", err)
		http.Error(w, "提交失败", http.StatusInternalServerError)
		return
	}
	// 返回成功响应
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"code": 0,
		"msg":  "提交成功",
	})
}

func main() {
	initDB()
	defer db.Close()
	http.HandleFunc("/api/submit_answer", submitAnswerHandler)
	log.Println("服务启动在 :8080 端口")
	http.ListenAndServe(":8080", nil)
}

答卷统计逻辑实现

统计功能需要根据问卷的问题类型,对答卷内容做对应处理,比如单选题统计各选项选择人数,多选题统计每个选项的选择次数。以下是统计逻辑的示例代码:

// 统计结果结构体
type StatResult struct {
	QuestionID int                 `json:"question_id"`
	QuestionTitle string           `json:"question_title"`
	StatDetail  map[string]int     `json:"stat_detail"` // 选项ID:选择人数
}

// 统计答卷数据
func statSurveyAnswers(surveyID int) ([]StatResult, error) {
	// 查询问卷问题列表
	var questionListStr string
	err := db.QueryRow("SELECT question_list FROM survey WHERE id = ?", surveyID).Scan(&questionListStr)
	if err != nil {
		return nil, err
	}
	var questionList []map[string]interface{}
	json.Unmarshal([]byte(questionListStr), &questionList)

	// 查询所有答卷
	rows, err := db.Query("SELECT answer_content FROM answer WHERE survey_id = ?", surveyID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	// 初始化统计容器,key为问题ID,value为选项统计map
	statMap := make(map[int]map[string]int)
	for _, q := range questionList {
		qID := int(q["id"].(float64))
		statMap[qID] = make(map[string]int)
		// 初始化所有选项为0
		options := q["options"].([]interface{})
		for _, opt := range options {
			optInfo := opt.(map[string]interface{})
			optID := optInfo["id"].(string)
			statMap[qID][optID] = 0
		}
	}

	// 遍历答卷统计
	for rows.Next() {
		var answerContentStr string
		rows.Scan(&answerContentStr)
		var answerContent map[string]interface{}
		json.Unmarshal([]byte(answerContentStr), &answerContent)
		// 遍历答卷中的每个问题答案
		for qIDStr, ans := range answerContent {
			// 转换问题ID为int
			var qID int
			fmt.Sscanf(qIDStr, "%d", &qID)
			if stat, ok := statMap[qID]; ok {
				// 处理单选和多选
				switch ansVal := ans.(type) {
				case string:
					// 单选题,答案是选项ID字符串
					stat[ansVal]++
				case []interface{}:
					// 多选题,答案是选项ID数组
					for _, optID := range ansVal {
						stat[optID.(string)]++
					}
				}
			}
		}
	}

	// 组装返回结果
	var result []StatResult
	for _, q := range questionList {
		qID := int(q["id"].(float64))
		qTitle := q["title"].(string)
		result = append(result, StatResult{
			QuestionID:   qID,
			QuestionTitle: qTitle,
			StatDetail:   statMap[qID],
		})
	}
	return result, nil
}

注意事项

  • 实际开发中需要对请求参数做合法性校验,比如校验问卷ID是否存在、答卷内容是否符合问题要求
  • 如果问卷访问量较大,可以对统计结果做缓存,避免每次查询都遍历所有答卷
  • 存储答卷内容时建议使用JSON格式,方便扩展不同的问题类型,不需要频繁修改表结构

Golang在线问卷系统答卷收集数据统计修改时间:2026-07-13 14:24:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。