www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

Wechat小程序完成pdf

2020-01-18 06:54 来源:未知

时间: 2019-09-07阅读: 445标签: 文件

笔者前端渣渣黄金年代枚,那篇小说是第贰回写,要是有硬核bug,请大佬们轻喷、提议... 别的,本文不关乎任何接口安全、参数校验之类的事物,暗许对调用方无脑级的信任:joy: 近日自用的接口蕴涵但不压迫以下这几个

当前Wechat只援助从谈天记录里面获取文件

|--- 微信相关| |--- 0. 处理微信推过来的一些消息| |--- 1. 获取微信SDK配置参数| |--- 2. 微信鉴权登陆| |--- 3. 获取微信用户信息| |--- 4. 获取AccessToken| |--- 5. 批量发送模版消息| |--- 6. 获取模版消息列表| |--- 7. 批量发送客服消息

一.前言

小品种超多很杂,何况好些个供给都以依据Wechat支付的,每一遍都查Wechat文档的话就能够很郁闷:unamused:... 公众号超多,项目中临时会涉及借权获取客户音讯(在不绑定Wechat开放平台的前提下,供给权且自行建造各类大伙儿号的openid关联关系卡塔尔(قطر‎,相像那样相同的时候需求持续三个民众号协作来完毕生机勃勃件事的必要,就便于把人整懵逼... 微信支付的商行号也比很多,而且一时支付须要用的商贾号,还不能够用关联的公众号收取来的openid去支付... Wechat官方文档提出!把得到AccessToken等WechatAPI抽离成独立的服务... 等等等等........所以...:joy:

眼下Wechat提供了二个接口wx.chooseMessageFile它能让顾客从闲聊记录里面采取一个也许四个文件,然后再次回到它的部分音讯,列入文件的path地址,文件名,文件的尺寸等.

创建ThinkJS项目

获得那些音讯再结合Wechat的上传接口wx.uploadFile,就可以完成公文上传.

官网

二.现实落实

thinkjs.org/

先是供给叁个按键来调用wx.chooseMessageFile.

简介

wx.chooseMessageFile({ count: 1, //能选择文件的数量 type: 'file', //能选择文件的类型,我这里只允许上传文件.还有视频,图片,或者都可以 success(res) { var size = res.tempFiles[0].size; var filename = res.tempFiles[0].filename; var newfilename = filename   ""; if (size  4194304||newfilename.indexOf(".pdf")==-1){ //我还限制了文件的大小和具体文件类型 wx.showToast({ title: '文件大小不能超过4MB,格式必须为pdf!', icon: "none", duration: 2000, mask: true }) }else{ that.setData({ path: res.tempFiles[0].path, //将文件的路径保存在页面的变量上,方便 wx.uploadFile调用 filename: filename //渲染到wxml方便用户知道自己选择了什么文件 }) } }})

ThinkJS 是风流倜傥款面向今后开拓的 Node.js 框架,整合了大批量的品种最棒实行,让厂商级开垦变得那般归纳、高效。从 3.0 初叶,框架底层基于 Koa 2.x 达成,包容 Koa 的保有机能。

诸如此比在这间就封存了文本的路径和称号

设置脚手架

data: { path:'', filename:''},
$ npm install -g think-cli

下一场等顾客张开提交的时候,再调用上传的接口

创立及运转项目

wx.uploadFile({url: serverUrl //上传的路径filePath: that.data.path, //刚刚在data保存的文件路径name: 'file', //后台获取的凭据success() {wx.showToast({ //做个提示或者别的操作title: '',icon: "none",duration: 5000,mask: true,success: function(res) {}})}})
$ thinkjs new demo;$ cd demo;$ npm install; $ npm start; 

与此相类似前段就水到渠成完结了,后台获取的文书是五个.tmp结尾的不常文件,然后就能够透过IO流将文件保留到您想保留的职责上去,就足以了.

目录布局

|--- development.js //开发环境下的入口文件|--- nginx.conf //nginx 配置文件|--- package.json|--- pm2.json //pm2 配置文件|--- production.js //生产环境下的入口文件|--- README.md|--- src| |--- bootstrap //启动自动执行目录 | | |--- master.js //Master 进程下自动执行| | |--- worker.js //Worker 进程下自动执行| |--- config //配置文件目录| | |--- adapter.js // adapter 配置文件 | | |--- config.js // 默认配置文件 | | |--- config.production.js //生产环境下的默认配置文件,和 config.js 合并 | | |--- extend.js //extend 配置文件 | | |--- middleware.js //middleware 配置文件 | | |--- router.js //自定义路由配置文件| |--- controller //控制器目录 | | |--- base.js| | |--- index.js| |--- logic //logic 目录| | |--- index.js| |--- model //模型目录| | |--- index.js|--- view //模板目录| |--- index_index.html

安装think-wechat插件

介绍

Wechat中间件,基于 node-webot/wechat,扶助 thinkJS 3.0

安装

$ npm install think-wechat --save

$ cnpm install think-wechat --save

配置

文件:/src/config/middleware.js

const wechat = requiremodule.exports = [ ... { handle: wechat, match: '/index', options: { token: '', // 令牌,和公众号/基本配置/服务器配置里面写一样的即可 appid: '', // 这里貌似可以随便填,因为我们后面要用数据库配置多个公众号 encodingAESKey: '', checkSignature: false } }, { handle: 'payload', // think-wechat 必须要在 payload 中间件前面加载,它会代替 payload 处理微信发过来的 post 请求中的数据。 options: { keepExtensions: true, limit: '5mb' } },]

注:match下自身这边写的是 /index ,对应的品类文件是 /src/controller/index.js ,对应的群众号后台所需安顿的服务器地址正是 http://域名:端口/index

创设数据库和血脉相仿表

小编那边创办了多个Wechat的相关表。

配置表:wx_config

字段

类型

说明

id int 主键 name varchar 名称 appid varchar appid secret varchar secret

用户表:wx_userinfo

字段

类型

注释

id int 主键 subscribe int 客户是不是订阅该民众号标记,值为0时,代表此顾客并未有青睐该公众号,拉取不到其它音讯。 nickname varchar 顾客的别名 sex int 客户的性别,值为1时是男子,值为2时是女人,值为0时是不解 language varchar 客商所在省份 city varchar 客户所在城市 province varchar 客户所在省份 country varchar 顾客所在国家 headimgurl longtext 客商头像,最终一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640圆柱形头像),客户并未有头像时该项为空。若顾客更动头像,原有头像U揽胜极光L将失效。 subscribe_time double 客商关注时间,为时间戳。假若客户曾数次关切,则取最终关心时间 unionid varchar 独有在客商将大众号绑定到Wechat开放平台帐号后,才会现身该字段。 openid varchar 顾客的标记,对近年来大伙儿号唯大器晚成 wx_config_id int 对应配置的Wechat号id

模版新闻日志表:wx_template_log

字段

类型

注释

id int 主键 template_id varchar 模版id openid varchar 顾客的标记,对当下民众号唯风流洒脱 url varchar 跳转url miniprogram varchar 跳转小程序 data varchar 发送内容json字符串 add_time double 增加大运戳 send_time double 发送时间戳 send_status varchar 发送结果 wx_config_id double 对应配置的Wechat号id uuid varchar 此番发送的uuid,业务系统可透过uuid查询模版音讯推送结果

管理Wechat推送音信

/src/controller/index.js

module.exports = class extends think.Controller { /* * 入口:验证开发者服务器 * 验证开发者服务器,这里只是演示,所以没做签名校验,实际上应该要根据微信要求进行签名校验 */ async indexAction() { let that = this; if (that.method != 'REPLY') { return that.json({code: 1, msg: '非法请求', data: null}) } const {echostr} = that.get(); return that.end; } /* * 文字 * 用于处理微信推过来的文字消息 */ async textAction() { let that = this; let {id, signature, timestamp, nonce, openid} = that.get(); let {ToUserName, FromUserName, CreateTime, MsgType, Content, MsgId} = that.post(); ..... that.success } /* * 事件 * 用于处理微信推过来的事件消息,例如点击菜单等 */ async eventAction() { let that = this; let {id, signature, timestamp, nonce, openid} = that.get(); let {ToUserName, FromUserName, CreateTime, MsgType, Event, EventKey, Ticket, Latitude, Longitude, Precision} = that.post { case 'subscribe': // 关注公众号 ... break; case 'unsubscribe': // 取消关注公众号 ... break; case 'SCAN': // 已关注扫码 ... break; case 'LOCATION': // 地理位置 ... break; case 'CLICK': // 自定义菜菜单 ... break; case 'VIEW': // 跳转 ... break; case 'TEMPLATESENDJOBFINISH':// 模版消息发送完毕 ... break; } that.success }}

注:支持的action包括: textActionimageActionvoiceActionvideoActionshortvideoActionlocationActionlinkActioneventActiondeviceTextActiondeviceEventActionWeb前端, 。

公众号后台配置

注:前边跟的id参数是为着差距是哪些公众号推过来的消息,在地方的接口参数中也可能有呈现

Wechat相关API的编写

目录结构

|--- src| |--- controller //控制器目录 | | |--- index.js // 处理微信推送的消息,上面有写到| | |--- common.js // 一些公共方法| | |--- open // 开放给其他业务服务的api接口| | | |--- wx.js| | |--- private // 放一些内部调用的方法,调用微信api的方法主要在这里面| | | |--- wx.js

以此目录构造也许不太合理,中期再更改吧:grin:

公共措施

// src/controller/common.jsimport axios from 'axios'import {baseSql} from "./unit";module.exports = class extends think.Controller { // 获取appinfo async getWxConfigById { let that = this; let data = await that.cache(`wx_config:wxid_${id}`, async () => { // 数据库内取 let info = await that.model.where; if  { return info } }) return data || {} } // 获取access_token async getAccessToken { let that = this; let accessToken = await that.cache(`wx_access_token:wxid_${id}`, async () => { let {appid, secret} = await that.getWxConfigById; let {data} = await axios({ method: 'get', url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}` }); return data.access_token }); return accessToken }}

接口过滤器

具备开放出来的接口的放到方法,俗称过滤器?全体开放的接口必传get参数是 wxid ,对应数据库表wx_config里面 id

// src/controller/open/wx.jsasync __before() { let that = this; let wxid = that.get; if  { return that.json({code: 1, msg: 'wxid不存在'}) } that.wxConfig = await that.controller.getWxConfigById; if (think.isEmpty { return that.json({code: 1, msg: 'wxid不存在'}) }}

接口 - 获取AccessToken

// src/controller/open/wx.jsasync get_access_tokenAction() { let that = this; let accessToken = await that.controller.getAccessToken; return that.json({code: 0, msg: '', data: {access_token: accessToken}})}

接口 - 获取Wechatsdk的config

// src/controller/open/wx.jsasync get_wxsdk_configAction() { let that = this; let {url} = that.get(); if  { return that.json({code: 1, msg: '参数不正确'}) } let sdkConfig = await that.controller.getSdkConfig(that.wxConfig.id, url); return that.json({code: 0, msg: '', data: sdkConfig})}// src/controller/private/wx.jsconst sha1 = require;const getTimestamp = () => parseIntconst getNonceStr = .toStringconst getSignature =  => sha1.sort().map(key => `${key.toLowerCase.join;async getSdkConfig { let that = this; let {appid} = await that.controller.getWxConfigById; let shareConfig = { nonceStr: getNonceStr(), jsapi_ticket: await that.getJsapiTicket, timestamp: getTimestamp(), url: url } return { appId: appid, timestamp: shareConfig.timestamp, nonceStr: shareConfig.nonceStr, signature: getSignature }}

接口 - 获取UserInfo

// src/controller/open/wx.jsasync get_userinfoAction() { let that = this; let {openid} = that.get(); if ) { return that.json({code: 1, msg: '参数不正确'}) } let userInfo = await that.controller.getUserInfo(that.wxConfig.id, openid); if (think.isEmpty { return that.json({code: 1, msg: 'openid不存在', data: null}) } return that.json({code: 0, msg: '', data: userInfo})}// src/controller/private/wx.jsasync getUserInfo { let that = this; let userInfo = await that.cache(`wx_userinfo:wxid_${id}:${openid}`, async () => { //先取数据库 let model = that.model('wx_userinfo', baseSql); let userInfo = await model.where({wx_config_id: id, openid: openid}).find(); if (!think.isEmpty && userInfo.subscribe == 1 && userInfo.unionid != null) { return userInfo } //如果数据库内没有,取新的存入数据库 let accessToken = await that.controller.getAccessToken; let url = `https://api.weixin.qq.com/cgi-bin/user/info?access_token=${accessToken}&openid=${openid}&lang=zh_CN`; let {data} = await axios({method: 'get', url: url}); if  { //命中修改,没有命中添加 let resId = await model.thenUpdate( Object.assign(data, {wx_config_id: id}), {openid: openid, wx_config_id: id}); return await model.where; } }) return userInfo}

接口 - 批量发送文字客性格很顽强在艰难险阻或巨大压力面前不屈音讯

// src/controller/open/wx.jsasync send_msg_textAction() { let that = this; let {list} = that.post(); if  { return that.json({code: 1, msg: '参数不正确'}) } that._sendMsgTextList(that.wxConfig.id, list); return that.json({code: 0, msg: '', data: null}) } async _sendMsgTextList { let that = this; let apiWxController = that.controller; for  { let data = await apiWxController.sendMsgText(wxid, item.openid, item.text) }}// src/controller/private/wx.jsasync sendMsgText { let that = this; let accessToken = await that.controller.getAccessToken; let url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${accessToken}` let {data} = await axios({ method: 'post', url: url, data: {"msgtype": 'text', "touser": openid, "text": {"content": content}} }) return data;}

写在结尾

骨子里还会有众多接口,这里就不全体列出来了。

有道是能看出来,在这里个类型里面并不仅是把Wechat的接口做了个轻易的转变,而是有后生可畏对温馨的拍卖逻辑在中间。

诸如获取微信客户消息的时候,会先推断缓存里有未有,若无就取数据库,假若还并未再去Wechat的接口取;要是数据库有,何况关怀字段是未关切的话,照旧会调用微信的接口取一波再修改。 反正一天内,Wechat接口的调用次数是纯属够用的。

再举个例子批量发送模版新闻,中央控制伏务在抽出央求后会先创设三个uuid,要发的模板新闻全体封存到数据库内,直接把uuid返给调用方。 然后中央调节会异步用uuid收取来那批模版信息,一个三个发,三个二个更新结果。 那样在作业方调用发送模版音讯之后,不要求等待全体发送完毕,就足以用得到的uuid,去中央调节查询本次批量出殡和下葬的状态结果。

现阶段是绑了七几个民众号,在没烧过香的前提下,尚未出过怎么样难点

如上就是本文的全部内容,希望对大家的读书抱有利于,也愿意大家多多点拨脚本之家。

TAG标签:
版权声明:本文由澳门新葡8455手机版发布于Web前端,转载请注明出处:Wechat小程序完成pdf