问卷调查管理系统_asp网络调查问卷系统源代码 web网上问卷程序 - CSDN
  • 问卷调查系统的设计与实现

    万次阅读 2020-06-05 20:25:46
    程序下载链接: https://download.csdn.net/download/qq_30615201/11223278 河北农业大学 本科毕业设计说明书 题 目: 问卷调查系统的设计与实现 学 院: ...

    程序下载链接:

    https://download.csdn.net/download/qq_30615201/11223278

    河北农业大学

     本科毕业设计说明书

     

     

     

          题    目:    问卷调查系统的设计与实现    

            学    院:                                                  

            专业班级:                                                  

            学    号:                                                  

            学生姓名:             崔胜利             

            指导教师姓名:                                                  

            指导教师职称:                                                  

     

     

       2019年  5 月 23 日

     

    摘要

    传统模式下,发起者需要提前制作问卷、试卷,统一作答,过后统一阅卷处理,不仅会消耗大量人力物力,还由于人工方式的局限性,常常存在各种不可避免的失误。由此可见,传统方式已经不能满足现代工作环境的需求。近年来,随着移动互联网浪潮中全面信息化的普及和发展,2018年中国移动端智能设备使用率达到68%远远高于PC端,移动互联的佼佼者莫过于微信,微信月活用户已经达到10亿,目前在国内市场依旧有着非常大的增长潜力。因此,整合现有的资源提供移动端基于微信小程序的在线问卷调查平台,解决新形势下传统模式的弊端,成为办公信息化和提高工作效率的必然选择。

    本文介绍了一个B/S结构下微信小程序的在线问卷调查系统,其后台可在主流浏览器上进行操作,前台采用微信小程序。它使用集成框架Spring+Sring MVC+MyBatis,存储数据库选用关系型数据库MySql,缓存数据库采用非关系型数据库Redis,服务器选用Apache Tomcat和Nginx相结合的方式。它的代码部分主要开发工具为IntelliJ IDEA和微信开发者工具。以图表的方式实现对问卷结果的数据分析。代码部分实现了前端问卷调查系统和后端管理系统的分离。采用Redis数据库做高速缓存提高访问效率。利用FFmpeg将MP4视频转为m3u8格式实现在线播放视频。

    关键词:微信小程序;问卷调查;在线投票;在线考试

     

     

    Abstract

    In the traditional mode, the initiator needs to make questionnaires and test papers in advance, and make a unified answer. After the unified review, it will not only consume a lot of manpower and material resources, but also due to the limitations of manual methods, there are often inevitable mistakes. It can be seen that the traditional way can no longer meet the needs of the modern working environment. In recent years, with the popularization and development of comprehensive information in the wave of mobile Internet, the use rate of smart devices in China's mobile terminals reached 68% in 2018, which is much higher than that of PCs. The leader of mobile internet is WeChat, WeChat monthly users have already It has reached 1 billion and currently has a very large growth potential in the domestic market. Therefore, integrating existing resources to provide mobile-based online questionnaire survey platform based on WeChat applet, to solve the drawbacks of the traditional model under the new situation, has become an inevitable choice for office informationization and work efficiency.

       This question introduces an online questionnaire survey system of WeChat applet under the B/S structure. The background can be operated on the mainstream browser, and the WeChat applet is used in the foreground. It uses the integration framework Spring+Sring MVC+MyBatis, the storage database uses the relational database MySql, the cache database uses the non-relational database Redis, and the server uses the combination of Apache Tomcat and Nginx. Its main part of the code development tools are IntelliJ IDEA and WeChat Developer Tools. Data analysis of the questionnaire results was carried out graphically. The code part realizes the separation of the front-end questionnaire system and the back-end management system. Using the Redis database for caching improves access efficiency. Use FFmpeg to convert MP4 video to m3u8 format to play video online.

    Keywords: WeChat applet; questionnaire survey; online voting; online exam.

     

    目录

    1绪论... 1

    1.1 项目背景及意义... 1

    1.2 国内外现状分析... 1

    1.3 基本目标和研究内容... 1

    1.4 论文内容组织安排... 1

    2可行性分析与需求分析... 3

    2.1 可行性分析... 3

    2.2 需求分析... 3

    2.2.1 功能性需求分析... 3

    2.2.2 非功能性需求分析... 4

    3系统设计... 5

    3.1系统架构... 5

    3.2 流程设计... 7

    3.3 数据库设计... 8

    4系统实现... 13

    4.1系统的开发与实施环境... 13

    4.2 核心技术简介... 13

    4.3 底层接口和类的封装... 14

    4.3.1公共类的实现... 14

    4.3.2关于ResultResponse统一接口参数的实现... 15

    4.3.3关于数据分页的实现... 15

    4.3.4关于自定义的验证方式和校验工具类的实现... 16

    4.3.5关于微信小程序端的js封装... 17

    4.4 前端系统的实现... 18

    4.4.1界面UI实现... 18

    4.4.2问卷添加页面... 18

    4.4.3问卷题型实现... 19

    4.4.4投票页面实现... 19

    4.4.5数据分析的实现... 20

    4.4.6其他部分效果实现... 21

    4.5 后端管理的实现... 22

    4.5.1用户登录的实现... 22

    4.5.2资源管理的实现... 22

    4.5.3验证方式的实现... 23

    结束语... 24

    参考文献... 25

    致谢... 26

     

     

     

     

     

     

    1绪论

    1.1 项目背景及意义

    随着用户对全方位多维度海量数据的需求日益增长,问卷调查作为获得数据的重要途径,在很多领域的运用已经十分广泛。反观传统问卷调查,地域限制、灵活性限制、人工失误这些不可避免的缺陷,使得用户需求与传统问卷的矛盾日益凸显。在校园里,存在各种信息统计,经常会有各种各样的问卷表单,师生需要在此消耗极大的精力和时间。随着我国移动互联技术的浪潮,智能设备用户的增长,给问卷调查带来全新的改革方案,那就是在线问卷调查。在线问卷成本低、时效性强、跨地域、表现形式丰富、覆盖范围广,可极大程度上减少人力资源的使用,满足了用户基本需求。微信小程序的问卷调查系统有很强的实用性。

    1.2 国内外现状分析

    问卷调查系统在国外起步较早例如:SurveySavvy于2009年推出,是一款易于使用的桌版问卷调查工具。SurveySavvy的SavvyConnect提供触手可及的调查。此外,SurveySavvy的VIP计划使用安全,先进的技术在用户上网时收集数据。SurveySavvy的用户在网上冲浪并获得额外的付费研究机会时获得现金奖励[1]。

    目前随着我国网络环境的发展和完善,在线问卷调查系统带来的便利开始崭露头角,大有可能取代传统的问卷调查模式的趋势。目前在线问卷调查平台正在从小型化逐渐转向全方面多维度的高信息化。近年来国内出现了一大批问卷星,腾讯问卷,调查派等等优秀的在线问卷调查平台。他们都具有良好的的跨平台性支持PC、移动WEB、微信小程序三种平台。以为问卷星为例,它支持丰富的题型高达32种,不仅实现了调查问卷的制作和发布更是对收集到的数据加以分析利用,数据统计结果以环状图、饼状图、柱状图等可读性较强的图表形式展示给用户,在方便用户对结果数据分析的同时降低对用户软件操作和数据分析能力的要求。

    1.3 基本目标和研究内容

    本课题意在为问卷、投票活动发起者提供移动端基于微信小程序的在线问卷调查系统,让被调查用户能够快速便捷的完成问卷调查。问卷调查结束自动统计整理分析问卷结果数据,反馈给发起者结果报表,以图表的形式实现对结果的数据分析。以此为目标研究内容如下:考察市场现有的在线问卷调查系统,明确系统范围确定模块边界。具体开发实施完成系统数据库、业务逻辑、后台管理页面、前台小程序页面的实现。进行系统测试与BUG调试后发布项目,根据用户反馈优化功能。

    1.4 论文内容组织安排

    本论文按照软件开发过程逐章编写,本文共分为四个章节:

    第一章绪论。本章主要描述了项目背景及意义,国内现状分析以及目标和研究内容。

    第二章可行性分析与需求分析。本章从经济、技术两个角度进行可行性分析,从软件都有哪些用户分别需要什么功能进行功能性需求分析,从软件的性能需求、UI设计、平台兼容性方面分析了非功能性需求。

    第三章系统设计。本章先论述了系统综合架构,然后画出了软件流程图,模块划分图,最后进行数据库设计。

    第四章系统实现。本章先阐述开发和实施环境和所涉及到的技术,然后到具体功能代码的实现,最后介绍前台UI实现和后台功能实现。

     

     

    2可行性分析与需求分析

    2.1 可行性分析

    软件开发可行性的分析主要从:经济可行性、技术可行性、操作可行性、社会可行性、组织可行性等方面进行分析,本节将从经济、技术方面进行可行性分析,为后期设计、开发、维护工作提供可行性理论依据。

    (1)经济可行性:从经济效益来分析,软件的开发的持续投入较低。系统服务器采用Apache Tomcat及Nginx[2],数据库采用MySql[3]及Redis[4]。这些软件也都是绿色开源软件,不需要支付额外费用。软件运行对服务器硬件资源的要求较低。系统所带来的的经济效益远超过它的开发成本,所以具有经济可行性。

    (2)技术可行性:技术层面腾讯提供微信小程序的开发工具和官方文档、Java基于SSM框架的系统技术也比较成熟且有丰富的资料可供参考、百度提供用于数据分析的工具EChart[5]并提供技术支持和官方API文档说明。且本人在此之前已经参与实现过数个基于微信的小程序参与实现数个SSM框架系统,有充分的开发经验。

    2.2 需求分析

    2.2.1 功能性需求分析

    为实现本系统目标,系统应具有前台页面和后台页面两大部分。后台需要具备管理和维护系统、用户权限分配管理功能的管理员称之为超级管理员,由超级管理员创建并指定权限的管理管理员称为活动管理员。前台需要实现发起问卷、发起投票、数据分析、答卷和投票的功能,前台用户均采用微信用户信息,用户在发起问卷、发起投票、数据分析时被称为活动发起者,在投票或答卷是被称为被调查者。

    后台用户分为活动管理员和超级管理员两种角色。超级管理员拥有后端的全部权限负责维护和管理系统,超级管理员有角色管理的权限可以管理其他管理员。活动管理员负责处理违规被举报的活动,活动管理员的权限由超级管理员指定和分配。

    (1)超级管理员功能需求

    1后台权限控制

    管理后台用户,管理后台角色,可为用户分配多种角色,每个角色可以拥有多个菜单权限,一个菜单可以被多个角色使用。

    2系统设置

    具备对系统名称的管理,系统服务邮箱的配置,系统介绍视频的编辑。

    3前台权限管理

    配置前台用户的访问权限,管理前台角色。

    前台用户分为调查活动发起者和活动被调查者。活动发起者发布和管理个人的调查问卷和投票、被调查者参与投票问卷活动发表评论。

    (2)活动管理员功能需求:

    1投票管理、问卷管理

    实现管理员对用户发起的问卷调查的控制,处理用户投诉举报。

    (1)被调查者功能需求:

    1活动大厅

    展示公开的投票活动,展示公开的问卷活动以供用户投票作答。

    2个人中心

    设置投票浏览历史、问卷浏览历史、我参与的投票、我参与的问卷。

    3问卷部分

    问卷作答页面。

    4投票部分

    查询投票详情、为候选项进行拉票评论、投票页面。

    5综合部分

    用户权限不足时跳转到未授权界面,提供分享界面和活动海报便于用户在多渠道宣传、观看问卷调查系统的介绍视频 。

    (2)活动发起者功能需求:

    1个人中心

    设置我发起的投票、我发起的问卷。

    2问卷部分

    复制问卷模板、提供草稿保存、添加问卷、管理问卷题目、问卷预览、编辑问卷、暂停问卷、统计问卷、查询问卷详情、通过图表的形式查看问卷数据分析、提供自动发送问卷统计结果的选择。

    3投票部分

    添加投票、提供草稿保存、管理投票候选项、报名成为候选项、编辑投票、暂停投票、统计投票、通过图表的形式查看问卷数据分析、投票页面。

    2.2.2 非功能性需求分析

    (1)安全性需求:数据库数据定时备份、不同用户访问权限控制、密码加密、使用Https协议提供数据传输的安全,使用恰当的安全策略在满足基本信息安全的情况下,最大程度上提高用户舒适度,做到预防Ddos攻击和防止sql注入式攻击[6]。

    (2)稳定性需求:系统本身具备可移植能力适应多种环境,满足Windows 或Linux两种系统,提供并发处理措施配置服务器集群,常用的不经常变化的数据放入缓存数据库提高访问效率。

    (3)界面需求:用户界面友好美观,提供丰富的提示提高交互性,方便使用,可操作性强,页面加载跳转等提供加载动画,常见异常错误界面美化。

    (4)兼容性需求:本系统中考虑到用户群体的广泛性,其使用的设备有很大差异:设备操作系统差异,主要要兼容IOS、Android两大平台、屏幕尺寸差异,要实现移动端的响应式布局[7]。

     

     

    3系统设计

    3.1系统架构

    后台用户通过浏览器访问进行后台管理,前台用户通过微信小程序进行操作,使用MySql作为主数据库,为提高访问效率采用Redis作为缓存服务器。

    MVC设计模式是Model(实体)、View(视图层)、Controller(控制层)的简称,是一种软件设计中经典的设计模式。在该系统实现基于该思想改进控制层将其分为Controller(页面跳转控制层)和Servive(逻辑控制层)Dao(数据库操作层),使用json数据通讯达到前后分离的效果[8]。

    系统架构图如图3.1所示。

    图3.1  系统框架图

    问卷调查系统包括四个子系统。每个子系统又进行了模块划分为日后的开发和维护提供方便。子系统分为Basics基础子系统、Manage权限子系统、Wx微信服务子系统、Wenjuan调查子系统:

    1. Basics基础子系统

    该子系统主要负责基础模块的集合例如数据校验模块负责数据的处理和验证、文件管理模块负责系统文件资源的上传和下载功能有文件管理的功能、基础模块封装底层实现类和接口供其他模块调用和继承。

    1. Manage权限子系统

    该子系统主要负责用户权限管理功能的实现,有资源管理、角色管理、用户管理以及为角色分配资源为用户分配角色的功能。子系统内部实现了Shiro框架下实现权限认证管理,前台部分基于Url的权限访问控制,后台采用基于Url加标签的权限控制。

    1. Wx微信服务子系统

    该子系统主要负责与微信的数据交互功能。在前端部分它实现了获取微信用户的OpenId和微信用户登录及获取微信用户详细信息的功能,在后端它通过定时任务框架Quartz实现了每1.5小时一次向微信服务器获取小程序accessToken的功能,以确保与其他微信接口之间的通讯顺畅。

    1. Wenjuan调查子系统

    该子系统主要实现了投票管理、问卷管理、数据分析的功能是该系统的核心业务子系统。该子系统的功能主要在微信小程序端实现,它采用百度ECharts做数据分析为用户提供良好数据展示效果。

    问卷调查系统系统模块划分图如图3.2所示。

    图3.2  系统模块划分图

    3.2 流程设计

    后台采用多用户多角色多资源的关系设计,用户和角色为多对多关系,角色和资源为多对多关系,实体表与实体表之间采用存储id方式的弱关联。前台用户分为用户和微信用户,其关系为一对一关系[3]。

    前台用户登录流程图如图3.3所示。

    图3.3  前台用户登录流程图

    后台用户登录流程图如图3.4所示。

    图3.4  后台用户登录流程图

    3.3 数据库设计

    问卷调查系统下属的四个子系统总使用数据表27个,各表名称及功能如表3.1所示。

    表3.1系统数据库列表

    表名称

    说明

    basics_file

    文件索引表,用于保存前台的图片信息

    manage_api

    后台页面Api接口表,用于权限系统中url的允许

    manage_environment

    系统环境配置表,保存系统名称,邮件服务,系统介绍视频

    manage_frontlink

    前台链接表,存储前台需角色方能访问的用户资源权限url

    manage_frontrole

    前台用户角色表,记录前台用户角色分配

    manage_link_role

    前台链接角色关系表,存储角色和前台url的多对多关系

    manage_resource

    后台按钮资源表,保存后台用户的按钮资源

    manage_resource_role

    后台按钮资源角色关系表,存储后台角色和按钮资源的多对多关系

    manage_role

    后台用户角色表,用于后台用户角色的管理[9]

    manage_subscriber

    前台用户表,用于记录前台用户信息

    manage_subscriber_role

    前台用户角色关系表,存储前台用户和前台角色的多对多关系

    续表3.1

    manage_user

    后台用户表,后台管理员信息表

    manage_user_role

    后台用户角色关系表,存储后台管理员与后台角色的多对多关系

    wj_candidate

    投票候选项表,保存投票活动的候选项

    wj_check

    填空验证规则表,记录问卷填空题题型的内容验证规则

    wj_choice

    选择题选项表,存储问卷中选择题的选项内容

    wj_comment

    评论信息表,存储系统中评论及评论关系表

    wj_commentrecord

    评论点赞记录表,记录用户对评论的点赞,拍砖

    wj_problem

    问卷问题表,保存问卷调查的问卷的问题

    wj_question

    问卷调查表,保存问卷调查活动信息

    wj_vote

    投票表,存储投票活动信息

    wj_voterecord

    投票记录表,记录用户对投票候选项的投票记录

    wx_param

    微信参数表,配置微信的参数,用于与微信开方接口通讯

    wj_answer

    用户答题答案表,存储用户对每道题的答案

    wj_reply

    用户问卷表,记录存储用户参加作答的问卷

    wj_footprint

    足迹表,用于记录用户的访问浏览记录

    wx_user

    微信用户表,存储从微信接口获取到的用户信息

    以下主要介绍5个核心表。

    (1)文件索引表basics_file,为用户上传的文件或图片提供数据索引方便使用和查找详情如表3.2所示。

    表3.2 文件索引表basics_file

    字段

    数据类型

    长度

    是否为空

    主键

    说明

    id   

    bigint

    20

    自增长字段

    createTime

    timestamp

     

    创建时间

    state

    int

    2

    状态

    realName

    varchar

    1024

    文件真实名称

    uniName

    varchar

    1024

    唯一名称

    filePath

    varchar

    1024

    文件路径

    fileType

    varchar

    32

    文件类型

    imgFlag

    int

    2

    是否是图片

    surface

    varchar

    64

    数据库表名

    nature

    varchar

    64

    字段名称

    surfaceId

    bigint

    20

    数据库表信息Id

    (2)评论信息表wj_comment,属于Wenjuan调查子系统用户存储用户评论详情如表3.3所示。

     

    表3.3 评论信息表wj_comment

    字段

    数据类型

    长度

    是否为空

    主键

    说明

    id   

    bigint

    20

    自增长字段

    createTime

    timestamp

     

    创建时间

    state

    int

    2

    状态

    comment

    varchar

    2048

    评论内容

    useless

    bigint

    8

    拍砖 数量

    fabulous

    bigint

    8

    点赞 数量

    subscriberId

    bigint

    20

    主人表 id

    subscriberSurface

    varchar

    64

    主人表 名称

    subscriberNature

    varchar

    64

    主人表 文字信息段

    surface

    varchar

    64

    被评论表 表名

    nature

    varchar

    64

    被评论表 字段名

    surfaceId

    bigint

    20

    被评论标 id

    costSurface

    varchar

    64

    代价表 表名

    costNature

    varchar

    64

    代价表 字段名称

    costSurfaceId

    bigint

    20

    代价表 id

    (3)投票表wj_vote,属于Wenjuan调查子系统,记录投票活动内容的38个字段详情如表3.4所示。

    表3.4投票表wj_vote

    字段

    数据类型

    长度

    是否为空

    主键

    说明

    id   

    bigint

    20

    自增长字段

    createTime

    timestamp

     

    创建时间

    state

    int

    2

    状态

    Name

    varchar

    64

    投票活动名称

    Cover

    varchar

    512

    活动封面图片id列表

    introduce

    varchar

    2048

    投票活动介绍

    imgIntroduce

    varchar

    512

    活动介绍图片id列表

    themeColor

    varchar

    10

    活动1600万主题色

    repeatFlag

    int

    2

    是否重复多日投票

    frequency

    int

    3

    每日投票次数

    restrictFlag

    int

    2

    是否限制IP和地区

    province

    varchar

    64

    限制地区省份

    City

    varchar

    64

    限制地区城市

    district

    varchar

    64

    限制地区区县

    ipWxUserFrequency

    int

    3

    每个IP允许的用户数

    overt

    int

    2

    是否公开投票

    comment

    int

    2

    是否开启评论

    续表3.4

    Outside

    int

    2

    是否公开报名

    sponsor

    int

    2

    是否显示主办方

    sponsorName

    varchar

    48

    主办方名称

    sponsorPhone

    varchar

    16

    主办方电话

    reward

    int

    2

    设置奖励

    rewardDesc

    varchar

    2048

    奖励说明

    rewarImg

    varchar

    512

    奖励图片  id列表

    startTime

    timestamp

     

    开始时间

    endTime

    timestamp

     

    结束时间

    voteType

    int

    2

    1文字2 图片3 图文

    unusual

    int

    2

    管理标志

    unusualEplain

    varchar

    256

    异常原因

    reportEplain

    varchar

    256

    举报信息

    rWxUserId

    bigint

    20

    举报人 id

    wxUserId

    bigint

    20

    发起人id

    candidateNum

    int

    3

    候选数量

    candidateIndex

    int

    3

    候选项序号

    supNum

    int

    20

    投票活动总票数

    voteDataStr

    text

     

    投票活动Json字符串

    voteCode

    varchar

    16

    投票活动密码

    suspend

    int

    2

    是否暂停

    (4)候选项表wj_candidate,用于保存投票活动的各个候选项详情如表3.5所示。

    表3.5候选项表wj_candidate

    字段

    数据类型

    长度

    是否为空

    主键

    说明

    id   

    bigint

    20

    自增长字段

    createTime

    timestamp

     

    创建时间

    state

    int

    2

    状态

    orderNum

    int

    5

    排序号候选项选手号

    cover

    varchar

    512

    活动封面图片id列表

    introduce

    varchar

    1024

    候选项介绍

    imgIntroduce

    varchar

    512

    选项介绍图片id列表

    name

    varchar

    64

    候选项名称

    supNum

    int

    20

    选项票数

    useFlag

    int

    2

    拒绝,审核中,通过

    voteId

    bigint

    20

    投票活动id

    voteType

    int

    3

    投票类型

    wxUserId

    bigint

    20

    报名人微信用户id

     

    续表3.5

    comment

    varchar

    3

    评论数量

    (5)问题表wj_problem,用于记录问卷中各个题目详情如表3.6所示。

    表3.6 问题表wj_problem

    字段

    数据类型

    长度

    是否为空

    主键

    说明

    id   

    bigint

    20

    自增长字段

    createTime

    timestamp

     

    创建时间

    state

    int

    2

    状态

    name

    varchar

    256

    问题问题表

    questionId

    bigint

    20

    所属问卷id

    orderNum

    int

    5

    题号

    qType

    varchar

    26

    问题类型

    cover

    varchar

    1024

    题目封面id列表

    must

    int

    2

    是否必须作答

    choicesNunber

    int

    4

    选择题选项数量

    answerNumber

    int

    4

    选择题答案数量

    lineNumber

    int

    2

    简答题文本框行数

    checkType

    varchar

    32

    填空检查类型

    checkId

    bigint

    20

    填空检查id

    maxFen

    int

    2

    评分题最高分

    score

    int

    3

    本题分数

    genre

    int

    2

    类型

    wxUserId

    bigint

    20

    所属用户id

    examineFlag

    int

    2

    是否考试题目

     

     

     

    4系统实现

    4.1系统的开发与实施环境

    系统的开发环境如下:

    (1)技术平台: J2EE[10]

    (2)开发软件:IntelliJ IDEA 、微信开发者工具

    (3)开发语言:Java[11]、Jsp、微信小程序

    (4)web服务器:Tomcat 7

    (5)数据库:MySql 5.5、Redis 3.2

    (6)版本控制:Tortoise SVN

    (7)Jar包管理:Maven 3.5

    (8)操作系统:Windows 10 专业版

    实施环境:

    (1)数据库:MySql 5.5、Redis 3.2

    (2)web服务器:Tomcat 7 、Nginx[12]

    (3)操作系统:Windows Server 2012

    4.2 核心技术简介

    本系统所涉及的技术如表4.1所示。

    表4.1核心技术

    技术名称

    说明

    Apache Shiro

    用于做权限控制的轻量级框架,在本系统中采用基于url和基于标签的控制方式[13]

    MyBatis

    是一款持久层框架,用于操作数据库

    Spring MVC

    属SpringFrameWor的子产品,将Web层进行职责分层帮助开发者敏捷开发。

    Spring

    开源的实现IOC容器和AOP的耦合性轻量级框架[14]

    Apache POI

    操作Microsoft Office文件的开源库,用于为excel文件的生成和读取等操作

    Quartz

    由java编写的开源作业调度框架,Wx微信服务子系统以每1.5小时频率向微信请求accessToken

    Common Email

    是对java自带的mail模块的封装,轻松的实现不同类型邮件发送,为用户发送报表[15]

    Apache Log4j

    一个强有力的日志操作包,用于系统日志的记录

    Google zxing

    谷歌发布的用来识别多种格式条形码的开源项目

    FFmpeg

    用来操作音频、视频的开源计算机程序,用于将上传后的MP4视频转化为m3u8格式

    JQuery

    是一个 JavaScript 库,封装了大量js原生代码方便开发者使用

    Layer

    一个基于JQuery的弹出层插件,可自定义页面,提示消息,对话框

    Ajaxfileupload

    是异步文件上传插件,项目已停止维护,为兼容JQuery版本在项目用有修改部分源码

    JQuery Validate

    一款文本数据验证的插件,方便在前端校验数据减少服务器负荷

    Ztree

    是一款轻量级的树结构框架,用于按钮菜单树的操作和实现树型显示数据

    H-ui

    轻量级前端框架,简单免费,兼容性好,用于做后台管理页面的布局设计

    续表4.1

    ECharts

    百度推出的一款数据分析与数据可视化插件,用于数据分析和报表

    BMap

    百度地图推出的小程序端的地图插件,用于定位用户信息,分析用户特征

    4.3 底层接口和类的封装

    4.3.1公共类的实现

    在本系统中改进MVC的三层架构将控制层细分为页面跳转控制层、逻辑控制层、数据操作层。对于在数据操作层对数据库的操作,逻辑控制层中增、删、改、查、检验实体对象的逻辑中常用的业务需求是很多的每个实体类的操作十分雷同。于是为方便起见,我们对各个实体类对数据库的访问操作做了进一步的提取。利用java中提供的泛型和继承得出BasicsAdminMapper数据访问层公共类,各个实体dao操作类均继承该公共类,以提高代码的复用性。基于泛型和反射的知识,对逻辑控制层做提取得到BasicsService逻辑控制层公共类。

    BasicsService公共类实现如表4.2所示。

    表4.2 BasicsService公共类实现

    方法名称

    说明

    getBasicsAdminMapper()

    抽象方法钩子函数,子类中实现让父类也可以使用子类的属性

    addSave(E pojo)

    添加实方法,方法中调用验证方法通过后会自定设置状态插入数据库

    editSave(E pojo)

    抽象方法由子类实现

    delete(Long id)

    对象的逻辑删除,修改状态字段state的值为0表示停用,提供了id为String类型的重载

    deleteByPrimaryKey(Long id)

    对象的物理删除,直接从数据库中删除,提供了id为String类型的重载

    selectByPrimaryKey(Long id)

    根据id查找对象并返回,提供了id为String类型的重载

    listByAttribute(String attribute, String checkVal)

    根据属性查找 只找 状态为启用的 state=1

    istByAttrValueMap(Map<String,String>attrValue, int state)

    传递一个字段、值Map,状态生成需要查询的sql语句并执行返回结果列表

    listByAttrValueMap(Map<String,String> attrValue)

    传递一个字段、值Map,默认状态为1成需要查询的sql语句

    listByAttributeResponse(String attribute)

    根据属性查找 只找 状态为启用的 state=1,返回值ResultResponse在后边介绍

    listJson(TableUploadUtil tableUploadUtil)

    根据分页条件计算页数,查询当前页内容列表,返回值TableReturnUtil在后详细介绍

    loadCheckAttributeIsExistence(String attribute, String checkVal, Long checkId)

    用于对象某字段的字段值已存在的判断,checkId为0存在即为存在,checkId为当前实体对象id会判断存在的值是否是本身的

    续表4.2

    checkInfo(E pojo)

    在将对象持久化入数据库之前,做对象实体的属性验证功能,用到自定义的多种验证规则后边详述

    BasicsAdminMapper公共类实现由表4.3所示。

    表4.3 BasicsAdminMapper公共类实现

    方法名称

    说明

    insert(T record)

    用于实体T的添加,其中采用主键返回策略将自动id返回给

    updateByPrimaryKey(T record)

    实体类T的更新工作,更新主键id为关键不能改变

    deleteByPrimaryKey(Long id)

    实体类T的删除,这个方法是实体类的物理删除方法

    selectByPrimaryKey(Long id)

    实体类T根据id的查询,返回一个T的一个实体对象使用频率极高

    listByAttribute(String attribute, String checkVal, Integer state)

    利用MyBatis中$和#两种符号的功能差异实现,可以用来查询指定字段、指定字段值的实体列表

    listByAttrValueMap( String attrValueMap, Integer state)

    原理与listByAttribute方法相同,这可以查询多个指定字段的指定值,使用时切忌数据库表中要存在这些字段

    getCount(TableUploadUtil tableUploadUtil)

    根据分页信息查询返回所有复合条数的数据数量,用于统一的数据列表分页,TableUploadUtil类会在后边详细叙述

    listPageObjs(TableUploadUtil tableUploadUtil)

    根据条件查询分页中当前页的数据,返回实体类T的对象列表

    4.3.2关于ResultResponse统一接口参数的实现

    系统采用前后分离的方式,最有效的实现方式就是通过权限token和json数据通讯,采用接口的方式,常存在不同接口间返回值的差异带来的不必要麻烦,为此系统中统一设计接口返回值达到接口返回值的一致性规范性,为使用提供便利。

    ResultResponse统一接口如表4.4所示。

    表4.4 ResultResponse统一接口

    字段名称

    说明

    String resultMsg

    返回信息提示用于对话框提示用户

    String resultCode

    结果码:200操作正常400返回操作异常401权限不足

    Object data

    成功后存放用户请求的数据

    4.3.3关于数据分页的实现

    系统中分页的实现主要有两种方式:方法一,页面一次将全部数据请求到页面缓存,用前台分页插件做分页,显示当前页的内容;方法二,采用数据库分页技术,每次请求得到符合条件的数量和当前页应显示的数据信息。方法一请求次数少但大量数据可能存在浪费过剩还有带来带宽占用过大的问题,方法二虽然请求次数高于方法一但每一条数据都是用户选择的,没有数据过剩的情况,大大降低带宽的占用提高访问速度。综上所述结合本项目的海量数据问题我们选择第二种实现方式。前端使用jquery.dataTables插件做分页的页面渲染,后端我们设计了适用于该插件的分页请求参数类TableUploadUtil和分页结果返回类TableReturnUtil。

    分页请求类如表4.5所示。

    表4.5 TableUploadUtil分页请求参数类

    字段名称

    说明

    int start

    开始记录数

    int draw

    前台传过来的要请求的页数

    int length

    每页记录数,分页大小默认为10

    String searchdetail

    搜索条件值

    String searchdeAttribute

    搜索条件属性

    String sql

    附加搜索sql

    分页结果返回类如表4.6所示。

    表4.6 TableReturnUtil分页结果返回类

    字段名称

    说明

    long pageLength

    分页大小默认为10,用于微信小程序分页

    int draw

    当前页数

    long length

    每页记录数,分页大小默认为10

    long pageNum

    符合条件的总页数,用于微信小程序分页

    long recordsTotal

    符合条件的信息总条数

    Object data

    当前页数据信息

    4.3.4关于自定义的验证方式和校验工具类的实现

    在项目中大多数需要用到数据验证,确保数据库的安全防止sql注入攻击和规范用户输入信息,数据校验多采用两种实现思路:一、前端的数据校验,可以有效减少后端验证带来的带宽占用问题减少对后端接口的请求,但是不能拦截技术人员绕过前言验证的攻击;二、在后端中做数据校验可以有效解决数据安全性问题。在本系统中采用二者结合的方式前端验证作为验证的第一道防线减少对后端的请求,用后端验证作为数据安全和数据规范保证数据完整性的最后一道屏障。前端验证使用jquery-validation插件。后端验证定义了运行时的CheckAnnotation,该类包括:type()方法默认值为“required”用于确定验证类型、message()方法返回验证失败的提示信息、attribute()方法确定要验证的数实体属性。在CheckAnnotationUtil类中存有验证类型与数据校验类的方法名称,通过反射的方式动态执行验证方法。系统实现了RegexUtil类作为数据校验的工具类。以此实现验证规则通过在实体类属性上加一个CheckAnnotation的简单方式实现多种多样的数据校验。RegexUtil数据校验类表如表4.7所示。

     

    表4.7 RegexUtil数据校验类

    字段名称

    说明

    htmlFilter(String inputString)

    过滤html代码

    isContainsSpecialChar(String text)

    是否包含中英文特殊字符,除英文"-_"字符外

    isChineseChar(String text)

    判断中文字符(包括汉字和符号)

    isEnglish(String text)

    判断英文字符(a-zA-Z)

    isZipCode(String text)

    邮政编码验证

    isIdCardNo(String text)

    第二代身份证号码验证

    isMobile(String text)

    手机号码验证

    isPhone(String text)

    电话号码验证

    isNumeric(String str)

    验证手机号或电话号码

    isDigits(String str)

    只能输入数字

    isEmail(String str)

    匹配Email地址验证

    4.3.5关于微信小程序端的js封装

    微信小程序在2016年内测,正式发布于2017年,相比于其他 技术平台起步较晚,但是借助腾讯公司的超大用户基数,势头迅猛发展迅速。微信小程序支持JavaScript的ES6标准,web上的js插件经过简单修改,即可在微信小程序上使用。为统一开发本系统封装了:dateTimePicker.js用于为时间picker提供最高年月日时分秒6级的时间选择数据;redis.js用于统一管理操作微信小程序缓存;bmapLocation.js结合百度官方bmap接口类实现对用户的定位和位置服务;dialog.js用户消息提示和弹出式对话框的操作;urls.js配置微信小程序用于和后端服务接口地址;util.js提供常用的操作如访问服务器api、时间字符串操作等等;

    Dialog对话框如表4.8所示。

    表4.8 dialog.js对话框的方法

    方法名称

    说明

    warnModalBack(title, content, callback)

    带确认按钮的对话框,其中callback为回调函数

    warnModal(title, content)

    带确认按钮的提示框

    warnModalError(content)

    带确认按钮的错误提示框

    warnModalSuccess(content)

    带确认按钮的成功提示框

    warnModalTrueBack(title, content, callback)

    带“是”“否”按钮的询问框,callback为回调函数

    showToastAutoError(title)

    带错误图片自动消失的提示框

    showToastAutoSuccess(title)

    带成功图片自动消失的提示框

    showToastSuccess(title)

    微信原装的成功提示框

    showToastLoading(title)

    微信原装的加载动画对话框

    4.4 前端系统的实现

    4.4.1界面UI实现

    为能给用户提供一套简洁大气UI,本系统规定:

    (1)不同页面统一字体大小为30rpx。

    (2)Icon主题颜色色值为# 1296DB、大小为32rpx。

    (3)页面统一背景颜色为#F3F3F3。

    (4)页面标题颜色色值#FFF、页面标题背景颜色色值#336799。

    (5)核心按钮均采用#1262DB至#12CADB的椭圆动态背景渐变色。

    4.4.2问卷添加页面

    问卷添加页面以选项卡效果呈现。页面分为活动内容、问卷设置、题目项三部分。利用上一步下一步按钮进行切换,每次下一步被触发时将会触发隐藏任务保存草稿,当用户中途退出程序后再次进入时询问用户是否使用草稿。

    问卷添加页面界面效果如图4.1所示。

    图4.1  问卷添加页面

    (1)活动部分包括设置问卷封面(必须上传)、问卷名称(1到20个字之间)、问卷介绍(不能为空)、问卷图片介绍(任意张)

    (2)问卷设置部分包括设置主题颜色(默认#000000)的弹出式拾色器、问卷开始时间和结束时间、设置地区和IP限制的开关、省市区三级联动选择器(默认北京市-北京-东城区)、数字按钮组的同IP微信用户数量(默认为1)、提供是否公开是否可以评论是否显示主办方的开关,主办方名称(在开启显示主办方的开关时不能为空),主办方电话(在开启显示主办方的开关时必须为手机号)

    (3)题目项部分包括设置是否试卷类型的开关(默认为关)、添加题目的按钮(试卷模式下只能添加单选题和多选题)、点击可选中某题目将显示该题的编辑复制上移下移删除按钮、提供预览功能为方便用户操作、发布问卷后清除草稿询问用户是否跳转到问卷答题页面是则跳转否则后退回个人中心。

    4.4.3问卷题型实现

    问卷提供单选题、多选题、填空题、简答题、评分题、定位题、位置题、文件题、图片题九种题型可供用户选择进而设计具有强大功能的问卷。

    (1)单选题界面提供题目图片的上传、选项图片的上传、可以选择被调查者是否必须作答、单选题选项数量不能低于2个、在选择问卷模式为试卷后必须设置其中一个为正确答案。

    (2)多选题提供题目选项的图片上传、选择是否必须作答、选项数量不能低于两个、在选择问卷模式为试卷后必须至少设置其中两个为正确答案。

    (3)填空题可上传题目图片、设置是否必须作答、可在手机号、邮箱、二代身份证号等选择一种验证方式限制被调查者输入信息。

    (4)简答题提供题目的图片上传、选择是否必答、选择显示时多行文本的行数。

    (5)评分题可设置题目图片、在2-10之间选择设置最高分、选择被调查者是否必须作答。

    (6)定位题、位置题、文件题、图片题这四种题型默认为必答题。

    问卷各类型问题界面效果如图4.2所示

    图4.2  问卷各类型问题

    4.4.4投票页面实现

    投票的添加部分与问卷的添加页面雷同,不再赘述。投票详情页面部分主要包括详情页面、活动详情页面、候选选投票页面、选项报名页面、候选项管理页面。

    详情页面需要根据发起者设置是否开启评论进而选择是否显示评论点赞部分,候选项显示主要有根据选手号显示和根据排行榜显示,排行榜显示时前三名分别采用金银铜三个icon其余选手则为排名名次。根据投票类型的不同,选手号列表显示效果不同,文字类投票会采用文字瀑布流的形式显示,图片和图文类型均采用图片显示。

    投票UI设计 具体界面如图所示。

    图4.3  投票UI设计

    4.4.5数据分析的实现

    在完成问卷活动结束后对数据分析处理是一个重要的功能。本系统提供五种类型的图表:仪表盘用于时间进度图显示活动进度、折线图根据活动时间长短显示各时段用户答卷数分布、饼状图用于对单选题的选择数量分析、柱状图显示多选题个选项的选择率、地图用于定位用户具体位置。具体页面如下图4.4和图4.5所示。

    图4.4  数据分析页面1

    图4.5  数据分析页面2

    4.4.6其他部分效果实现

    在用户权限不足时会自动跳转到401权限不足页面,提醒用户到登录界面切换账号登录。本系统提供介绍视频供用户学习使用本系统,在视频介绍页面即可查看。由于微信小程序不能直接播放m3u8格式的视频,介绍页面采用web-view标签将服务器视频播放页面导入的方法实现。

    部分在其他效果如图4.6所示。

    图4.6  其他部分页面

    4.5 后端管理的实现

    4.5.1用户登录的实现

    后台管理利用Shiro框架采用Url加标签级的权限控制方式利用Redis数据库做用户权限的高速缓存,用户全部权限存储Redis中有效期为10分钟,Key的生成规则如下:"session_"+LoginType.ADMIN.toString()+"_"+us.getUserName()+"_"+us.getUserPassword()。LoginType.ADMIN.toString()为用户的登录类型、us.getUserName()为用户名称、us.getUserPassword()为用户密码。当用户权限不足或session过期时自动跳转到登录页面,当Key权限过期时自动加载刷新当前用户的权限放入Redis缓存。登录后跳转到后台主页默认加载欢迎页面。

    登录页面下图4.7所示。

    图4.7  登录页面

    4.5.2资源管理的实现

    本系统按钮资源、角色、用户之间为多对多对多关系两两之间采用关联表进行关联。可任意创建角色分配资源也可以创建用户分配角色超级管理员角色拥有全部权限。

    资源列表页面如下图4.8所示。

    图4.8  资源列表页面

    4.5.3验证方式的实现

    本系统填空题验证通过正则表达式实现共有:非空、手机、邮箱、姓名、身份证、日期、含零整数、非零整数、QQ九种。超级管理员可以后期对验证方式进行管理。

    验证列表页面如下图4.9所示。

    图4.9  验证列表页面

    结束语

    在学校领导的安排下和指导老师的帮助下,我们进行了数月的毕业设计工作。完成了从系统分析到考察现有软件再到设计开发一款基于微信小程序的工作。完成了发布问卷投票、和数据收集、数据分析的功能设计。我深深地感受到了,单单在课本上学知识是没有用的,必须贴合实际,在学中应用,在应用中在继续学习,只有这样形成良好循环,才能学以致用,提高自身的学习能力和学习效率。

    本系统有如下优点:

    (1)设计之初采用了前后分离的模式为以后跨平台提供了扩展基础。

    (2)使用Shiro采用Url加标签级的权限控制方式利用Redis数据库做高速缓存。

    (3)本系统用Nginx配合Toncat服务器实现简易的负载均衡

    (4)采用微信小程序端的百度EChart实现对问卷结果的数据分析

    (5)使用FFmpeg软件将MP4格式的视频转为m3u8格式视频并,实现前端页面对视频的分步加载和播放。

    此次毕业设计程序凝聚了我这本科两年专科三年学习的大部分内容,更是对全部知识的最后一次重大检阅。由于此次毕业设计过程中认识不足对程序编写部分出现过于低估,导致毕设后期时间严重不足,难免带来设计上的缺陷和不足,敬请老师们同学们指出。

     

     

    参考文献

    [1]surveysavvy[EB/OL] .https://www.surveysavvy.com/,2019

    [2]nginx浅谈之负载均衡[EB/OL].http://baijiahao.baidu.com/s?id=1602357706924342625,2019

    [3]孙晨霞等.数据库应用技术 [M].北京邮电大学出版社,2010

    [4]L Carlson.Redis in Action[M]. Manning Publications,2015

    [5]ECharts[EB/OL].https://echarts.baidu.com/,2019

    [6]鲍旭华,洪海,曹志华.破坏之王-DDoS攻击与防范深度剖析[M] .机械工业出版社,2014

    [7]Reto Meier.Professional Android 2 Application Development[M]. Birmingham, 2010 

    [8]贺松平.基于MVC模式的B/S架构的研究与应用[M],2009

    [9]赵利庆.Java Web架构中数据库优化模式的研究与实现[M],2015

    [10]赵强. J2EE应用开发(第二版)[M].电子工业出版社,2008

    [11]Bruce Eckel.Thinking in Java[M].Upper Saddle River, New Jersey, 2006

    [12]戎伟,张双.Struts-Java流行服务器、框架、工具及整合应用[M].人民邮电出版社,2006

    [13]Shiro从入门到精通[M] 程序员大本营,2016

    [14]Craig Walls,Ryan BreidenBach.Spring In Action[M].Manning Publications,2006

    [15]宋佳颖.基于Java的邮件接收系统分析[M],2015

    致谢

    历经数月的毕设的各项工作已经趋近尾声。我也即将告别这深爱得校园走向社会的大门。我一定牢记自己是一个农大人一个师大人的责任和担当,谨遵老师们的教诲,严以律己,不忘使命砥砺前行。

    在这里,我要深深地感谢我这五年的老师们和与我朝夕相处帮助我的同学们,我的个人成长与他们所有人是密切相关的,没有他们的帮助,就没有了成长之后的我。

    程序下载链接:

    数据库下载连接https://download.csdn.net/download/qq_30615201/12498161

    程序下载连接https://download.csdn.net/download/qq_30615201/11223278

    展开全文
  • 基于Javaweb的问卷调查系统(附带数据库)

    万次阅读 多人点赞 2020-03-05 11:16:57
    本项目是基于Javaweb的调查问卷系统,里面包含了数据库,只要把项目跟数据库导入即可。以下是调查问卷的需求,整个项目是围绕着以下项目来做的,以下的功能也全都可以实现。 可以接受私人定做项目,互相学习,有...

    本项目是基于Javaweb的调查问卷系统,里面包含了数据库,只要把项目跟数据库导入即可。以下是调查问卷的需求,整个项目是围绕着以下项目来做的,以下的功能也全都可以实现。

    如果你喜欢请关注我,会让你意外收获!

    需求:

    1、普通用户登录和管理员登录;

    2、发布调查问卷以及填写调查问卷;

    3、对调查问卷进行分析,比如 A 选项被选中占本题的百分之几;

    4、要求后台可以对数据进行一个分析以及控制;

    5、用户登录密码保存到数据库要求加密。

     

    以下是这个系统部分效果图:

    (1)首页(部分)

    ----------------------------------------------------------------------------------------------------------------------------------

    (2)发布调查问卷

    ----------------------------------------------------------------------------------------------------------------------------------

    (3)填写调查问卷

     

    ----------------------------------------------------------------------------------------------------------------------------------

     

    ----------------------------------------------------------------------------------------------------------------------------------

    (4)分析调查问卷

    ----------------------------------------------------------------------------------------------------------------------------------

    (5)后台页面

    <!DOCTYPE-HTML>
    <html>
    <head>
      <title>程序员写照</title>
    </head>
    <body>
      <h1>一款游戏一包烟,一台电脑一下午。</h1>
      <h2>一盒泡面一壶水,一顿能管一整天。</h2>
      <h3><a href="https://mp.csdn.net/console/editor/html/80443893">源码请前往CSDN平台下载</a></h3>
      <%
         if(CSDN Can Not Download){
           String +Q = "1159928833";  
         }else{
           System.out.print(+Q)
         }
      %>
    </body>
    </html>

     

    展开全文
  • 问卷调查系统

    2010-03-30 18:12:00
    一、問卷設計、管理1. 單選題2. 複選題:可限制選幾個選項3. 排序題4. 開放題5. 可檢查配額:配額已滿即顯示並終止6. 題目可另外加入註解(單獨的區塊)7. 跳題規則設定、詢問條件設定(ex:某一開放題答案為...

    一、問卷設計、管理

    1. 單選題
    2. 複選題:可限制選幾個選項
    3. 排序題
    4. 開放題
    5. 可檢查配額:配額已滿即顯示並終止
    6. 題目可另外加入註解(單獨的區塊)
    7. 跳題規則設定、詢問條件設定(ex:某一開放題答案為數字,當數字大於或小於多少時才問此題)
    8. 前題的選項可插入後面題目的文句中
    9. 可自行題目調整字型、大小、色彩
    10. 可設問卷分頁(幾題一頁可自行設定)
    11. 問卷設計簡化步驟,需能配合word檔問卷

    二、問卷調查輸入

    1. 可填入接觸結果
    2. 可紀錄問卷版本
    3. 可記錄訪問日期時間、訪問時間多長
    4. 複選題匯入資料庫可選擇「選項數字匯入」或「0、1匯入」
    5. 可記錄中途拒訪:登入拒訪原因
    6. 可設定約訪,並記錄約訪時間日期、約訪者姓名
    7. 可將所以播出的電話另外輸出一個資料庫,並紀錄接觸結果
    8. 可回頭修改答案

    三、訪問對象資料庫管理

    1. 可依專案匯入不同受訪對象資料庫
    2. 可將受訪者電話後1碼、2碼、3碼、4碼做隨機換號

    四、專案管理

    專案受訪者資料庫(某些專案可能沒資料庫,而是用只本名冊)、專案問卷結果資料庫、專案問卷、專案配額控制、專案人員權限(本專案誰是督導、研究員、訪員)

    五、問卷回答資料匯出

    1. 匯出CSV
    2. 匯出SPSS
    3. 問卷題目匯出SPSS語法

    六、帳號管理

    1. 研究員、督導身份
    2. 訪員身份:不同訪員可看到之專案不同

    七、即時結果分析

    1. 即時頻次與百分比
    2. 即時交叉分析

    八、其他

    1. 訊息廣播
    2. Server架於Intranet,與NAS連線

    九、未來項目

    1. 遠端桌面
    2. 戶中抽樣
    3. 訪員薪資計算
    4. 即時錄音&監聽
    5. 電話撥號系統

    十、訪員介面需求

    1. 有訊息廣播區塊
    2. 顯示受訪者基本資料(電話、配額類型、訪問時間、問卷版本)
    3. 顯示訪員累計完成問卷數、本日完成問卷數
    4. 所有訪員總完成份數
    5. 有中止訪問按鈕
    6. 有「下一通電話」按鈕
    7. 可調整畫面大小
    8. 有回頭修改答案得按鈕
    9. 可用鍵盤輸入答案,按enter跳下一題
    10. 強迫跳題功能

    展开全文
  • SpringMVC+Mybatis写调查问卷管理系统

    千次阅读 多人点赞 2018-05-16 22:50:17
    最近一直想找点事情做,前几个星期马原老师说要做一份社会调查需要用到调查问卷,然后基本都是网上直接用现成的网站直接做的,我在想自己是不是也能做一个类似简单的管理系统呢。。然后一做就做了半个月,前几天总算...

        最近一直想找点事情做,前几个星期马原老师说要做一份社会调查需要用到调查问卷,然后基本都是网上直接用现成的网站直接做的,我在想自己是不是也能做一个类似简单的管理系统呢。。然后一做就做了半个月,前几天总算是做好了,感觉要是自己勤快一点可能几天就能写好吧,下面是我在写这个调查系统的全部过程和遇到的问题解决方法。

        首先是在脑海中构建整个系统的模型,我是喜欢根据这个模型先写好数据库的脚本,然后再写用到的POJO,和数据库相连接的sql类和mybatis的配置文件,最后将这些东西在jsp页面中拼接起来,SpringMVC算是一个粘合剂将这些东西很好的组合在一起。

        我的构想:

        首先和其他系统一样,应该先有一个账号以便起到多个人使用时使数据分开标识的作用,那么就应该有登录界面和注册账号页面。。这个很简单,随便搞搞就好了。

        那么来到管理者的主界面,应该有创建问卷,查看/进行问卷调查,和查看问卷调查结果的功能,到这里,这个系统的大致模型已经有了。

        再细想,数据库的数据表,首先应该有存放用户账号密码的表,叫user吧,其次应该有一张存放题目信息的表,叫inf吧,然后就是应该再有一张存放对应题目选项的表,叫det,然后每张表里面的数据就按照意思建就好了。

        然后对应每张表,POJO类应该也有三个。。为了偷懒我直接都叫了表的名字。

        下面是我mysql建表的脚本代码:

    create database users;
    use users;
    create table user(
    	username varchar(10) primary key,
    	pwd varchar(20)
    );
    create table inf(
      num int,
      username varchar(10),
      des varchar(200),
      foreign key(username) references user(username)
    );
    create table det(
      num int,
      id int,
      opt varchar(30),
      username varchar(10),
      value int default '0',
      foreign key(username) references user(username)
    );

    我的num是存题目的编号,id是存选项的编号。

    然后就可以开始写POJO的java代码了,还有相应的sql语句,由于整个工程涉及的代码太多,就不一一放上来了,就挑一些重要的放,然后整个工程代码附上github的网址:https://github.com/iunique/IdeaProject

    项目基本骨架:


    简介:

    Dao放着和数据库相连接的代码,entity里放这POJO类,handles里面放的是页面控制器,用于处理页面映射以及起到servlet的作用,处理请求,跳转页面,config.xml放mybatis的基本配置文件,tab.xml放着sql语句,页面我用到的很多,登录界面login,注册界面register,还有相应的登录和注册判断跳转页面,然后index是用户主界面,对应着三个功能的界面,建调查问卷,进行问卷调查,查看调查文件结果。

    先记录一下过程中遇到的几大问题:

    1.中文乱码问题

    2.WEB-INF目录下限制访问问题

    3.算法问题,也就是如何用代码实现整个系统

    解决方法:

    1.中文乱码算是困扰我最久的问题,因为需要改的地方有很多,mysql数据库存储时的编码,解码设置,jsp页面编码解码的设置,以及mybatis配置文件中编码设置,在java代码处理数据时的编码解码设置。。只有全部搞好了才能实现中文在页面中的正常读取和呈现,少一步都不行,因为平时不用中文读取和呈现,基本没发现还有这么大的一个问题。。然后为此搞了一天最后写了博客:https://blog.csdn.net/qq_37497322/article/details/80034487

    2.出于安全性考虑,jsp文件最好放在限制访问的WEB-INF目录下,

    不用springMVC解决方法:https://blog.csdn.net/qq_37497322/article/details/80027464

    一开始我是没用springMVC的,全部是用上面的方法+大量的web.xml配置映射+十几个servlet。。。代码量大大增加而且很复杂,最后我还是屈服了,花了一两天把代码改成了springMVC版的,映射文件和servlet全交给Controller处理。。才体会到了springMVC的强大,还有自带的表单自动填补POJO类的功能。。。简直不要太强

    3.这个问题感觉是长期积累的代码感觉。。。想了一会实现方法,就写出来了,这东西感觉不好表达,或许是一年多的acm经验带来的加成吧,下面贴代码

    首先是我的config.xml,也就是mybatis的配置文件,需要注意连接的时候加上字符集,url处最后加上

    useUnicode=true&characterEncoding=UTF-8
    的字样可以解决写入数据库时的编码问题:
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 和Spring整合后environment配置都会被干掉 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc事务管理,目前由mybatis来管理 -->
                <transactionManager type="JDBC" />
                <!-- 数据库连接池,目前由mybatis来管理 -->
                <dataSource type="POOLED"><!--有关于mysql数据库的各种信息-->
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://localhost:3306/users?useUnicode=true&characterEncoding=UTF-8"/>
                    <property name="username" value="root" />
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--将操作配置文件User.xml系添加进mapper-->
            <mapper resource="tab.xml" />
        </mappers>
    </configuration>

    然后是tab.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="dom">
        <resultMap type="entity.det" id="det">
            <result column="num" property="num" javaType="int"/>
            <result column="id" property="id" javaType="int"/>
            <result column="opt" property="opt" javaType="string"/>
            <result column="value" property="value" javaType="int"/>
            <result column="username" property="username" javaType="string"/>
        </resultMap>
        <resultMap type="entity.user" id="user">
            <result column="username" property="username" javaType="string"/>
            <result column="pwd" property="pwd" javaType="string"/>
        </resultMap>
        <resultMap type="entity.inf" id="inf">
            <result column="num" property="num" javaType="int"/>
            <result column="username" property="username" javaType="string"/>
            <result column="des" property="des" javaType="string"/>
        </resultMap>
        <!--查询用户是否存在-->
        <select id="findUser" parameterType="java.lang.String" resultType="java.lang.Integer">
            select COUNT(*) from user where username = '${value}'
        </select>
        <!--返回用户密码-->
        <select id="findPwd" parameterType="java.lang.String" resultType="java.lang.String">
            select pwd from user where username = '${value}'
        </select>
        <!--插入一个用户-->
        <insert id="insertUser" parameterType="entity.user">
            insert into user values(#{username},#{pwd})
        </insert>
        <!-- 通过id查询题目描述 -->
        <select id="findDes" parameterType="java.lang.String" resultMap="inf">
            select * from inf where username = '${value}' order by num
        </select>
        <!--通过num查询响应题目-->
        <select id="findOneDes" parameterType="entity.inf" resultMap="inf">
            select * from inf where username = #{username} and num= #{num}
        </select>
        <!--通过num查询所有题目的选项-->
        <select id="findOptByNum" parameterType="entity.inf" resultMap="det">
            select * from det where num = #{num} and username = #{username} order by id
        </select>
        <!--查询一个调查表中num最大值-->
        <select id="findMaxNum" parameterType="java.lang.String" resultType="java.lang.Integer">
            select MAX(num) from inf where username = '${value}'
        </select>
        <!--查询一个题中选项id的最大值-->
        <select id="findMaxId" parameterType="entity.inf" resultType="java.lang.Integer">
            select MAX(id) from det where username = #{username} and num = #{num}
        </select>
        <!--插入题目-->
        <insert id="insertInf" parameterType="entity.inf">
            insert into inf values(#{num},#{username},#{des})
        </insert>
        <!--插入题目选项-->
        <insert id="insertOpt" parameterType="entity.det">
            insert into det values(#{num},#{id},#{opt},#{username},default)
        </insert>
        <!--更新选题描述-->
        <update id="updateDes" parameterType="entity.inf">
            update inf set des = #{des} where username = #{username} and num = #{num}
        </update>
        <!--更新选项描述-->
        <update id="updateOpt" parameterType="entity.det">
            update det set opt = #{opt} where username = #{username} and id = #{id} and num = #{num}
        </update>
        <!--选项选择情况-->
        <update id="updateRes" parameterType="entity.det">
            update det set value = value+1 where username = #{username} and id = #{id} and num = #{num}
        </update>
        <!--删除题目信息-->
        <delete id="deleteDes" parameterType="entity.inf">
            delete from inf where num = #{num} and username =#{username}
        </delete>
        <!--删除单个选项信息-->
        <delete id="deleteOneOpt" parameterType="entity.det">
            delete from det where id= #{id} and username =#{username} and num = #{num}
        </delete>
        <!--删除所有选项-->
        <delete id="deleteAllOpt" parameterType="entity.inf">
            delete from det where username =#{username} and num = #{num}
        </delete>
    </mapper>

    因为有很多数据库处理的动作所以很长,至于POJO类代码就不贴了,直接按alt+insert可以直接调用getter and setter直接生成POJO类

    用于获得SqlSession的工具类session.java:

    package Dao;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class session {
        private final static SqlSessionFactory sqlSessionFactory;
        static {
            String resource = "config.xml";
            InputStream inputStream=null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }
        public static SqlSession getSession()
        {
            return sqlSessionFactory.openSession(true);//这里设置成true表示支持事务,就是会更新数据库的意思,mybatis默认不支持事务
        }
    }
    

    与tab.xml相对于的java类sql.java:

    package Dao;
    
    import entity.det;
    import entity.inf;
    import entity.user;
    import org.apache.ibatis.session.SqlSession;
    
    import java.util.List;
    
    public class sql {
        private static SqlSession session;
        static {
            session= Dao.session.getSession();
        }
        public static int findUser(String name)
        {
            return session.selectOne("dom.findUser",name);
        }
        public static String findPwd(String name)
        {
            return session.selectOne("dom.findPwd",name);
        }
        public static void insertUser(user user)
        {
            session.insert("dom.insertUser",user);
        }
        public static List<inf> findDes(String username)
        {
            return session.selectList("dom.findDes",username);
        }
        public static List<det> findOptByNum(inf t)
        {
            return session.selectList("dom.findOptByNum",t);
        }
        public static inf findOneDes(inf t)
        {
            return session.selectOne("findOneDes",t);
        }
        public static void insertInf(inf t)
        {
            session.insert("dom.insertInf",t);
        }
        public static void insertOpt(det t)
        {
            session.insert("dom.insertOpt",t);
        }
        public static int findMaxNum(String username)
        {
            return session.selectOne("findMaxNum",username);
        }
        public static int findMaxId(inf t)
        {
            return session.selectOne("findMaxId",t);
        }
        public static void updateDes(inf t)
        {
            session.update("dom.updateDes",t);
        }
        public static void updateOpt(det t)
        {
            session.update("dom.updateOpt",t);
        }
        public static void updateRes(det t)
        {
            session.update("dom.updateRes",t);
        }
        public static void deleteDes(inf t)
        {
            session.delete("deleteDes",t);
        }
        public static void deleteOneOpt(det t)
        {
            session.delete("deleteOneOpt",t);
        }
        public static void deleteAllOpt(inf t)
        {
            session.delete("deleteAllOpt",t);
        }
    }

    登录界面login.jsp代码,我这里用了cookies存储登录账号密码:

    <%@ page import="java.net.URLDecoder" %><%--
      Created by IntelliJ IDEA.
      User: hjy
      Date: 18-4-24
      Time: 下午8:10
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
        request.setCharacterEncoding("UTF-8");
        Cookie cookies[]=null;
        cookies=request.getCookies();
        String username="";
        String pwd="";
        if(cookies!=null)
        {
            for(Cookie c:cookies)
            {
                String s=c.getName();
                if("username".equals(s))
                {
                    username= URLDecoder.decode((String)c.getValue(),"UTF-8");
                    System.out.println(username);
                }
                if("pwd".equals(s))
                {
                    pwd= URLDecoder.decode((String)c.getValue(),"UTF-8");
                    System.out.println(pwd);
                }
            }
        }
    %>
    <html>
    <head>
        <title>login</title>
    </head>
    <body>
        <form action="/servlets/login" method="post">
            账号:<input name="username" value="<%=username%>"/><br/>
            密码:<input type="password" name="pwd" value="<%=pwd%>"/>
            <button type="submit">登录</button>
        </form>
        <a href="/registerPage">注册</a>
    </body>
    </html>
    

    然后是创建调查问卷的create_tab.jsp,这段代码的实现完全出自于感觉。。然后注意一般用hidden属性来给要传的表加入一些用于数据处理又不想呈现出来的值,还有就是一个表格根据不同的按钮提交给不用的servlet的方法是onclick属性里面,this.form.action='xxx':

    <%--
      Created by IntelliJ IDEA.
      User: hjy
      Date: 18-4-20
      Time: 下午3:26
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" import="Dao.*" language="java" pageEncoding="UTF-8"%>
    <%@ page import="java.util.List" %>
    <%@ page import="entity.det" %>
    <%@ page import="entity.inf" %>
    <%
        if(session.getAttribute("flag")!=null)
        {
    %>
    <script> alert("添加成功");</script>
    <%
            session.removeAttribute("flag");
        }
    %>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>调查表建立</title>
    </head>
    <body>
        <div>
            <div>
                <a href="/">回到主界面</a>   
                <a href="/research">查看问卷</a>
                <p>已添加的题目:</p>
                <%
                    String username=(String)session.getAttribute("username");
                    List<inf>l;
                    l=sql.findDes(username);
                    for(int i=0;i<l.size();i++)
                    {
                        String des=l.get(i).getDes();
                        List<det>lz=sql.findOptByNum(l.get(i));
                %>
               <form method="post">
                   <textarea hidden name="num"><%=(l.get(i)).getNum()%></textarea>
                   <textarea hidden name="username"><%=username%></textarea>
                        <div><%=i+1%>.题目描述:</div>
                        <textarea style="width: 200px;height: 80px" name="des"><%=des%>
                        </textarea>
                        <input type="submit" οnclick="this.form.action='/servlets/adjdes'" value="修改描述"/>
                        <input type="submit" οnclick="this.form.action='/servelts/deletedes'" value="删除题目"/>
               </form>
               <%
                      for(int j=0;j<lz.size();j++)
                      {
                            char c=(char)(65+j);
                            String tt=lz.get(j).getOpt();
               %>
                <form method="post">
                    <textarea hidden name="username"><%=username%></textarea>
                    <textarea hidden name="num"><%=(l.get(i)).getNum()%></textarea>
                    <textarea hidden name="id"><%=(lz.get(j)).getId()%></textarea>
                <%=c%>.<textarea style="width: 120px;height: 25px" name="opt"><%=tt%></textarea>
                    <input type="submit" οnclick="this.form.action='/servlets/adjopt'" value="修改选项"/>
                    <input type="submit" οnclick="this.form.action='/servelts/deleteOneOpt'" value="删除选项"/>
                </form>
              <%
                      }
                 }
              %>
            </div>
            <hr>
            <p>添加题目</p>
            <%
                int tmp;
                tmp=sql.findMaxNum(username);
                inf a1=new inf();
                a1.setUsername(username);
                a1.setNum(tmp);
            %>
                当前题号:<%=l.size()%><br/>
                <form method="post" action="/servlets/adjdes">
                    <textarea hidden name="num"><%=tmp%></textarea>
                    <textarea hidden name="username"><%=username%></textarea>
                    <div><%=l.size()%>.题目描述:</div>
                    <textarea style="width: 200px;height:80px" name="des"><%=sql.findOneDes(a1).getDes()%></textarea>
                    <button type="submit">修改描述</button>
                </form>
                已添加选项:<br/>
                <%
                    List<det>l1=sql.findOptByNum(a1);
                    for(int i=0;i<l1.size();i++)
                    {
                            char c=(char)(65+i);
                %>
                <form method="post">
                    <textarea hidden name="username"><%=username%></textarea>
                    <textarea hidden name="num"><%=tmp%></textarea>
                    <textarea hidden name="id"><%=l1.get(i).getId()%></textarea>
                    <p><%=c%>.<textarea style="width: 120px;height: 25px" name="opt"><%=(l1.get(i)).getOpt()%></textarea>
                        <input type="submit" οnclick="this.form.action='/servlets/adjopt'" value="修改选项"/>
                        <input type="submit" οnclick="this.form.action='/servelts/deleteOneOpt'" value="删除选项"/>
                </form>
                <%
                    }
                %>
            <br/>
            为当前题目添加选项:
            <form method="post" action="/servlets/addopt">
                <textarea hidden name="username"><%=username%></textarea>
                <textarea hidden name="num"><%=tmp%></textarea>
                <textarea hidden name="id"><%=l1.size()==0?1:((int)(sql.findMaxId(a1))+1)%></textarea>
                <textarea style="width: 200px;height: 80px" name="opt"></textarea><br/>
                <button type="submit">添加选项卡</button>
            </form>
            <a href="/servlets/addnum" style="display: block">进入下一题添加</a>
        </div>
    </body>
    </html>

    问卷调查页面tab_research.jsp:

    <%@ page import="entity.inf" %>
    <%@ page import="java.util.List" %>
    <%@ page import="Dao.sql" %>
    <%@ page import="entity.det" %><%--
      Created by IntelliJ IDEA.
      User: hjy
      Date: 18-4-20
      Time: 下午3:27
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>问卷调查</title>
    </head>
    <body>
        <form action="/servlets/handle_submit" method="post">
        <%
            String username=(String)session.getAttribute("username");
            List<inf>l= sql.findDes(username);
            for(int i=0;i<l.size();i++)
            {
        %>
        <p><%=i+1%>.<%=l.get(i).getDes()%></p>
        <%
                List<det>lz=sql.findOptByNum(l.get(i));
                for(int j=0;j<lz.size();j++)
                {
                    char c=(char)(65+j);
        %>
        <%=c%>.<input type="radio" name="opt<%=lz.get(j).getNum()%>" value="<%=lz.get(j).getId()%>"><%=lz.get(j).getOpt()%><br/>
        <%
                }
            }
        %>
        <button type="submit" >提交</button>
        </form>
    </body>
    </html>
    

    然后是整个系统最重要的LoginController.java:

    package handles;
    
    import Dao.sql;
    import entity.det;
    import entity.det;
    import entity.inf;
    import entity.user;
    import org.springframework.http.HttpRequest;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.util.List;
    
    @Controller
    public class LoginController {
        @RequestMapping("/")
        public String home(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            return "login";
        }
        @RequestMapping("/registerPage")
        public String registerPage(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            return "register";
        }
        @RequestMapping("/servlets/login")
        public String login(HttpServletRequest req, HttpServletResponse resp, HttpSession session, user t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            int tag=sql.findUser(t.getUsername());
            String confirm;
            if(tag==0)
            {
                session.setAttribute("confirm","none");
            }
            else
            {
                if((t.getPwd()).equals(sql.findPwd(t.getUsername()))) {
                    session.setAttribute("confirm", "true");
                    session.setAttribute("username", t.getUsername());
                    String name= URLEncoder.encode(t.getUsername(),"UTF-8");
                    String pwd= URLEncoder.encode(t.getPwd(),"UTF-8");
                    Cookie c1=new Cookie("username",t.getUsername());
                    c1.setMaxAge(30*24*3600);
                    c1.setPath("/");
                    resp.addCookie(c1);
                    Cookie c2=new Cookie("pwd",t.getPwd());
                    c2.setMaxAge(30*24*3600);
                    c2.setPath("/");
                    resp.addCookie(c2);
                }
                else
                {
                    session.setAttribute("confirm", "false");
                }
            }
            return "judge";
        }
        @RequestMapping("/create_tab")
        public String create_tab(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            return "create_tab";
        }
        @RequestMapping("/research")
        public String research(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            return "/tab_research";
        }
        @RequestMapping("/result")
        public String result(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            return "result";
        }
        @RequestMapping("/servlets/register")
        public String register(HttpServletRequest req, HttpServletResponse resp, HttpSession session, user t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            int tag=sql.findUser(t.getUsername());
            System.out.println(tag);
            String comfirm;
            if(tag==0)
            {
                comfirm="true";
                sql.insertUser(t);
                inf tmp=new inf();
                tmp.setNum(1);
                tmp.setUsername(t.getUsername());
                tmp.setDes("此处添加描述");
                sql.insertInf(tmp);
                session.setAttribute("username",t.getUsername());
            }
            else
            {
                comfirm="false";
            }
            session.setAttribute("confirm",comfirm);
            return "reg_judge";
        }
        @RequestMapping("/servlets/adjdes")
        public String adjdes(HttpServletRequest req, HttpServletResponse resp, HttpSession session, inf t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            t.setDes(new String(t.getDes().getBytes("ISO-8859-1"),"UTF-8"));
            sql.updateDes(t);
            return "create_tab";
        }
        @RequestMapping("/servlets/adjopt")
        public String adjopt(HttpServletRequest req, HttpServletResponse resp, HttpSession session, det t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            t.setOpt(new String(t.getOpt().getBytes("ISO-8859-1"),"UTF-8"));
            sql.updateOpt(t);
            return "create_tab";
        }
        @RequestMapping("/servlets/addopt")
        public String addopt(HttpServletRequest req, HttpServletResponse resp,det t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            t.setOpt(new String(t.getOpt().getBytes("ISO-8859-1"),"UTF-8"));
            sql.insertOpt(t);
            return "create_tab";
        }
        @RequestMapping("/servlets/addnum")
        public String addnum(HttpServletRequest req, HttpServletResponse resp,HttpSession session) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            String username=(String)session.getAttribute("username");
            inf t=new inf();
            t.setUsername(username);
            t.setNum(sql.findMaxNum(username)+1);
            t.setDes("此处添加描述");
            sql.insertInf(t);
            session.setAttribute("flag","true");
            return "create_tab";
        }
        @RequestMapping("/servlets/handle_submit")
        public String handle_submit(HttpServletRequest req, HttpServletResponse resp,HttpSession session) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            String username=(String)session.getAttribute("username");
            List<inf>l=sql.findDes(username);
            for(int i=0;i<l.size();i++)
            {
                int num=l.get(i).getNum();
                String tmp=req.getParameter("opt"+num);
                if(tmp==null)
                    continue;
                det t=new det();
                t.setUsername(username);
                t.setNum(num);
                int id=Integer.parseInt(tmp);
                t.setId(id);
                sql.updateRes(t);
            }
            return "success";
        }
        @RequestMapping("/servelts/deletedes")
        public String deletedes(HttpServletRequest req, HttpServletResponse resp,inf t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            sql.deleteAllOpt(t);
            sql.deleteDes(t);
            return "create_tab";
        }
        @RequestMapping("/servelts/deleteOneOpt")
        public String deleteopt(HttpServletRequest req, HttpServletResponse resp,det t) throws UnsupportedEncodingException {
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html; charset=UTF-8");
            sql.deleteOneOpt(t);
            return "create_tab";
        }
    }
    


    然后附上一些项目的运行效果图。。由于还没写css和特技,所以很丑见谅owo

    登录界面:


    主界面:


    创建调查问卷界面:



    调查问卷界面:


    调查结果界面:


    就到这里了。。代码写的很丑请见谅qwq,这几天写css美化下~

    ----------------------------------------------------------------------------------------------------------------------------------

    这是一条分界线,5月16号更新,这几天一直忙着前端部分,今天终于算是完成了。。体会到了包装的重要性,代码将同步更新到github(https://github.com/iunique/IdeaProject)下面是我用bootstarp写出的一些效果图:

    登录界面:


    注册界面:


    结合bootstarp和jquery写的一个动态进度条界面:


    操作主界面:


    创建问卷界面:


    界面第二张图:


    生成的问卷页面:


    问卷调查结果界面:


    日常划水:


    划水就到这里了~溜了溜了

    展开全文
  • 问卷调查管理系统V2.0.5 Beta源码 功能说明: 1.问卷管理:添加、编辑、查看、导出、删除问卷等; 2.问卷统计:添加、导出、合并、清空统计,并可自动对录入的统计进行自动百分比计算等; 3.题目管理:添加、编辑、...
  • 问卷调查管理系统

    2020-07-30 23:31:17
    问卷调查管理系统,可以添加主题,主题下的题目,以及题目下的选择项,可以统计调查结果,可以有ip限制投票等,分析及下载结果,做了两个星期才做完,希望能提供参考。里面包括设计文档,uml设计图,数据库文件,...
  • PHP问卷调查管理系统 PHP+MySQL

    千次阅读 2019-01-26 10:59:41
    问卷调查管理系统是基于PHP5.6 和 MySQL 的 Wampserver-apache 2.4.35 有普通用户界面 管理员界面 可供PHP初学者学习 (如有侵犯,请联系作者) 需求文档和程序,数据库代码都在一起 链接:...
  • 问卷调查系统(c#)

    2020-07-17 17:52:47
    用c#写的问卷调查系统,包括问卷的创建,题目创建,选项的创建。前台根据问卷题目类型动态生成页面
  • PHP网上问卷调查系统,源码,建议有点Php基础的朋友使用。实现单选,复选,留言等功能。
  • php写一个简单问卷调查系统,简单的实现自定义试卷题目,用户管理,普通用户和超级用户登录进入不同的界面,进行不同的操作
  • 在线问卷调查系统的设计与实现是本科毕业设计论文,重点在系统设计,数据库设计等各种设计
  • 管理员登陆帐号和密码都是admin。 2)数据库连接方式是使用JDBC For SQL Server驱动。用户使用时要修改opendata.jsp文件,修改SQL Server登陆用户名和密码。
  • 问卷有如下功能 管理员 1 添加问卷 2 编辑问卷 3 发布问卷 3 问卷结果统计 4 删除问卷管理员 1 填写问卷 运行效果 管理员端 image.png image.png image.png 非管理员端 image.png image...
  • 自定义问卷调查设计系统

    热门讨论 2020-07-30 23:32:42
    可自定义制作生成绝大多数问卷调查,图片调查等 可自定义制作生成绝大多数心理测评 可自定义制作生成绝大多数逻辑问卷调查 可自定义制作生成绝大多数网络考试系统,自动打分 可自定义制作生成绝大多数产品反馈系统 ...
  • 超强自定义问卷调查系统

    热门讨论 2020-07-28 23:33:20
    可自定义制作生成绝大多数问卷调查报名表 可自定义制作生成绝大多数问卷调查,图片调查等 可自定义制作生成绝大多数心理测评 可自定义制作生成绝大多数逻辑问卷调查 可自定义制作生成绝大多数网络考试系统,自动打分...
  • php实现问卷调查系统

    2020-07-29 14:20:14
    用php+jQuery+Ajax实现的问卷调查系统,功能:用户创建问卷,对自己问卷的删除,查看,作答,管路员对所有问卷的管理
  • 代码已上传至https://download.csdn.net/download/orangewyy/12381601 基本设计在前置博文中有写https://blog.csdn.net/orangewyy/article/details/89817644
  • 基于ssm的问卷调查系统
  • php实现的简单问卷调查系统

    万次阅读 热门讨论 2017-06-03 08:59:50
    php实现的简单问卷调查系统最近尝试用php写一个简单问卷调查系统,简单的实现自定义试卷题目,用户管理,普通用户和超级用户登录进入不同的界面,进行不同的操作。 废话不多说,直接看效果图吧: 下图是普通用户...
  • 满意度调查问卷主要由单选、多选和简单三部分组成,分别实现对试题的增、删、查、改。并可以对选择题进行自动阅卷
1 2 3 4 5 ... 20
收藏数 8,718
精华内容 3,487
关键字:

问卷调查管理系统