Index
介绍
大家在做移动端应用开发的时候都会不满足于APP客户端,小程序的应用也越来越广泛了。
现在我们开发了一套kintone在微信小程序上的SDK。基于这个SDK大家就可以做适用于自己的微信小程序了。
SDK做了些什么
这里不得不提到kintone的JS Client (@kintone/rest-api-client),既可以支持Commonjs规范服务端nodejs开发,也可以支持AMD规范的浏览器端的js开发。
此微信小程序SDK就是基于kintone的JS Client (@kintone/rest-api-client)改造而得。使用过JS Client (@kintone/rest-api-client)的开发者相信很快就能上手。
这里面已经封装好了kintone的大部分REST-API,包括上传下载文件,并调用了wx.request,wx.uploadFile,wx.downloadFile来发送请求到kintone。
callWxAPI(requestConfig) { switch (requestConfig.fileMethod) { case 'download': { return wx.downloadFile(requestConfig); } case 'upload': { return wx.uploadFile(requestConfig); } case 'read': return wx.getFileSystemManager().readFileSync(requestConfig.tempFilePath, 'utf8'); default: { return wx.request(requestConfig); } } } wxSendRequest(requestConfig) { // Execute request return new Promise((resolve, reject) => { requestConfig.fail = err => { reject(err); }; switch (requestConfig.fileMethod) { case 'download': { requestConfig.success = res => { if (res.statusCode === 200) { resolve({tempFilePath: res.tempFilePath}); } else { reject({ ...res, data: JSON.parse(this.callWxAPI({fileMethod: 'read', tempFilePath: res.tempFilePath})) }); } }; break; } case 'upload': { requestConfig.success = res => { if (res.statusCode === 200) { resolve(JSON.parse(res.data)); } else { reject({...res, data: JSON.parse(res.data)}); } }; break; } default: { requestConfig.success = res => { if (res.statusCode === 200) { resolve(res.data); } else { reject(res); } }; } } this.callWxAPI(requestConfig); }); }
范例
以下是利用这个SDK做的库存管理的微信小程序的范例。在手机端添加数据后,小程序和kintone的PC端都得到了同步更新。
部署
Step 1
首先,需要下载好微信开发者工具,并且创建一个JavaScript项目
Step 2
通过npm导入@kintone/rest-api-client-wechat-mp库。
cd your-project-directory npm init npm install @kintone/rest-api-client-wechat-mp
Step 3
启用增强编译和 使用npm模块 选项来支持async等。
选择 “工具” => “构建npm” 来让微信小程序支持npm。
部署完成了。以下是商品列表的演示画面:
代码解析
库存管理
在库存管理应用里实现了
商品列表
商品入库
商品添加
商品出库
商品检索
这几个基本的演示功能。
目录结构
以下是此商品库存管理的微信小程序的目录结构:
其中:
common:
放置静态资源和公用的函数。
kintoneConfig.js定义了kintone的配置信息,kintone的字段代码等。
utility.js定义了一些公用的kintone的连接函数、数据初始化、数据校验等函数。
miniprogram_npm:
微信小程序自动编译的npm第三方库。
pages:
库存管理具体的代码及页面。
components:
检索页面的部件。
添加商品代码
以下是以具体添加商品作为范例来说明SDK的使用方法。
首先了解一下添加商品功能的页面的目录结构。
add.js:逻辑层
写具体的添加商品的逻辑代码。
通过page构造器注册页面
data:初始化数据
onLoad:在页面初始化的时调用uploadFile函数,自动执行文件上传的API并获取file key。
还有其他一些formInputChange、formDateChange等函数与前端add.wxml进行数据绑定,
最后通过在函数submitForm里通过添加记录的API来将数据添加到kintone。
add.wxml:视图层
这是页面模板的页,构建出页面的结构。
这里选择日期,上传图片,提交表单,数据校验这些都是通过微信的WEUI组件库来实现的。他能带给用户类似于原生视觉体验的UI。
add.json:配置
可以写调用的WEUI组件的信息,小程序的页面路径、界面表现、网络超时时间、底部 tab 等
add.wxss:样式
该页面的样式信息
以下是add.js的代码范例:
const kintoneConfig = require('../../common/kintoneConfig'); const utility = require('../../common/utility'); Page({ /** * 页面的初始数据 */ data: { warehouses: ["上海A", "上海B", "苏州", "无锡"], warehouseIndex: 0, warehousePositions: ["1-1", "1-2", "2-1", "2-2"], warehousePositionIndex: 0, inOutDate: `${utility.formatDate(new Date())}`, formData: { inOutDate: `${utility.formatDate(new Date())}`, }, rules: [ { name: 'inOutDate', rules: [{required: true, message: '日期必填'}], }, { // 多个规则 name: 'inOutAmount', rules: [{required: true, message: '数量必填'}, { validator: (rule, value, param, models) => { var regPos = /^\d+$/; // 非负整数 if (!regPos.test(value)) { return rule.message; } }, message: '数量格式不对', valid: true, }], }, { name: 'commodityName', rules: [{required: true, message: '商品名称必填'}] }, ], commodityNameTitle: kintoneConfig.field.commodityName.name, commodityNumberTitle: kintoneConfig.field.commodityNumber.name, inOutDateTitle: kintoneConfig.field.inOutDate.name.in, inOutAmountTitle: kintoneConfig.field.inOutAmount.name.in, unitTitle: kintoneConfig.field.unit.name, inOutNoteTitle: kintoneConfig.field.inOutNote.name, warehouseTitle: kintoneConfig.field.warehouse.name, warehousePositionTitle: kintoneConfig.field.warehousePosition.name, commoditySizeTitle: kintoneConfig.field.commoditySize.name, commodityPriceTitle: kintoneConfig.field.commodityPrice.name, imageTitle: kintoneConfig.field.image.name, }, onLoad() { this.setData({ uploadFile: this.uploadFile.bind(this) }); }, formDateChange: function(e) { this.setData({ inOutDate: e.detail.value, }); this.formInputChange(e); }, formInputChange: function(e) { const {field} = e.currentTarget.dataset; this.setData({ [`formData.${field}`]: e.detail.value }); }, warehouseChange: function(e) { this.setData({ warehouseIndex: e.detail.value, }); }, warehousePositionChange: function(e) { this.setData({ warehousePositionIndex: e.detail.value }); }, fileKey: '', uploadFile: function(files) { console.log('upload files', files); const kintoneFile = utility.kintoneFileModule(); return kintoneFile.upload({filePath: files.tempFilePaths[0]}).then(rsp => { this.fileKey = rsp.fileKey; return {urls: files.tempFilePaths}; }).catch(e => { console.log(e.get()); }); }, deleteFile: function() { this.fileKey = ''; }, submitForm: function() { this.selectComponent('#form').validate((valid, errors) => { console.log('valid', valid, errors); if (!valid) { const firstError = Object.keys(errors); if (firstError.length) { this.setData({ error: errors[firstError[0]].message }); } } else { const kintoneRecord = utility.kintoneRecordModule(); const record = {}; record[kintoneConfig.field.commodityName.code] = {value: this.data.formData.commodityName}; record[kintoneConfig.field.commodityNumber.code] = {value: this.data.formData.commodityNumber}; record[kintoneConfig.field.warehouse.code] = {value: this.data.warehouses[this.data.warehouseIndex]}; record[kintoneConfig.field.warehousePosition.code] = {value: this.data.warehousePositions[this.data.warehousePositionIndex]}; record[kintoneConfig.field.commoditySize.code] = {value: this.data.formData.commoditySize}; record[kintoneConfig.field.commodityPrice.code] = {value: this.data.formData.commodityPrice}; record[kintoneConfig.field.unit.code] = {value: this.data.formData.unit}; if (this.fileKey.length > 0) { record[kintoneConfig.field.image.code] = {value: [{fileKey: this.fileKey}]}; } const value = {}; value[kintoneConfig.field.inOutDate.code] = {value: this.data.formData.inOutDate}; value[kintoneConfig.field.inOutAmount.code] = {value: parseInt(this.data.formData.inOutAmount)}; value[kintoneConfig.field.inOutNote.code] = {value: this.data.formData.inOutNote}; record[kintoneConfig.field.inOutTable.code] = {value: [{value: value}]}; kintoneRecord.addRecord({app: kintoneConfig.appId, record: record}).then(rsp => { wx.redirectTo({url: `../commodity/detail?id=${rsp.id}`}); }).catch(e => { console.log(e.get()); }); } }); }, });
资源列表
SDK源码和文档:https://cybozudev.kf5.com/hc/kb/article/1307637
demo源码:https://github.com/kintone-samples/SAMPLE-rest-api-client-wechat-mp-CN
总结
好了,小程序的SDK和范例就介绍到这里,希望能给大家在开发kintone的微信小程序的时候带来帮助,如果有什么疑问或者建议,可以在下面留言哦。
注意事项
本示例代码不保证其运行。
我们不为本示例代码提供技术支持。