乐趣区

小程序egg后台简要文档

小程序 egg 后台简要文档

更多 blog

如果不需要后端 java 或者其他语言支持,对于小型的小程序后台,可以使用 eggjs 框架快速搭建简要的数据后台。

如果未接触过 node 编写接口,首先还是需要基本过一下 egg 官方文档,至少得把快速入门看完。

不会从头开始把每一步都详细写下来,只针对微信对接的一些处理列出来。

数据库

使用 mongo,示例通过 egg-mongoose 进行连接处理。

安装插件后,在 /config/plugin.js 进行基本配置:

mongoose: {
  enable: true,
  package: 'egg-mongoose'
}

/config/config.default.js 文件中配置 mongodb 的连接(保证本地测试环境数据库连接好):

// connect mongo
  config.mongoose = {
    client: {
      url: 'mongodb://127.0.0.1/fulishe',
      options: {},}
  }

/app/models 文件夹编写相关的 model,在程序运行时会自动在 mongo 上创建对应的表。也可以优先创建好数据库和表设计等。

编写接口

controller 写主要的业务逻辑,接受接口请求参数并返回。
对于入参,需要进行验证的可以做验证处理,需要处理返回结果,即使请求出错也不要返回非 200 的状态码。
可以将处理结果设置为一个函数,如:

// data: 返回给前端的数据,code: 状态,1 为成功,0 为失败,message:状态信息
formatResponse: function (data, code, message) {
  return {
    code,
    data,
    message
  }
}

!> 为避免出现出现问题而导致程序中断,最好在每一个容易出现问题的地方进行 try catch 将异常抛出并返回到前端。

service 编写数据库操作函数等,通过在 controller 进行调用,统一管理数据库数据进出。
注意在数据新增的时候需要进行 save 操作:

const addUser = await this.ctx.model.Users(data)
addUser.save() // 不要遗漏

相关的增删改查操作,需要直接点的可以看仓库 app/service 下的写法。

小程序接口相关

以下是 eggjs 对小程序包括获取 openId、获取 unionId、获取手机号码、判断用户是否关注公众号、客服信息发送进行编写说明。
如果某个对象不知道是什么,一般都是可以根据名字找到对于的 js 文件或者通过 npm 引入,不再表述引入什么了。

获取 openId

参数说明:

  • APPID:小程序的 appId
  • SECRET:小程序的 secret,跟 appId 在同一个地方能找到
  • CODE:小程序在前端通过 wx.login()获取的 jscode
const openIdRes = await rp(`https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${CODE}&grant_type=authorization_code`)
const openId = JSON.parse(openIdRes).openId // 在处理错误判断后,返回的数据是 json 字符串,需要转化

获取 unionId

unionId,属于微信端通用的账号唯一标识,举个例子就是同一个微信号,唯一对应一个 unionId。而在每一个小程序上,用户 openId 都不一样。可以用于判断在小程序上的用户是否关注公众号等。

在第一个获取 openId 的时候,会返回 openId 以及 session_key,通过小程序前端传过来的encryptedData 以及 iv 就可以拿到unionId

参数说明:

  • APPID:小程序的 appId
  • sessionKey:获取 openId 的时候,一并返回了 sessionKey
  • encryptedData:小程序在前端通过获取用户信息返回
  • iv:小程序在前端通过获取用户信息返回
const pc = new WXBizDataCrypt(APPID, sessionKey)
const data = pc.decryptData(encryptedData, iv)
const unionId = data.unionId

获取手机号码

获取手机号码的步骤跟获取 unionId 一样。

只需要注意的是,encryptedDataiv是在小程序端通过 getPhoneNumber 获取。

判断用户是否关注公众号

这里单独在小程序后台无法判断。需要在对于的公众号后台提供一个接口用于判断该 unionId 是否已经关注了公众号。

客服信息发送

在小程序开发设置中配置消息推送。

配置参考:

参数 备注
URL(服务器地址) https://..com/message/check 微信那边与你服务器通信的接口
Token(令牌) isToken 自定义
EncodingAESKey(消息加密密钥) 填写那可以自动生成
消息加密方式 兼容模式 涉及信息安全
数据格式 JSON 一般是这个吧

controller 层编写一个 get 接口,对应 /message/check,用以给微信进行服务器验证。
完整验证函数接口可如下:

async index() {const { ctx} = this
  // 1. 获取微信服务器 Get 请求的参数 signature、timestamp、nonce、echostr
  const {
    signature,
    timestamp,
    nonce,
    echostr
  } = ctx.query

  // 2. 将 token、timestamp、nonce 三个参数进行字典序排序
  let array = ['线上配置的令牌', timestamp, nonce]
  array.sort() // JavaScript sort 函数就是字典序排序的

  // 3. 将三个参数字符串拼接成一个字符串进行 sha1 加密
  const tempStr = array.join('')
  const hashCode = crypto.createHash('sha1') // 创建加密类型
  const resultCode = hashCode.update(tempStr, 'utf8').digest('hex')

  // 4. 开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信
  if (resultCode === signature) {ctx.body = echostr} else {
    // 非微信服务器请求
    ctx.body = format.formatResponse({
      resultCode,
      req: ctx.query
    }, 0, '验证失败 1')
  }
}

自动回复操作:
controller 层编写一个 post 接口,对应 /message/check,用于自动回复。
完整处理自动回复接口:

async handle() {const { ctx} = this
  const {FromUserName, MsgType, Content} = ctx.request.body // 这是从微信转发过来的用户发送的信息参数
  const {openid} = ctx.query
  // 获取 accessToken
  const tokenRes = await rp(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${CONST.appId}&secret=${CONST.secret}`)
  if (!('errcode' in JSON.parse(tokenRes))) {if (MsgType === 'text') {
      const postData = {
        touser: openid,
        msgtype: "link",
        link: {
          title: '链接标题',
          description: '链接描述',
          url: '链接',
          thumb_url: '链接封面图'
        }
      }
      const sendRes = await rp({uri: `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${JSON.parse(tokenRes).access_token}`,
        method: 'post',
        body: postData,
        json: true
      })
    }
  }
  ctx.body = 'success'
}

!> 注意:需要在自动回复的最后返回 success,否则会在聊天窗口看到提示: 该小程序提供的服务出现故障,请稍后再试

退出移动版