2019高考报名人数达到了 1031 万的新高,作为一名三年前参考高考的准程序猿,赶在高考前,加班加点从零开始做了一款高考查分小程序,算是一名老学长送给学弟学妹们的高考礼。上线仅 1 个月,用户数就突破了 1k,关于小程序的介绍就不多说了,可以去搜【历年高考分数线查询】体验,今天主要谈谈技术原理和实现细节。

数据来源

小程序后台共收录近 30w 条数据,包含 2008-2017 年所有重点高校的各个批次的文理分科录取分数线以及 2008-2018 所有采用新课标一卷、新课标二卷、新课标三卷以及部分自主命题省份的从提前批到高职专科批的录取分数线,勉强称得上内容翔实。

所有数据均采集自各大院校和各高考相关网站,由于数据量巨大,为提高速度,使用了 concurrent.futures (需要 Python3.5+) 模块里的 ThreadPoolExecutor 来构建线程池来并发执行多任务。

数据库采用的是 PgSQL,一款号称世界上最强大的开源数据库产品,所有数据均存在新建的 gaokao 数据库中,其下有两个表,university(院校的录取分)和 province(省份的批次线)

university 表说明

字段 解释
name 院校名称
stu_loc 生源地
stu_wl 文理科
pc 录取批次
year 年份
score 录取平均分

province 表说明

字段 解释
year 年份
stu_loc 考生所在地
stu_wl 文理科
pc 批次
control 本批次最低控制线

30w 的数据量,多个站点,并发爬取,数据冲突是不可避免地,在执行插入之前,首先过滤掉残缺不全的数据,比如在插入 university 表时某条数据缺少 pc 字段,那么这条记录就应该被舍弃,最严重的是数据重复,我采用的解决办法是:先查询待插入的数据是否已经存在, university 表的主码是(name,stu,stu_wl,pc,year),因为现实约束一个院校只能在一个年份在一个类别一个批次只能有一个录取平均分,如果不存在,才执行最后的插入,并 commit 提交事务。

后台搭建

在 30w 条数据拿到后,我打算后台采用 Flask+PgSQL 的模式实现,甚至在后台在阿里云服务器部署好,小程序端在开发者工具联调通过之后,小程序上线遇到到一个大麻烦,因为小程序要求线上运行不能通过 ip 地址访问后台,必须通过备案的域名访问,域名购买一个倒不麻烦,只是域名备案比较耗时间,需要一周多时间,而当时距离高考也就不到 5 天,在手足无措之时,无意间看到小程序云开发,关于小程序云开发,官网的介绍是:

开发者可以使用云开发开发微信小程序、小游戏,无需搭建服务器,即可使用云端能力。

云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。

也就是说,只要把数据导入小程序自带的后台,就能通过小程序平台的 API 访问到这些数据,以前了解过第三方的 LeanCloud云 和 Bomb 云,没想到小程序现在集成了这些功能,不得不佩服一下腾讯。

也就是,接下来的后台的工作是主要是导入数据,查询小程序后台可知,后台支持导入 json 或者 csv 格式的数据。于是我就写了个脚本,把数据从本地数据库导出到 json 文件中:

import psycopg2
import json# 连接 pgsql 数据库,为保证隐私,密码已隐藏
conn = psycopg2.connect(database="gaokao", user="postgres", password="*******", host="127.0.0.1", port="5432")
cur = conn.cursor()cur.execute('select stu_loc,year,stu_wl,pc,control from province')
result = []
query_res = cur.fetchall()
for i in query_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 控制中文的正常显示
with open("province.json", 'w', encoding="utf-8") as f:f.write(json.dumps(result, indent=2, ensure_ascii=False))

这里还有有个坑需要说明一下,小程序后台要求的 json 格式和我们平常意义上的 json 格式还有点区别,首先,json 的所有内容不能被 [ 和 ] 包括起来,而且每个被 {} 所包括得数据项之间不能有逗号。

选用 notepad++ 打开原来的 json 文件,使用替换功能就能解决,把 [ 和 ] 替换成空格,把 },替换成 } 即可。

修改之后,在小程序后台通过导入该 json 文件,后台搭建就基本完成了。

小程序端编写

关于小程序端的编写,我主要谈谈两点经验,第一是页面的编写,比如下面这个界面。

最开始想实现这样的效果,完全没有思路,最后在从自定义模态弹窗那得到了思路,一开始地区院校这个下拉框对应的布局是隐藏的,在 wxml 文件中通过 hidden=true 控制,一点击 地区/院校 下拉框,就把 hidden 置为 false,如果开始有其他下拉框对应的布局的 hidden 属性是 false 的话,同时要把这些布局的 hidden 属性置为 true 来隐藏其他布局,当然,这里的 true or false 需要在 js 里通过 setData() 动态修改,把修改后的数据从数据层渲染到视图层。

第二是关于小程序云开发的原生 Bug,查询后台时一次只能最多查询到 20 条数据,要实现一次得到所有匹配的结果,需要解决两个问题,第一个问题很自然而然就能想到,第一次查到 20 条数据后,第二次跳过前 20 条再取 20 条,第三次跳过前 40 条再取 20 条,以此类推;还有一个更为致命的问题,查询后台的 API 获取结果的回调函数的 异步 的,也就是说,为了保证获得完整数据,第二次查询需要写在第一次查询的回调里,第三次查询需要写在第二次查询的回调里,而且你还不能显式地知道要查询多少次,需要写多少层这样的嵌套,以及烦人的同名变量覆盖问题,这就是所谓的 异步地狱。为了解决这个问题,需要我们编写代码把这个异步方法转成同步的,具体做法是:

先在所要添加功能的js页面中导入 runtime.js 文件,同时把runtime.js文件放入相应文件夹

const regeneratorRuntime = require("../runtime");

runtime.js 下载地址:https://github.com/inspurer/CampusPunchcard/blob/master/runtime.js

同时模仿下例代码完成业务逻辑:

// 查询可能较慢,最好加入加载动画​
wx.showLoading({title: '加载中',})const countResult = await db.collection('province').where({stu_loc: name,pc: pici,}).count()const total = countResult.total//计算需分几次取const batchTimes = Math.ceil(total / MAX_LIMIT)// 承载所有读操作的 promise 的数组//初次循环获取云端数据库的分次数的promise数组for (let i = 0; i < batchTimes; i++) {const promise = await db.collection('province').where({stu_loc: name,pc: pici,}).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()//二次循环根据​获取的promise数组的数据长度获取全部数据push到newResult数组中for (let j = 0; j < promise.data.length; j++) {var item = {};item.code = i * MAX_LIMIT + j;item.name = promise.data[j].stu_loc;item.year = promise.data[j].year;item.wl = promise.data[j].wl;item.pc = promise.data[j].pc;item.score = promise.data[j].score;console.table(promise.data)newResult.push(item)}}if (newResult.length != 0) {that.setData({hasdataFlag: true,resultData: newResult})} else {that.setData({hasdataFlag: false,resultData: newResult})}// 隐藏加载动画wx.hideLoading()

以上就是我本次开发的一些心得体会,欢迎批评指正。

课程完整源码

https://github.com/TencentCloudBase/Good-practice-tutorial-recommended

联系我们

更多云开发使用技巧及 Serverless 行业动态,扫码关注我们~

转载于:https://www.cnblogs.com/CloudBase/p/11475427.html

基于小程序·云开发构建高考查分小程序丨实战相关推荐

  1. 基于微信小程序云开发的医院体检预约小程序源码,医院体检预约小程序源码,实现体检预约管理、体检预约凭证、预约数据查看导出 版权申诉

    功能介绍 对于医院体检科室和体检机构而言,每天的体检人数分布也不太均衡,若很多人集中在 某些天体检,会出现「医生强度大.体检人排队久」的问题.采用体检预约小程序进行体检预约数管理,体检人可预约到更广的 ...

  2. 基于微信小程序云开发实现考研题库小程序项目(完整版)

    今天手把手的带大家实现一款答题类的题库小程序,如果着急的话,可以直接去看文末源码.下载与项目部署. 考研题库小程序云开发实战,完整版提供给大家学习.题库小程序,基于云开发的微信答题小程序,软件架构是微 ...

  3. “小程序 · 云开发”重磅上线,让小程序开发更高效!

    近日,"小程序 · 云开发"解决方案正式上线,该方案可以为小程序开发者提供完整的云端支持. 通过简化复杂的后端和运维操作,让即便不具备一定后端知识的开发者,也能高效开发出一款高质量 ...

  4. 小程序云开发_借助小程序云开发制作校园导览小程序丨实战

    导语 偌大校园,寻路犯难.没关系!本文教你借助云开发制作精美校园导览小程序,带你走遍校园的每个角落,发现不一样的风景. 背景 刚入学的新生要想不迷失在偌大的校园,除了依靠不怎么可靠的路边标识外,总会收 ...

  5. 借助云开发轻松实现后台数据批量导出丨实战

    小程序导出数据到excel表,借助云开发后台实现excel数据的保存 我们在开发小程序的过程中,可能会有这样的需求:如何将云数据库里的数据批量导出到excel表里? 这个需求可以用强大的云开发轻松实现 ...

  6. 借助小程序·云开发制作校园导览小程序丨实战

    背景 当你刚上大学的时候,要想不迷失校园,除了依靠不怎么可靠的路边标识外,总会收到那么一张卡通绘制的校园地图: 这种静态图片可以让我们快速地了解到所需的地理位置信息,但使用和思考过后,会发现以下问题: ...

  7. 小程序·云开发 - 仿瑞幸咖啡小程序(一) - 从入门到辞职

    最近新开一个瑞幸咖啡小程序的项目.刚好看到小程序有新的功能 - 云开发,就开始边做边学了. 首先,开启一个新的项目的时候,勾选云开发. 新建完项目之后,小程序就可以进行云开发服务了. 需要注意的是,新 ...

  8. 简化后端:一篇带你走进云开发及小程序云开发的世界

    目录 前言 小程序是什么 什么是小程序的云开发 目前国内云开发相对较成熟的云计算技术 1.阿里云 2.腾讯云 3.百度云 4.天翼云 5.金山云 6.Ucloud 7.华为云等公司 云开发与传统开发的 ...

  9. 解密小程序云开发数据库

    作者:phoenixxliu,腾讯 TEG 后台开发工程师 目录: 导语 一.背景 二.竞品分析 三.需求和挑战 四.架构和方案 五.总结和展望 导语 小程序云开发(Tencent CloudBase ...

最新文章

  1. 使用 C#/.NET Core 实现单体设计模式
  2. bitand( ) 函数用法
  3. KVM虚拟机相关步骤
  4. 对MySQL性能影响关系紧密的五大配置参数
  5. 剑指Offer05. 替换空格
  6. California Fault Lines: Understanding the Causes and Impact of Network Failures
  7. git 撤销挂起的更改_小姐姐带你用Git
  8. 一款不错的千神阁导航网模板V1.5
  9. jmeter解决不同线程组之间传递参数问题
  10. 无法读取方案文档 ‘http://www.springframework.org/schema/beans/spring-beans-4.1.xsd‘问题解决
  11. 2018-09-14
  12. windows命令行设置和系统快捷键
  13. 趣味计算机课堂示范课,枯燥的理工学科,秒变趣味课堂
  14. 劳务派遣计算机信息管理系统,劳务派遣人员信息管理系统
  15. C++ 11,智能指针(整理总结)3
  16. html5语音听写流式,iOS 讯飞语音听写(流式版)
  17. Python实现Flesch阅读易读性公式计算
  18. Machine Learning with Graphs 之 Random Walk with Restarts and Personalized PageRank
  19. AP Memory IoT RAM——嵌入式物联网最佳存储解决方案
  20. MTK平台驱动调试的资料

热门文章

  1. html:(30):继承和特殊性
  2. mysql中 课程1比课程2成绩高_小菜菜mysql练习解读分析1——查询 01 课程比 02 课程成绩高的学生的信息及课程分数...
  3. warning.js:7 Warning: [antdv: Table] Each record in dataSource of table should have a unique `key`
  4. mint-ui 写一个下拉滑动选择,mt-popup和mt-picker结合使用
  5. 巨蟒python全栈开发flask5
  6. vue之watch用法
  7. 清除Pycharm设置的方法
  8. unity中发布android时候出现这样的提示错误:error:device not found
  9. Schema evolution in Avro, Protocol Buffers and Thrift
  10. c#完美截断字符串(中文+非中文)