当前位置: 首页 > 后端技术 > Node.js

基于小程序·云开发打造高考查分小程序丨实战

时间:2023-04-03 11:40:46 Node.js

2019年高考报名人数再创新高1031万人。作为三年前高考的准程序员,他加班加点,从零开始,做了一个高考查分的小程序,算是一个高考的礼物老学长对年幼的学生。上线仅一个月,用户量就突破1k。小程序的介绍就不多说了。可以搜索【历年高考成绩查询】的经验。今天主要讲一下技术原理和实现细节。数据源小程序后台收集了近30万条数据,包括2008-2017年所有重点高校文理科各批次录取分数线,以及所有新课标卷、新课标卷、新课标2008年到2018年的课程标准,三卷,部分独立命题省份从提前批到高职批的录取分数线,勉强称得上详细。所有数据均来自各高校及高考相关网站。由于数据量巨大,为了提高速度,使用concurrent.futures(需要Python3.5+)模块中的ThreadPoolExecutor构建线程池,实现多个任务并发执行。数据库采用号称全球最强大的开源数据库产品PgSQL。所有数据都存储在新建的高考数据库中。下面有两个表,university(大学录取分数线)和province(省批次中专行)大学表描述字段解释name学院名称stu_loc学生出身stu_wl文理pc录取batchyearyearscoreaverageadmission省表描述字段解释yearyearstu_loc候选位置stu_wlartsandsciencepcbatchcontrolminimumcontrol本批上线数据量30w,多站点,并发爬取,数据冲突在所难免。在插入之前,先过滤掉不完整的数据。该条记录应该丢弃,最严重的是数据重复,我采用的解决方案是:首先检查要插入的数据是否已经存在,大学表的主键是(name,stu,stu_wl,pc,year),因为reality约束,一个学院一年内只能有一个类别,一批的录取平均分,如果不存在,则进行最后的insert,提交transaction。后台搭建好30万条数据后,我打算采用Flask+PgSQL的模式来实现后台,甚至在后台部署到阿里云服务器上。麻烦大了,因为小程序需要在线运行,无法通过ip地址访问后台,必须通过注册的域名访问。买域名不麻烦,但是域名注册很费时间,要一个多星期,那个时候离高考也不远了5天,当时我手足无措,无意中看到了小程序的云开发。关于小程序的云开发,官网上的介绍是:开发者无需搭建服务器即可使用云开发开发微信小程序和游戏。云能力。云开发为开发者提供完整的原生云支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的API进行核心业务开发,可实现快速启动和迭代。,与开发人员已经使用的云服务兼容,并且不相互排斥。也就是说只要将数据导入到小程序后台,就可以通过小程序平台的API访问数据。之前了解过第三方的LeanCloud云和炸弹云,没想到现在小程序也集成了这些功能。不得不佩服腾讯。也就是说接下来的后台工作主要是导入数据,查询小程序后台可知后台支持导入json或csv格式的数据。于是写了一个脚本将本地数据库的数据导出到json文件:importpsycopg2importjson#connectpgsql数据库,保证隐私,密码隐藏conn=psycopg2.connect(database="gaokao",user="postgres",password="********",host="127.0.0.1",port="5432")cur=conn.cursor()cur.execute('selectstu_loc,year,stu_wl,pc,controlfromprovince')result=[]query_res=cur.fetchall()foriinquery_res:item={}item['stu_loc']=i[0]item['year']=i[1]item['wl']=i[2]item['pc']=i[3]item['score']=i[4]result.append(item)#indent=2控制json格式的缩进#ensure_ascii控件中文正常显示withopen("province.json",'w',encoding="utf-8")asf:f.write(json.dumps(result,indent=2,ensure_ascii=False))还有一个这里需要说明一下,小程序后台需要的json格式和我们通常意义上的json格式有点区别。首先,[和]不能包含json的所有内容,{}包含的每个数据项之间不能有逗号。用notepad++打开原来的json文件,用replace功能解决问题。将[和]替换为空格,并将}替换为}。修改后,通过在小程序后台导入json文件,后台搭建基本完成。小程序的编写关于小程序的编写,主要说说两点经验。首先是页面的编写,比如下面的界面。一开始我也想实现这样的效果,但是完全没有想法。最后,我从自定义模态弹窗中得到了启发。最开始的地方高校下拉框对应的布局是隐藏的,通过wxml文件中的hidden=true来控制,只要你点击地区/大学下拉框,将隐藏设置为false。如果其他下拉框对应的布局的hidden属性为false,则将这些布局的hidden属性设置为true即可隐藏其他布局。当然这里的true或false需要在js中通过setData()动态修改,修改后的数据从数据层渲染到视图层。二是关于小程序云开发的原生bug。查询后台时,一次最多只能查询20条数据。要一次性得到所有的匹配结果,需要解决两个问题。第一个问题自然而然。第一次找到20条数据后,第二次跳过前20条取20条,第三次跳过前40条取20条,以此类推;还有一个比较致命的问题,查询后台API获取结果的回调函数是异步的,也就是说为了保证获取到完整的数据,需要在回调函数中写第二次查询第一次查询,第三次查询需要写在第二次查询的回调中,而且还不能明确知道查询了多少次,这样的嵌套要写多少层,变量的烦人问题同名覆盖,这就是所谓的异步地狱。为了解决这个问题,我们需要编写代码将这种异步方法转换为同步方法。具体方法是:首先在需要添加功能的js页面导入runtime.js文件,并将runtime.js文件放入对应文件夹;constregeneratorRuntime=require("../runtime");runtime.js下载地址:https://github.com/inspurer/CampusPunchcard/blob/master/runtime.js并模仿如下代码完成业务逻辑://查询可能比较慢,最好加上加载动画wx.showLoading({title:'Loading',})constcountResult=awaitdb.collection('province').where({stu_loc:name,pc:pici,}).count()consttotal=countResult.total//需要分几次计算constbatchTimes=Math.ceil(total/MAX_LIMIT)//承载所有读操作的promises数组//得到promise的小数第一个循环数组中的云数据库for(leti=0;i