- 电子发票下发用户微信卡包提示发票代码和发票号重复?
请求电子发票下发微信卡包,但是微信返回billing_code and billing_no repeated,发票号和发票代码重复,我想请教下发票代码和发票号不是唯一的吗,这边没有下发过给其他用户
2019-09-26 - 调用“6 更新发票卡券状态”接口出错:
post 方式调用 https://api.weixin.qq.com/card/invoice/platform/updatestatus?access_token=xxx 接口 body如下: { "card_id":"p6EtvvxaYF_cDMeU69MzIGruudQs", "code":"144032009110", "reimburse_status":"INVOICE_REIMBURSE_CANCEL" } 得到响应内容: { "errcode": 72038, "errmsg": "invoice order never auth hint: [Fx2L.a0715ld75]" } 但是用户是点击授权过的了,为什么会报错呢?(其实能拿到card_id 就肯定是授权过的了不是吗)
2020-02-05 - 使用 DllPlugin 优化小程序项目打包速度
背景 以前有用过dllplugin将一些第三方库打包,在日常开发中忽略第三方的打包,来优化打包速度。 存在问题 打包出来的文件是通过var [name]_[hash]的方式,暴露在全局变量当中,但是在小程序里面,这样暴露的变量并不是全局变量,具体可以看下这篇资料。小程序有一个全局变量,App,Page,Component,global,wx这些基本变量都是挂载到这个全局变量里面。 解决方案 webpack 的配置上有一个配置,output中libraryTarget,可以将变量导出到一个变量当中,相关资料。 所以可以将变量导出到global当中,但是当我设置[代码]libraryTarget:global[代码]的时候,导出的dll文件将变量挂载到了window下。具体原因我还没找出来,通过尝试,我发现设置[代码]globalObject:global[代码]就可以将变量挂载到global对象当中。 webpack的output 配置如下: [代码]output: { filename: filename, library: '[name]_[chunkhash]', globalObject: 'global', //全局对象配置 libraryTarget: 'global', } [代码] 代码引用出现问题 我们将打包出来的变量挂载到了global对象当中,但是在文件里面引用时,还是以 [name]_[hash] 全局变量的形式引用,所以小程序会报错:[代码][name]_[hash] is undefined[代码] 解决方案 我想了一种解决方案,比较low,我在在配置dllplugin的时候,将引入的变量名改为 global.[name]_[hash],暂时解决了这个问题,由于时间关系,我没有深入寻找其他解决方案,如果有朋友有其他解决方案,欢迎随时交流。 代码片段如下: [代码]new DllPlugin({ path: path.join(outputPath, '[name].manifest.json'), name: 'global.[name]_[chunkhash]', }) [代码] vendor.dll.js引入问题 熟悉dllplugin的都知道,如果在H5项目中,使用插件在html文件里面插入一个script标签即可。在小程序项目当中,需要通过require("…/…/vendor.dll.js");引入。现成的插件当中没有这样的。所以我们老大写了一个插件将vendor.dll.js加到入口文件。 插件实现方案 通过webpack的插件钩子emit,在生成到js文件之前,将[代码]require("vendor.dll.js");[代码]加入到js文件当中。具体实现方案: [代码]const path = require('path'); const upath = require('upath'); const relative = require('relative'); const getRelativePath = (filePath) => { if (!/^\.(\.)?\//.test(filePath)) { filePath = `./${filePath}`; } return filePath; }; const chunksHandle = (chunks, compilation) => { // 获取入口chunk const entryChunk = chunks.pop(); // 遍历入口文件 entryChunk.files.forEach(filePath => { const assetFile = compilation.assets[filePath]; const extname = path.extname(filePath); let content = assetFile.source(); // 增加 dll js if (extname === '.js') { let subFile = 'vendor.dll.js'; let relativePath = upath.normalize(relative(filePath, subFile)); relativePath = getRelativePath(relativePath); content = `require("${relativePath}");\n${content}`; } assetFile.source = () => content; }); }; const emitHandle = (compilation, callback) => { if (compilation.entrypoints instanceof Map) { compilation.entrypoints.forEach(({ chunks }) => chunksHandle(chunks, compilation)); } else { Object.keys(compilation.entrypoints).forEach(key => { const { chunks } = compilation.entrypoints[key]; chunksHandle(chunks, compilation); }); } callback(); }; MpvuePlugin.prototype.apply = compiler => compiler.hooks.emit.tapAsync('mpvue-emit', emitHandle); module.exports = MpvuePlugin; [代码] 推荐一个 DllPlugin 的插件 auto-dllplugin,这个插件将dllplugin 首次打包和再次打包结合在一起,通过计算hash值判断是否为首次打包,并且将打包结果缓存,如果是再次打包则直接拿缓存数据。不过这个插件不能直接使用到小程序项目打包当中,需要按照我上面所述的修改,我已经修改好一个版本,在个人GitHub项目上,已提pr。 效果 未使用dllplugin [图片] 使用dllplugin [图片] 总结 我们这个 DllPlugin 的方案同理也适用于当前主流的一些框架,例如:mpvue,wepy,taro等等。我们当前使用的环境是:mpvue+wepack4+babel7。欢迎大家一起交流~
2019-09-03