- 微信支付商户免充值代金券接口升级验收脚本(NodeJS版) 用例组合1001+1002+1003+1004+1005
前言: 本文是在社区网友Memory的原贴基础上,转译成的NodeJS版本用例。 附原文地址:微信支付商户免充值代金券接口升级验收脚本 用例组合1001+1002+1003+1004+1005(强迫症专用)? - 微信开放社区 https://developers.weixin.qq.com/community/develop/article/doc/0002e82b060c3028230c915f150813 1,为什么要升级? 开通免充值代金券后,几个支付相关接口参数会发生变动,需要改相应代码适配变动。 详见:开通免充值业务API接口升级详情 https://pay.weixin.qq.com/wiki/doc/api/download/ptsh_mczjksj.pdf 2,官方的测试验收示例 详见:https://pay.weixin.qq.com/wiki/doc/api/download/mczyscsyl.pdf 3,接口升级验收进度查询 详见:https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=15_6&index=4 4,使用自动升级验收脚本前的重要提醒! 请务必去改自己的应用层代码,这里只是方便统一验收用。 5,自动升级验收脚本代码 [代码]const request = require('request'); const md5 = require('md5'); const xml2js = require('xml2js'); const xmlparser = new xml2js.Parser({ explicitArray: false }); var requestPost = function (url, data) { return new Promise(function (resolve, reject) { request.post({ url: url, body: data }, function (error, response, body) { if (error) return reject(error); resolve(body); }) }) } let SandBox_Url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey' let MicroPay_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/micropay" let UnifiedOrder_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder" let OrderQuery_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery" let ReFund_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/refund" let RefundQuery_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/refundquery" let DownloadBill_Url = "https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill" let nonce_str = "5K8264ILTKCH16CQ2502SI8ZNMTM67VS" let appid = "wxc813982bbb9ad5d4" async function get_sign_key(mch_id, key) { let sign = md5(`mch_id=${mch_id}&nonce_str=${nonce_str}&key=${key}`) let template = `<xml><mch_id><![CDATA[${mch_id}]]></mch_id><nonce_str><![CDATA[${nonce_str}]]></nonce_str><sign><![CDATA[${sign}]]></sign></xml>` let result = await requestPost(SandBox_Url, template) let xmlJSON = await xmlparser.parseStringPromise(result); return xmlJSON.xml } async function json2xml(params, wxpay_key) { const _params = {}; Object.keys(params).sort().forEach(function (key) { _params[key] = params[key]; }); let encrypted_str = `` let xml = `<xml>` for (let key in _params) { xml += `<${key}><![CDATA[${_params[key]}]]></${key}>` encrypted_str += `${key}=${_params[key]}&` } encrypted_str += `key=${wxpay_key}` encrypted_str = md5(encrypted_str).toUpperCase() xml += `<sign><![CDATA[${encrypted_str}]]></sign></xml>` return xml } async function get_out_trade_no() { let num = ''; for (var i = 0; i < 5; i++) { num += Math.floor(Math.random() * 10); } return `${Date.parse(new Date())}${num}`; } async function upgrade(mch_id, key) { let wxpay_key = await get_sign_key(mch_id, key) if (wxpay_key.sandbox_signkey) { wxpay_key = wxpay_key.sandbox_signkey } else { return wxpay_key } let out_trade_no, out_trade_no_2nd, template, result, xmlJSON console.log(`========用例编号1001刷卡========`) out_trade_no = await get_out_trade_no() let MicroPay_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'body': "check", 'out_trade_no': out_trade_no, 'total_fee': "501", 'spbill_create_ip': "8.8.8.8", 'auth_code': "120061098828009406", } template = await json2xml(MicroPay_param, wxpay_key); result = await requestPost(MicroPay_Url, template) console.log(`========用例编号1001刷卡正常支付查询========`) let OrderQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no, } template = await json2xml(OrderQuery_param, wxpay_key); result = await requestPost(OrderQuery_Url, template) console.log(`========用例编号1002刷卡========`) out_trade_no_2nd = await get_out_trade_no() MicroPay_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'body': "check", 'out_trade_no': out_trade_no_2nd, 'total_fee': "502", 'spbill_create_ip': "8.8.8.8", 'auth_code': "120061098828009406", } template = await json2xml(MicroPay_param, wxpay_key); result = await requestPost(MicroPay_Url, template) console.log(`========用例编号1002刷卡正常支付查询========`) OrderQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no_2nd, } template = await json2xml(OrderQuery_param, wxpay_key); result = await requestPost(OrderQuery_Url, template) console.log(`========用例编号1002刷卡支付退款========`) let ReFund_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_refund_no': out_trade_no, 'total_fee': "502", 'refund_fee': "501", 'out_trade_no': out_trade_no_2nd, } template = await json2xml(ReFund_param, wxpay_key); result = await requestPost(ReFund_Url, template) console.log(`========用例编号1002刷卡支付退款查询========`) let RefundQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no_2nd, } template = await json2xml(RefundQuery_param, wxpay_key); result = await requestPost(RefundQuery_Url, template) console.log(`========用例编号1003-公众号/APP/扫码正常支付========`) out_trade_no = await get_out_trade_no() let UnifiedOrder_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'body': "check", 'out_trade_no': out_trade_no, 'total_fee': "551", 'notify_url': "https://www.weixin.qq.com/wxpay/pay.php", 'spbill_create_ip': "8.8.8.8", 'trade_type': "JSAPI", } template = await json2xml(UnifiedOrder_param, wxpay_key); result = await requestPost(UnifiedOrder_Url, template) console.log(`========用例编号1003-公众号/APP/扫码正常支付查询========`) OrderQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no, } template = await json2xml(OrderQuery_param, wxpay_key); result = await requestPost(OrderQuery_Url, template) console.log(`========用例编号1004-公众号/APP/扫码支付退款========`) out_trade_no_2nd = await get_out_trade_no() UnifiedOrder_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'body': "check", 'out_trade_no': out_trade_no_2nd, 'total_fee': "552", 'notify_url': "https://www.weixin.qq.com/wxpay/pay.php", 'spbill_create_ip': "8.8.8.8", 'trade_type': "JSAPI", } template = await json2xml(UnifiedOrder_param, wxpay_key); result = await requestPost(UnifiedOrder_Url, template) console.log(`========用例编号1004-公众号/APP/扫码支付退款查询========`) OrderQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no_2nd, } template = await json2xml(OrderQuery_param, wxpay_key); result = await requestPost(OrderQuery_Url, template) console.log(`========用例编号1004-公众号/APP/扫码支付退款========`) ReFund_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_refund_no': out_trade_no, 'total_fee': "552", 'refund_fee': "551", 'out_trade_no': out_trade_no_2nd, } template = await json2xml(ReFund_param, wxpay_key); result = await requestPost(ReFund_Url, template) console.log(`========用例编号1004-公众号/APP/扫码支付退款查询========`) RefundQuery_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'out_trade_no': out_trade_no_2nd, } template = await json2xml(RefundQuery_param, wxpay_key); result = await requestPost(RefundQuery_Url, template) console.log(`========下载交易的对账单========`) let DownloadBill_param = { 'appid': appid, 'mch_id': mch_id, 'nonce_str': nonce_str, 'bill_date': "2021-04-01", 'bill_type': "ALL" } template = await json2xml(DownloadBill_param, wxpay_key); await requestPost(DownloadBill_Url, template) return { retcode: 0 } } module.exports = { upgrade } [代码]
2021-05-10 - 免充值产品测试验收用例的wechatpay-axios-plugin教学帖
社区内大佬们都有贡献 「免充值代金券」 的测试用例实现,这篇文章也来凑一下热闹,顺带帮你把一下为啥要做这个 「测试验收」 以及 「验收注意」 细节。 引言 官方用例文档链接 一共25页,非常详细,照着描一步步做,很快就能验收完。本篇作为「教学帖」,试着让友商们理解,这个验收的重要性,如果希望能够获取帮助直接验收,请阅读代金券接口升级验收脚本 用例组合1001+1002+1003+1004+1005。 安装nodejs sdk 本篇以 [代码]wechatpay-axios-plugin[代码] 这款npm开发包展开,详细介绍可阅读 从APIv3到APIv2再到企业微信,这款微信支付开发包的README你应该来读一读。 [代码]npm install wechatpay-axios-plugin@"v0.5.5" [代码] v0.6系列做了[代码]返回数据签名强校验[代码],以下示例代码需要做特殊处理,本篇以v0.5.5展开。 获取沙箱密钥 先要理解,沙箱环境是个仿真环境,不是生产环境,友商朋友们应该做环境隔离。起步需要商户使用生产环境的 [代码]API密钥[代码],去获取[代码]沙箱密钥[代码],后续所有[代码]沙箱环境[代码]操作都要使用由[代码]沙箱密钥[代码]生成的[代码]数据签名sign[代码]。 [代码]const { Wechatpay, Formatter } = require('wechatpay-axios-plugin'); const mchid = '你的商户号'; const secret = '你的32字节的`API密钥`字符串'; const appid = '你的APPID字符串'; const mch_id = mchid; const noop = {serial: 'any', privateKey: 'any', certs: {any: undefined}}; // 实例化一个对象 let wxpay = new Wechatpay({ secret, mchid, ...noop }); const { data: { sandbox_signkey } } = await wxpay.v2.sandboxnew.pay.getsignkey({ mch_id, nonce_str: Formatter.nonce() }); [代码] 1001 付款码(刷卡)支付 订单金额 [代码]5.01[代码] 元,其中 [代码]0.01[代码] 元使用免充值券,用户实际支付 [代码]5.00[代码] 元。验证商户具备正确解析及识别免充值代金券字段的能力。 1001.1 请求支付 [代码]// 重新实例化一个沙箱环境的对象 wxpay = new Wechatpay({ secret: sandbox_signkey, mchid, ...noop }); // 模拟一个商户订单号 let out_trade_no = `SD${+new Date()}_501`; const { data: { coupon_fee, settlement_total_fee, total_fee } } = await wxpay .v2.sandboxnew.pay.micropay({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, body: 'dummybot', total_fee: 501, spbill_create_ip: '127.0.0.1', auth_code: '120061098828009406' }); console.table({ 代金券金额: coupon_fee, 应结订单金额: settlement_total_fee, 订单金额: total_fee }); [代码] 打印日志应如下: [代码]┌──────┬─────┐ │ (index) │ Values │ ├──────┼─────┤ │ 代金券金额 │ '1' │ │应结订单金额 │ '500' │ │ 订单金额 │ '501' │ └──────┴─────┘ [代码] 1001.2 获取支付结果 [代码]const { data: { settlement_total_fee, total_fee, coupon_fee, coupon_fee_0, coupon_type_0, coupon_count, } } = await wxpay .v2.sandboxnew.pay.orderquery({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, }); console.table({ 代金券金额: coupon_fee, 应结订单金额: settlement_total_fee, 订单金额: total_fee, 单个代金券支付金额: coupon_fee_0, 代金券类型: coupon_type_0, 代金券使用数量: coupon_count }); [代码] 打印日志应如下: [代码]┌──────────┬──────┐ │ (index) │ Values │ ├──────────┼──────┤ │ 代金券金额 │ '1' │ │ 应结订单金额 │ '500' │ │ 订单金额 │ '501' │ │单个代金券支付金额 │ '1' │ │ 代金券类型 │ 'NO_CASH'│ │ 代金券使用数量 │ '1' │ └──────────┴──────┘ [代码] 1002 付款码(刷卡)支付退款 订单金额 [代码]5.02[代码] 元,其中 [代码]0.01[代码] 元使用免充值代金劵,实际支付 [代码]5.01[代码] 元,退款查询升级。 1002.1 请求支付 [代码]//模拟重置一个商户订单号 out_trade_no = `SD${+new Date()}_502`; const { data: { coupon_fee, settlement_total_fee, total_fee, } } = await wxpay .v2.sandboxnew.pay.micropay({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, body: 'dummybot', total_fee: 502, spbill_create_ip: '127.0.0.1', auth_code: '120061098828009406' }); console.table({ 代金券金额: coupon_fee, 应结订单金额: settlement_total_fee, 订单金额: total_fee }); [代码] 打印日志应如下: [代码]┌────────┬─────┐ │ (index) │ Values │ ├────────┼─────┤ │ 代金券金额 │ '1' │ │ 应结订单金额 │ '501' │ │ 订单金额 │ '502' │ └────────┴─────┘ [代码] 1002.2 获取支付结果 [代码]const { data: { settlement_total_fee, total_fee, coupon_fee, coupon_fee_0, coupon_type_0, coupon_count } } = await wxpay .v2.sandboxnew.pay.orderquery({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, }); console.table({ 商户订单号: out_trade_no, 代金券金额: coupon_fee, 应结订单金额: settlement_total_fee, 订单金额: total_fee, 单个代金券支付金额: coupon_fee_0, 代金券类型: coupon_type_0, 代金券使用数量: coupon_count }); [代码] 打印日志应如下: [代码]┌──────────┬────────────┐ │ (index) │ Values │ ├──────────┼────────────┤ │ 商户订单号 │'SD1618966329677_502'│ │ 代金券金额 │ '1' │ │ 应结订单金额 │ '501' │ │ 订单金额 │ '502' │ │单个代金券支付金额│ '1' │ │ 代金券类型 │ 'NO_CASH' │ │ 代金券使用数量 │ '1' │ └──────────┴─────────────┘ [代码] 1002.3 请求退款 [代码]const { data: { cash_refund_fee, cash_fee, refund_fee, total_fee } } = await wxpay .v2.sandboxnew.pay.refund({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, out_refund_no: `RD${out_trade_no}`, total_fee: 502, refund_fee: 501, }); console.table({ 退款金额: refund_fee, 标价金额: total_fee, 现金支付金额: cash_fee, 现金退款金额: cash_refund_fee, }); [代码] 打印日志应如下: [代码]┌────────┬─────┐ │ (index) │ Values │ ├────────┼────┤ │ 退款金额 │ '502' │ │ 标价金额 │ '502' │ │ 现金支付金额 │ '501' │ │ 现金退款金额 │ '501' │ └───────┴─────┘ [代码] 1002.4 获取退款结果 [代码]const { data: { settlement_total_fee, total_fee, cash_fee, settlement_refund_fee, coupon_refund_fee_0, coupon_type_0_0, coupon_refund_fee_0_0, refund_fee_0, coupon_refund_count_0, } } = await wxpay .v2.sandboxnew.pay.refundquery({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), }); console.table({ 应结订单金额: settlement_total_fee, 订单金额: total_fee, 现金支付金额: cash_fee, 退款金额: settlement_refund_fee, 总代金券退款金额: coupon_refund_fee_0, 代金券类型: coupon_type_0_0, 总代金券退款金额: coupon_refund_fee_0_0, 申请退款金额: refund_fee_0, 退款代金券使用数量: coupon_refund_count_0, }); [代码] 1003 JSAPI/APP/Native支付 订单金额 [代码]5.51[代码] 元,其中 [代码]0.01[代码] 元使用免充值券,实际支付 [代码]5.50[代码] 元。 验证正常支付流程,商户使用免充值代金券支付。 1003.1 统一下单 [代码]//模拟重置一个商户订单号 out_trade_no = `SD${+new Date()}_551`; const {data: { prepay_id } } = await wxpay .v2.sandboxnew.pay.unifiedorder({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), body: 'dummybot', total_fee: 551, notify_url: 'https://www.weixin.qq.com/wxpay/pay.php', spbill_create_ip: '127.0.0.1', trade_type: 'JSAPI' }); console.table({ 预支付交易会话标识: prepay_id }); [代码] 1003.2 获取支付结果 [代码]const { data: { out_trade_no, total_fee, cash_fee, coupon_fee, coupon_count, coupon_fee_0, coupon_type_0, coupon_fee_0 } } = wxpay .v2.sandboxnew.pay.orderquery({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), }); console.table({ out_trade_no, total_fee, cash_fee, coupon_fee, coupon_count, coupon_fee_0, coupon_type_0, coupon_fee_0 }); [代码] 1004 JSAPI/APP/Native支付退款 订单金额 [代码]5.52[代码] 元,其中 [代码]0.01[代码] 元使用免充值券,实际支付 [代码]5.51[代码] 元。 1004.1 统一下单 [代码]//模拟重置一个商户订单号 out_trade_no = `SD${+new Date()}_551`; const {data: { prepay_id } } = await wxpay .v2.sandboxnew.pay.unifiedorder({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), body: 'dummybot', total_fee: 552, notify_url: 'https://www.weixin.qq.com/wxpay/pay.php', spbill_create_ip: '127.0.0.1', trade_type: 'JSAPI' }); console.table({ 预支付交易会话标识: prepay_id }); [代码] 1004.2 获取支付结果 [代码]const { data: { out_trade_no, total_fee, cash_fee, coupon_fee, coupon_count, coupon_fee_0, coupon_type_0, coupon_fee_0 } } = wxpay .v2.sandboxnew.pay.orderquery({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), }); console.table({ out_trade_no, total_fee, cash_fee, coupon_fee, coupon_count, coupon_fee_0, coupon_type_0, coupon_fee_0 }); [代码] 1004.3 请求退款 [代码]const { data: { cash_refund_fee, cash_fee, refund_fee, total_fee } } = await wxpay .v2.sandboxnew.pay.refund({ appid, mch_id, nonce_str: Formatter.nonce(), out_trade_no, out_refund_no: `RD${out_trade_no}`, total_fee: 552, refund_fee: 551, }); console.table({ 退款金额: refund_fee, 标价金额: total_fee, 现金支付金额: cash_fee, 现金退款金额: cash_refund_fee, }); [代码] 打印日志应如下: [代码]┌───────┬────┐ │ (index) │ Values│ ├───────┼────┤ │ 退款金额 │ '552' │ │ 标价金额 │ '552'│ │现金支付金额│ '551' │ │现金退款金额│ '551' │ └──────┴────┘ [代码] 1004.4 获取退款结果 [代码]const { data: { settlement_total_fee, total_fee, cash_fee, settlement_refund_fee, coupon_refund_fee_0, coupon_type_0_0, coupon_refund_fee_0_0, refund_fee_0, coupon_refund_count_0, } } = await wxpay .v2.sandboxnew.pay.refundquery({ appid, mch_id, out_trade_no, nonce_str: Formatter.nonce(), }); console.table({ 应结订单金额: settlement_total_fee 订单金额: total_fee 现金支付金额: cash_fee, 退款金额: settlement_refund_fee 总代金券退款金额: coupon_refund_fee_0 代金券类型: coupon_type_0_0, 总代金券退款金额: coupon_refund_fee_0_0 申请退款金额: refund_fee_0 退款代金券使用数量: coupon_refund_count_0, }); [代码] 1005 交易对账单下载 使用了免充值券的订单,免充值券部分的金额不计入结算金额。验证商户对账能正确理解到这一点,对账无误。这里预期会返回 [代码]1269[代码] 条明细数据。 汇总结果:总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款金额。 这里数据应为: [代码]1269, `10.79, `5.93, `0.24, `0.0,`11.27, `6.37 [代码] 以生产标准为例,查询当前时间偏移两天以前的账单: [代码]const { data } = await wxpay .v2.sandboxnew.pay.downloadbill({ appid, mch_id, bill_type: 'ALL', bill_date: ( new Date(+new Date() + (8 - 48)*3600*1000) ).toISOString().slice(0, 10), nonce_str: Formatter.nonce(), }, { transformResponse: [] }); console.table(data); [代码] 打印日志形如: [代码]交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注 `2016-05-04 02:18:18,`wxf7c30a8258df4208,`10014843,`0,`harryma007,`4.00123E+27,`autotest_20160501030456_45023,`oT2kauIMXH398DZBeJ4m22CuSDQ0,`NATIVE,`REFUND,`PAB_DEBIT,`CNY,`0,`0,`2.00123E+27,`REF4001232001201605015390231647,`0.01,`0,`ORIGINAL,`PROCESSING,`body中文测试,`attach中文测试,`0,`0.60%,`0,`0.01,` `2016-05-04 02:18:18,`wxf7c30a8258df4208,`10014843,`0,`harryma007,`4.00123E+27,`autotest_20160501060418_79156,`oT2kauIMXH398DZBeJ4m22CuSDQ0,`NATIVE,`REFUND,`PAB_DEBIT,`CNY,`0,`0,`2.00123E+27,`REF4001232001201605015391766944,`0.01,`0,`ORIGINAL,`PROCESSING,`body中文测试,`attach中文测试,`0,`0.60%,`0,`0.01,` ... 14:51:51,`wxf7c30a8258df4208,`10014843,`0,`harryma8888,`4.00968E+27,`wxautotest1462344441,`oT2kauGtJag902bjdvevrJbpGuxo,`NATIVE,`SUCCESS,`CMBC_CREDIT,`CNY,`0.05,`0.01,`0,`0,`0,`0,`中文[body],`测试中文[attach],`0,`0.60%,`0.05,`0,` 总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额 1269,`10.79,`5.93,`0.24,`0,`11.27,`6.37 [代码] 一铲到底 以下是一键验收全流程的一个[代码]魔性 chain[代码]到底的实现,感谢您阅读至此。 [图片] 本文如果对你开通 「免充代金券」 功能有帮助,那就来个赞呗。
2021-05-10 - 录音stop失效?你需要一套歪操作😅
社区里有这么一个帖子:录音stop失效 帖子下的回复说的很有道理,启发了我的解决思路 录音是个异步的过程 录音的交互一般都是:按钮按下开始录音,按钮弹起停止录音。 但是如果按钮按下的持续时间太短,就会出现当调用RecorderManager.stop()的时候,录音的异步操作还没有返回结果。 这种情况下,[代码]stop()[代码]就(像是)不会被执行 我觉得这里小程序的处理是不妥的。起码应该将[代码]stop()[代码]操作缓存在任务队列里,再根据情况决定执不执行,或者进入[代码]onError[代码]回调 推理猜测说完了,说说解决,大致思路就是给个自己的标志位: [代码]const manager = wx.getRecorderManager() let isRecording = false manager.onStart(() => { // isRecording为false // 说明handleTouchend()->manager.stop()先于开始录音 // manager.stop()并没有被正确执行 // 因此需要再调用一次 if (!isRecording) { manager.stop() } }) // ---- 业务代码 ---- function handleTouchstart () { isRecording = true manager.start() } function handleTouchend () { manager.stop() isRecording = false } [代码]
2019-02-22 - 在公用Util文件中给小程序页面变量赋值
util文件为小程序公用的一个方法文件,我们可以将程序内经常用的方法写在这个文件中,通过其他文件引用,可以达到一个方法全局使用的方法,减少代码量,一定程度上减少维护时间.这是util中是没有办法用this.setData()方法去设置变量值的.因为他不属于任何一个页面.那我们如果想要在util文件的方法中给页面赋值怎么实现呢? 这里用到了微信公用方法:getCurrentPages() 之前做过一个案例希望可以加载页面的时候自动加载底部导航栏实现自定义热更新的小程序底部导航栏,如果分开写的话每个导航页面都需要写一个方法,就考虑想用Util写一个公共方法 代码如下: //获取底部导航方法 function settabbar() { wx.request({ url: getApp().globalData.url + ‘syssetting/gettabbar’,//获取底部导航图标,文字信息 method: ‘POST’, header: {// 设置请求的 header ’content-type’: ‘application/x-www-form-urlencoded’ }, data: { appid: getApp().globalData.appid }, success: function (res) { wx.hideLoading() var pages = getCurrentPages(); //这里使用了getCurrentPages()方法,该方法是用来获取浏览记录的 console.log(pages) //打印结果如下图 var prevPage = pages[pages.length - 1] prevPage.setData({ tabbar: res.data, page:’/’+ prevPage.route }) }, fail: function (res) { wx.showToast({ title: ‘请求失败’, }) }, }) } [图片] 我们可以看到结果中的route表示了当前打开的页面 如果我们再首页点进商品详情页再打印出路由记录时会显示如下结果: [图片] 我们会发现变量pages为2个元素的数组了,展开第二个元素可以看到现在打开的商品详情页,第一个元素的路径为首页路径 这样我们可以得到的在Util页面中标示当前页面为pages[pages.length - 1] var prevPage = pages[pages.length - 1] prevPage.setData({ tabbar: res.data, page:’/’+ prevPage.route }) 我们用这个方法就可以在util页面中给引用的页面赋值了!!! PS:util文件的编写方法 和暴露接口的方法请参照小程序文档
2021-04-15