调查问卷

来源:互联网 发布:数据字典模板 编辑:程序博客网 时间:2024/06/09 14:23

在线调查问卷在我们的生活中应用的非常广泛,能够非常方便快捷的获取到我们需要的信息,统计分析出相关核心的数据,方便我们的决策。在微信发展迅速的时代,覆盖面非常的大,那么基于微信公众号去推送我们的在线问卷调查,这个就是一个相当方便、有价值的系统。那么,今天我就来大概讲一讲利用我们起步公司研发的WeX5平台快速开发出一款在线调查问卷的系统,我们主要分以下几个步骤讲解,如有纰漏,还望及时指出,谢谢微笑

一、效果图展示

效果图展示主要分为后台的数据管理及前端的调查问卷:

后台管理系统效果图如下所示:

问卷调查发布页面:


问卷调查统计页面:


问卷调查汇总页面:


问卷调查详情页面:


微信公众号中的前端效果图:



二、在线调查后台管理

在线调查后台管理系统主要用于对调查问卷的发布及统计信息进行管理,方便管理人员对所有发布信息的管控,以及对调查的问卷进行汇总统计,总结出有利于生产的有价值的数据。我们在项目选型之前,考虑了java框架的后台以及BeX5的平台,分析评估后一致觉得BeX5平台在开发效率和后期维护、性能稳定方面都有非常大的优势,所以我们使用该平台作为我们后台管理系统的主选开发平台。在项目开发过程中也确实体现了该平台强大的优势:上手快、开发效率高、维护成本低、性能稳定。详细的后台管理系统的界面见上面的后台效果图。

废话不多说了,看看后台的开发界面吧,感受一下BeX5开发平台带给我们的快感奋斗奋斗


是不是很壮观的页面啊,包括了源码、设计、JS、CSS,还有一系列的封装好的组件可供使用。其中设计页面,可实现拖拽布局、js页面实现前端逻辑处理、css实现样式。好了,贴些代码感受一下js的强大吧:

[javascript] view plain copy
  1. define(function(require) {  
  2.     var $ = require("jquery");  
  3.     var justep = require("$UI/system/lib/justep");  
  4.     var biz = require("$UI/system/lib/biz");  
  5.   
  6.     var Model = function() {  
  7.         this.callParent();  
  8.     };  
  9.   
  10.     var mainData = "";  
  11.     Model.prototype.modelLoad = function(event) {  
  12.         mainData = this.comp("mainData");  
  13.         var type = this.getContext().getRequestParameter("type");  
  14.         if (type == "new") {  
  15.             mainData.newData();  
  16.         } else if (type == "edit") {  
  17.             var data = this.getContext().getRequestParameter("data");  
  18.             if (data) {  
  19.                 var filter = "RM_VS_Paper='" + data + "'";  
  20.                 mainData.setFilter("____dataFilter_", filter);  
  21.                 mainData.refreshData();  
  22.             }  
  23.             if (mainData.getValue("fPState") == "已完成"  
  24.                     || mainData.getValue("fPState") == "已终止") {  
  25.                 this.comp("trgFinish").set({  
  26.                     "disabled" : "true"  
  27.                 });  
  28.                 this.comp("trgAbort").set({  
  29.                     "disabled" : "true"  
  30.                 });  
  31.                 this.comp("saveBtn").set({  
  32.                     "disabled" : "true"  
  33.                 });  
  34.                 this.comp("surveyBtn").set({  
  35.                     "disabled" : "true"  
  36.                 });  
  37.   
  38.                 this.comp("button6").set({  
  39.                     "disabled" : "true"  
  40.                 });  
  41.                 this.comp("button4").set({  
  42.                     "disabled" : "true"  
  43.                 });  
  44.                 this.comp("button5").set({  
  45.                     "disabled" : "true"  
  46.                 });  
  47.                 this.comp("button9").set({  
  48.                     "disabled" : "true"  
  49.                 });  
  50.                 this.comp("button7").set({  
  51.                     "disabled" : "true"  
  52.                 });  
  53.                 this.comp("button8").set({  
  54.                     "disabled" : "true"  
  55.                 });  
  56.   
  57.                 this.comp("addBtn").set({  
  58.                     "disabled" : "true"  
  59.                 });  
  60.                 this.comp("button11").set({  
  61.                     "disabled" : "true"  
  62.                 });  
  63.             }  
  64.   
  65.         }  
  66.   
  67.         var uploader = this.comp("attachmentSimple1").uploader;  
  68.         var data = this.comp("dQuestion");  
  69.         uploader.on('onFileSelected'function(event) {  
  70.             var fileName = event.file.name;  
  71.             fileName.lastIndexOf(".")  
  72.             var fileType = fileName.substr(fileName.lastIndexOf(".") + 1,  
  73.                     fileName.length).toLowerCase();  
  74.             // alert(fileType);  
  75.             if (fileType != "jpg" && fileType != "png") {  
  76.                 alert("请选择jpg或者png格式文件!");  
  77.                 event.cancel = true;  
  78.                 return;  
  79.             }  
  80.             // 只能上传一张,再次上传则替换  
  81.             var img = data.val("fQuestionPic");// 要在这里取值  
  82.             if (img !== null && img != "" && img !== "[]"  
  83.                     && typeof (img) !== "undefined") {  
  84.                 data.setValue("fQuestionPic""");  
  85.             }  
  86.         });  
  87.   
  88.     };  
  89.   
  90.     // 新增  
  91.     Model.prototype.newBtnClick = function(event) {  
  92.         var url = "$UI/riskMonitor/survey/process/surveySend/detailActivity.w?process=/riskMonitor/survey/process/surveySend/surveySendProcess&activity=surveySendActivity&type=new&data="  
  93.                 + mainData.getCurrentRowID();  
  94.         justep.Portal.openWindow(url, {  
  95.             title : "问卷调查发布"  
  96.         });  
  97.     };  
  98.   
  99.     // 完成调查  
  100.     Model.prototype.trgFinishDOMActivate = function(event) {  
  101.         var messageDialog2 = this.comp("messageDialog2");  
  102.         messageDialog2.show();  
  103.         messageDialog2.on("onOk"function(event) {  
  104.             var paperID = mainData.getCurrentRowID();  
  105.             mainData.setValue("fPState""已完成");  
  106.             mainData.setValue("fFinishTime"new Date());  
  107.             mainData.saveData();  
  108.             mainData.filters.setFilter("paperFilter""RM_VS_Paper='" + paperID  
  109.                     + "'");  
  110.             mainData.refreshData();  
  111.             this.callBackFun();  
  112.         }, this);  
  113.     };  
  114.   
  115.     // 撤销问卷  
  116.     Model.prototype.trgAbortDOMActivate = function(event) {  
  117.         var messageDialog3 = this.comp("messageDialog3");  
  118.         messageDialog3.show();  
  119.         messageDialog3.on("onOk"function(event) {  
  120.             var paperID = mainData.getCurrentRowID();  
  121.             mainData.setValue("fPState""已终止");  
  122.             mainData.saveData();  
  123.             mainData.filters.setFilter("paperFilter""RM_VS_Paper='" + paperID  
  124.                     + "'");  
  125.             mainData.refreshData();  
  126.             this.callBackFun();  
  127.         }, this);  
  128.     };  
  129.     // 回调函数?????????????????????????  
  130.     Model.prototype.callBackFun = function(event) {  
  131.         this.comp("trgFinish").set({  
  132.             "disabled" : "true"  
  133.         });  
  134.         this.comp("trgAbort").set({  
  135.             "disabled" : "true"  
  136.         });  
  137.         this.comp("saveBtn").set({  
  138.             "disabled" : "true"  
  139.         });  
  140.         this.comp("deleteBtn").set({  
  141.             "disabled" : "true"  
  142.         });  
  143.         this.comp("surveyBtn").set({  
  144.             "disabled" : "true"  
  145.         });  
  146.   
  147.         this.comp("button6").set({  
  148.             "disabled" : "true"  
  149.         });  
  150.         this.comp("button4").set({  
  151.             "disabled" : "true"  
  152.         });  
  153.         this.comp("button5").set({  
  154.             "disabled" : "true"  
  155.         });  
  156.         this.comp("button9").set({  
  157.             "disabled" : "true"  
  158.         });  
  159.         this.comp("button7").set({  
  160.             "disabled" : "true"  
  161.         });  
  162.         this.comp("button8").set({  
  163.             "disabled" : "true"  
  164.         });  
  165.   
  166.         /* 
  167.          * var caller = null; var callerName = 
  168.          * justep.Request.URLParams.callerName; if(callerName && (callerName != 
  169.          * '')) { var frames = window.parent.frames; for(var i=0; i<frames.length; 
  170.          * i++) { if(frames[i].name == callerName) { caller = frames[i]; break; } } } 
  171.          * if(caller) { if(caller.dataChangeCallBackFun) { //var data = 
  172.          * justep.xbl('dPaper'); var id = mainData.getCurrentRowID(); 
  173.          * caller.dataChangeCallBackFun(id); } } 
  174.          */  
  175.     };  
  176.   
  177.     // 调查发布  
  178.     Model.prototype.button1Click = function(event) {  
  179.         var mainData = this.comp('mainData');  
  180.         var paperID = mainData.getCurrentRowID();  
  181.         if (mainData.getCount() == 0) {  
  182.             alert("请选择要发布的问卷信息!");  
  183.             return;  
  184.         }  
  185.         var fPState = mainData.getValue("fPState");  
  186.         if (fPState == "编制中") {  
  187.             var messageDialog1 = this.comp("messageDialog1");  
  188.             messageDialog1.show();  
  189.             messageDialog1.on("onOk"function(event) {  
  190.                 mainData.setValue("fPState""已发布");  
  191.                 mainData.setValue("fSendTime"new Date());  
  192.                 mainData.saveData();  
  193.                 mainData.filters.setFilter("paperFilter""RM_VS_Paper='"  
  194.                         + paperID + "'");  
  195.                 mainData.refreshData();  
  196.             }, this);  
  197.         } else if (fPState == "已发布") {  
  198.             alert("本次调查已发布,不能再进行发布!");  
  199.         } else if (fPState == "已终止") {  
  200.             alert("本次在线调查已终止,不能再进行问卷发布!");  
  201.         } else {  
  202.             alert("本次在线调查已完成,不能再进行问卷发布!");  
  203.         }  
  204.     };  
  205.   
  206.     // 问卷调查预览  
  207.     Model.prototype.trgPreviewDOMActivate = function(event) {  
  208.         var process = this.getContext().getCurrentProcess();// justep.Context.getCurrentProcess();  
  209.         var activity = this.getContext().getCurrentActivity();// justep.Context.getCurrentActivity();  
  210.         var mainData = this.comp("mainData");  
  211.         var paperid = mainData.getCurrentRowID();  
  212.         // var url =  
  213.         // "/riskMonitor/survey/process/surveyPaper/surveyPaper.j?process=" +  
  214.         // process + "&activity=" + activity + "&paperID=" + paperid;  
  215.         var url = "$UI/riskMonitor/survey/process/surveyPaper/surveyPaper.j?process="  
  216.                 + process + "&activity=" + activity + "&paperID=" + paperid;  
  217.         justep.Portal.openWindow(url, {  
  218.             title : "调查问卷预览"  
  219.         });  
  220.     };  
  221.   
  222.     Model.prototype.addBtnClick = function(event) {  
  223.         // 添加调查员  
  224.         this.comp("windowDialog").open();  
  225.     };  
  226.   
  227.     return Model;  
  228. });  

三、前端开发

前面我们讲解了后台管理系统的开发,那么还有一个最重要的前端展示,我们选择了WeX5平台,WeX5平台封装了相当多的H5组件,方便我们开发人员的拖拽,只要熟悉h5、js、css就可以完全胜任前端的开发了。

前端UI:完全恪守html5+css3+js,干净纯洁
设备api:采用业界主流Phonegap/Cordova
后端:标准协议,支持所有主流技术和平台
(java、node、php、.net等)

向导、模板:简单定义,即可轻松制作向导和模板
主题、样式:海量bootstrap资源引入和定制
UI组件:纯H5+CSS3,轻松引入第三方UI组件
插件:轻松对接即时通讯、推送、支付等各类插件
后端:轻松调用后端组件和api,并实现可视化

各种应用打包:无任何限制和费用,打包多种应用
(Android apk,ios ipa、微信和其他轻应用)
各种打包模式:快捷打包、远程服务打包、原生环境打包,
给你所有的打包方式和方便性

我们可以使用WeX5平台开发出安卓、苹果手机App,也可以开发出基于微信的项目,非常的方便。


前端开发页面类似于BeX5的开发页面,可以对问答题、单选题、多选题、判断题进行控制显示,涵盖了大多数的调查问卷格式,可以应用于多个行业。

看下在线调查的前端js代码:

[javascript] view plain copy
  1. define(function(require) {  
  2.     var $ = require("jquery");  
  3.     var justep = require("$UI/system/lib/justep");  
  4.     var Baas = justep.Baas;  
  5.   
  6.     var Model = function() {  
  7.         this.callParent();  
  8.         this._userID = "";  
  9.         this._userNickName = "";  
  10.         this._userAdrress = "";  
  11.         this._longtitude = "";  
  12.         this._latitude = "";  
  13.     };  
  14.   
  15.     // 获取页面索引  
  16.     Model.prototype.MyGetIndex = function(event) {  
  17.         return this.comp("data1").getRowIndex(this.comp("data1").getCurrentRow()) + 1;  
  18.     };  
  19.   
  20.     Model.prototype.modelParamsReceive = function(event) {  
  21.         var paperID = this.getContext().getRequestParameter("paperID");  
  22.         var data1 = this.comp("data1");  
  23.         var surveyData = this.comp("surveyData");  
  24.         surveyData.setFilter("surveyFilter0""fPaperID = '" + paperID + "' and fPerID = '" + this.getContext().getRequestParameter("openID") + "'");  
  25.         surveyData.refreshData();  
  26.         if (surveyData.getCount() > 0 && surveyData.getFirstRow().val("fSState") == "已完成") {  
  27.             this.setPropReadonly();  
  28.         }  
  29.         ;  
  30.         Baas.sendRequest({  
  31.             "url" : "/riskMonitor/riskMonitor",  
  32.             "action" : "queryQuestion",  
  33.             "async" : false,  
  34.             "params" : {  
  35.                 paperID : paperID,  
  36.                 openID : this.getContext().getRequestParameter("openID")  
  37.             },  
  38.             "success" : function(data) {  
  39.                 data1.loadData(data);  
  40.                 data1.refreshData();  
  41.             },  
  42.             "error" : function(msg) {  
  43.                 justep.Util.hint("获取调查问题失败", {  
  44.                     "type" : "danger"  
  45.                 });  
  46.             }  
  47.         });  
  48.     };  
  49.   
  50.     // 转换动态图片URL  
  51.     Model.prototype.transURL = function(picture, rowID) {  
  52.         if (!picture)  
  53.             return null;  
  54.         var src = null;  
  55.         if (picture !== null && picture !== "" && picture !== "[]") {  
  56.             var imageJson = eval("(" + picture + ")");  
  57.             var realFileName = imageJson[0].realFileName;  
  58.             var storeFileName = imageJson[0].storeFileName;  
  59.             var operateType = "browse";  
  60.             var url = '/baas/justep/attachment/simpleFileStore?realFileName=' + realFileName + '&storeFileName=' + storeFileName + '&ownerID=' + rowID + '&operateType=' + operateType;  
  61.             src = require.toUrl(url);  
  62.         }  
  63.         return src;  
  64.     };  
  65.   
  66.     Model.prototype.setPropReadonly = function(event) {  
  67.         this.comp("button1").set({  
  68.             disabled : true  
  69.         });  
  70.         this.comp("textarea1").set({  
  71.             disabled : true  
  72.         });  
  73.         this.comp("checkboxGroup1").set({  
  74.             disabled : true  
  75.         });  
  76.         this.comp("radioGroup1").set({  
  77.             disabled : true  
  78.         });  
  79.     };  
  80.   
  81.     Model.prototype.getWeixinUser = function(event) {  
  82.         // 获取url上的code参数 - 微信授权code,用于获取微信用户信息  
  83.         var weixinCode = this.getContext().getRequestParameter("code");  
  84.         var self = this;  
  85.         if (weixinCode !== "") {  
  86.             justep.Baas.sendRequest({  
  87.                 "url" : "/riskMonitor/weixin",  
  88.                 "action" : "userinfo",  
  89.                 "async" : false,  
  90.                 "params" : {  
  91.                     code : weixinCode  
  92.                 },  
  93.                 "success" : function(weixinUser) {  
  94.                     self._userID = weixinUser.openid;  
  95.                     self._userNickName = weixinUser.nickname;  
  96.                 },  
  97.                 "error" : function(msg) {  
  98.                     justep.Util.hint("获取用户信息失败", {  
  99.                         "type" : "danger"  
  100.                     });  
  101.                 }  
  102.             });  
  103.         }  
  104.     };  
  105.   
  106.     // 提交问卷  
  107.     Model.prototype.button1Click = function(event) {  
  108.         // 需将参与调查的人员信息插入到survey表中。回答的内容插入到details表中  
  109.         // 提交调查问卷  
  110.         var surveyData = this.comp("surveyData");  
  111.         var detailData = this.comp("detailData");  
  112.         var data1 = this.comp("data1");  
  113.         var self = this;  
  114.         // 插入回答此问卷人的信息  
  115.         var surveyID = justep.UUID.createUUID();  
  116.         var openID = this.getContext().getRequestParameter("openID");  
  117.         var nickName = this.getContext().getRequestParameter("nickName");  
  118.         var surveyType = this.getContext().getRequestParameter("surveyType");  
  119.   
  120.         // 如果openID为空,默认是临时用户  
  121.         if (openID === "") {  
  122.             openID = "temp_" + justep.UUID.createUUID();  
  123.         }  
  124.         if (nickName === "") {  
  125.             nickName = "temp";  
  126.         }  
  127.   
  128.         var surveyRows = surveyData.newData({  
  129.             index : 0,  
  130.             defaultValues : [ {  
  131.                 "fID" : surveyID,  
  132.                 "fPaperID" : this.getContext().getRequestParameter("paperID"),  
  133.                 "fPerID" : openID,  
  134.                 "fPerName" : nickName,  
  135.                 "fSState" : "已完成",  
  136.                 "fFinishTime" : justep.Date.toString(new Date(), justep.Date.STANDART_FORMAT),  
  137.                 "fAddress" : this._userAddress,  
  138.                 "flongitude" : this._longtitude,  
  139.                 "fLatitude" : this._latitude  
  140.             } ]  
  141.         });  
  142.         var detailRows = null;  
  143.         var success = function(resultData) {  
  144.             var tempdefaultValues = [];  
  145.             // 开始插入答卷人答卷答案  
  146.             data1.each(function(param) {  
  147.                 var tempAnswerJson = {  
  148.                     "fID" : justep.UUID.createUUID(),  
  149.                     "fSurveyID" : surveyID,  
  150.                     "fQuestionID" : param.row.val("fID"),  
  151.                     "fAnswer" : param.row.val("fAnswer")  
  152.                 };  
  153.                 tempdefaultValues.push(tempAnswerJson);  
  154.             });  
  155.   
  156.             detailData.newData({  
  157.                 index : 0,  
  158.                 defaultValues : tempdefaultValues,  
  159.             });  
  160.             detailRows = detailData.saveData({  
  161.                 "onSuccess" : function(resultData) {  
  162.                     // justep.Util.hint("交卷成功!");  
  163.                     if (surveyType == "qrcode") {  
  164.                         justep.Util.hint("提交成功!");  
  165.                         if (self.wxApi) {  
  166.                             self.wxApi.exec().done(function(wx) {  
  167.                                 wx.closeWindow();  
  168.                             });  
  169.                         }  
  170.                     } else {  
  171.                         justep.Shell.showPage(require.toUrl("./paper.w?_userID=" + self.getContext().getRequestParameter("openID") + "&_userNickName="  
  172.                                 + self.getContext().getRequestParameter("nickName")));  
  173.                     }  
  174.                 },  
  175.                 "onError" : function(msg) {  
  176.                     detailData.deleteData(detailRows);  
  177.                     justep.Baas.showError(msg);  
  178.                 }  
  179.             });  
  180.   
  181.         };  
  182.         var error = function(msg) {  
  183.             // 保存失败后清除数据  
  184.             surveyData.deleteData(surveyRows);  
  185.             justep.Baas.showError(msg);  
  186.         };  
  187.   
  188.         surveyData.saveData({  
  189.             "onSuccess" : success,  
  190.             "onError" : error  
  191.         });  
  192.         // }, this);  
  193.     };  
  194.   
  195.     Model.prototype.data1IndexChanged = function(event) {  
  196.         var rowID = event.source.getCurrentRowID();  
  197.         var itemsData = this.comp("itemsData");  
  198.         itemsData.setFilter("itemFilter0""fQuestionID = '" + rowID + "'");  
  199.         itemsData.refreshData();  
  200.     };  
  201.   
  202.     // 设置微信标题  
  203.     Model.prototype.modelModelConstruct = function(event) {  
  204.         document.title = this.getContext().getRequestParameter("paperName");  
  205.     };  
  206.   
  207.     Model.prototype.modelLoad = function(event) {  
  208.         if (justep.Browser.isWeChat) {  
  209.             this.wxApi = new navigator.WxApi("wxcc420846eb481632");  
  210.         }  
  211.         // var self = this;  
  212.         // // 获取url上的code参数 - 微信授权code,用于获取微信用户信息  
  213.         // var weixinCode = this.getContext().getRequestParameter("openID");  
  214.         // // 判断运行环境是否在X5移动客户端中,如果在移动客户端中,则当deviceready后取手机设备uuid作为用户唯一标识  
  215.         // if (weixinCode !== "") {  
  216.         // if (justep.Browser.isWeChat) {  
  217.         // self.wxApi = new navigator.WxApi("wxcc420846eb481632");  
  218.         // }  
  219.         // }  
  220.     };  
  221.   
  222.     return Model;  
  223. });  

四、WeX5平台介绍

wex5平台是北京起步公司开发的面向移动应用的开源平台

  • 定位开发面向消费者和公众的开放应用系统