找回密码
 骑士注册

QQ登录

微博登录

搜索
❏ 站外平台:

查看: 813|回复: 0
收起左侧

看看“疫苗查询”小程序有温度的代码

[复制链接]
腾讯开源 发表于 2018-07-30 11:20:04 | 显示全部楼层 |阅读模式

近日,一篇《疫苗之王》刷爆了朋友圈,疫苗的安全问题被推到了风口浪尖,腾讯安全反诈骗实验室团队推出了“腾讯安心计划”小程序,方便用户便捷地查询疫苗安全信息。

 

这样一个暖心的小程序是怎样做出来的?

 

“腾讯安心计划”小程序分为三个主要服务:小程序前端、TARS代理服务、TARS后台服务。

 

1. 小程序前端负责接收用户查询请求及反馈结果:

它的页面中实现了一个查询框,并且将查询框内输入的内容组成get请求发往接口URL。

 

1.  // 小程序代码段  

2.  // 疫苗批号查询输入框  

3.  <template>  

4.    <input  

5.      value="{{input}}"  

6.      maxlength="20"  

7.      bindinput="handleInput" />  

8.  </template>  

9.    

10.// 疫苗输入框响应参数  

11.<script>  

12.import wepy from 'wepy'  

13.export default class extends wepy.page {  

14.  data = {  

15.    input: ''  

16.  }  

17.  methods = {  

18.    handleInput(e) {  

19.      const val = e.detail.value  

20.      this.input = val  

21.      this.search()  

22.    },  

23.    async search() {  

24.      // 发送查询请求  

25.      // 发出的请求类似与 xxxx.url.com/queryVaccine?number=123  

26.      const resp = await wepy.request({  

27.        url: 'xxxx.url.com/queryVaccine',  

28.        data: {  

29.          number: this.input  

30.        }  

31.      })  

32.      const {data} = resp.data  

33.    }  

34.  }  

35.}  

36.</script> 

 

2. 代理服务负责解析HTTP请求,并将其转为TARS请求发往后端:

它使用TARS-Node.JS,绑定一个接口URL(如:xxxx.url.com/queryVaccine),通过Node.JS的KOA2框架提供的get方法解析收到的请求,并获得其中的参数,然后直接传参调用后端tars服务的请求接口。

1.  //  Node.js koa2 获取参数代码段  

2.  const Koa = require('koa')  

3.  const router = require('koa-router')()  

4.  const koaBody = require('koa-bodyparser')  

5.  // TARS工具  

6.  const Tars = require('tars_client')  

7.  // 引入TARS文件  

8.  const vaccineProxy = require(‘tars/VaccineObj').App  

9.  const app = new Koa()  

10.  

11.// 监听这个路径的get请求  

12.// 通过批次查询疫苗信息接口  

13.router.get('/queryVaccine', async ctx => {  

14.  // 获取 get参数里面的变量  

15.  // xxxx.url.com/queryVaccine?nunber=123 其中?后的参数可以这样获取  

16.  let {number} = ctx.query  

17.  

18.  try {  

19.    const tars = Tars.stringToProxy(  

20.      vaccineProxy.VaccineObj, 'App.Vaccine.VaccineObj'   

21.    )  

22.    // 调用tars接口,传参  

23.    let result = await tars.QueryVaccine(number)  

24.    // 获取结果体里面的结果信息  

25.    let info = result.response.arguments.vVaccine  

26.  

27.    // 返回信息给前端  

28.    ctx.body = info  

29.  } catch(e) {  

30.    console.log(e)  

31.    ctx.body = 'error'  

32.  }  

33.})  

34.  

35.// 加载路由  

36.app.use(router.routes())  

37.  

38.// 启动服务  

39.app.host = 'localhost'  

40.app.port = 80  

41.const server = app.listen(app.port, app.host, () => {  

42.  console.log('Koa server listening on %s:%d', server.address().address, server.address().port)  

43.}); 


3. 查询服务负责提供查询结果:


它提供了一个查询本地内存的功能,首先定期从DB中捞出疫苗的信息数据,并写入内存,在收到接口请求后,在内存中查询到结果,再把结果返回给主调服务。

1.  //在tars文件中定义结构体  

2.  struct Vaccine  

3.  {  

4.      0 require string vaccine ;  //疫苗名称  

5.      1 require string number ;    //批次  

6.      2 require string company ;  //公司  

7.      3 require string state ;   //状态   

8.  };  

9.    

10.//创建疫苗信息vector vVaccine,并从数据库加载相关内容至结构体  

11.TC_Mysql::MysqlData oResults;  

12.try  

13.{  

14.    oResults = mysql.queryRecord("select vaccine,number,company,state from vaccine;");  

15.}  

16.catch (exception & e)  

17.{  

18.    LOG->error() << "VaccineData error query: " << e.what() << endl;  

19.    return -1;  

20.}  

21.const size_t oResultsCnt = oResults.size();  

22.  

23.vVaccine.clear();  

24.for (size_t i=0; i<oResultsCnt; i++)  

25.{  

26.    App::Vaccine stInfo;  

27.    stInfo.vaccine=oResults[i]["vaccine"];  

28.    stInfo.number=ToUpperCaseString(oResults[i]["number"]); //批次号统一归一化为大写  

29.    stInfo.company=oResults[i]["company"];  

30.    stInfo.state=oResults[i]["state"];  

31.  

32.    vVaccine.push_back(stInfo);  

33.}  

34.  

35.//在VaccineObjImp.cpp中定义queryVaccine接口  

36.tars::Int32 VaccineObjImp::QueryVaccine(const std::string & strIn,vector<App::Vaccine> &vVaccine,tars::TarsCurrentPtr current)  

37.{  

38.    CAttrReport::getInstance()->AttrReportCount("QueryVaccine");  

39.    LOG->debug()<<"QueryVaccine"<<endl;  

40.    //调用实际请求函数  

41.    int ret=QueryVaccine(strIn,vVaccine);  

42.    return ret;  

43.}  

44.  

45.//实际请求函数QureyVaccine函数定义  

46.int QueryVaccine(const std::string & strIn,vector<App::Vaccine> & vMatchVaccine)  

47.{  

48.    if(strIn.length()<3)  

49.    {  

50.        return -1;  

51.    }  

52.  

53.    int size_cnt=0;  

54.  

55.    const size_t cnt=VaccineHandle::getInstance()->vVaccine.size();  

56.    for(size_t i=0;i<cnt;i++)  

57.    {  

58.        if(size_cnt > SConfig::getInstance()->maxMatch)  

59.            break;  

60.  

61.        if(isNumberMatch(strIn,VaccineInfoHandle::getInstance()->vVaccineInfo[i].number))//模糊批号匹配  

62.        {  

63.            //将查询到的内容push进查询结果vector  

64.            vNumberVaccine.push_back(VaccineHandle::getInstance()->vVaccine[i]);  

65.            size_cnt++;  

66.        }  

67.    }  

68.    return 0;  

69.}  

 

这样,一个具备查询后台数据功能的小程序就完成了。

 

小程序的便捷开发与部署,不同于APP的版本管理,可以快速更新页面内容而用户无感知。TARS的多语言支持以及高可用,可以通过多种方案及手段高效实现自己的需求,同时不需要将过多的精力放在服务的容灾容错处理上。

 

单纯从代码开发效率来看,小程序+TARS这样的实现组合,可以在只有一个前端+一个后端开发者,或者一个全栈开发者的情况下,在一天之内就可以高效便捷地实现一个与“腾讯安心计划”功能类似的小程序了。

 

如果优秀的您对代码有不一样的想法,欢迎留言评论。

TARS开源地址:https://github.com/Tencent/Tars

您需要登录后才可以回帖 登录

本版积分规则

快速回复 返回顶部 返回列表

分享到微信

打开微信,点击顶部的“╋”,
使用“扫一扫”将网页分享至微信。