使用taro + node + 微信各种支付 + 支付宝支付 的混合开发项目

2,155 阅读3分钟

基于taro搭建的转多端项目

新项目需要同时运行在微信小程序和webapp上,产品期望更新功能时,两端(或更多端)保持同步更新, 为适用该场景,选择使用业内的混合开发框架taro(一套代码支持多端运行)

主要内容:

项目遇到的坑点;
node中后台的运用;
微信小程序遇到的问题;

一. 项目遇到的坑点

  • 总体用法和写react没有太多区别, 只是taro做了一些封装, 有些用法会不一样;例如:把connect进行了封装
// 项目使用了redux管理请求
import { dispatchHome } from '@reducers/modules/home'
import { dispatchCommon } from '@reducers/modules/common'

@connect(({ common, home }) => ({ common, home }), {
    dispatchHome,
    dispatchCommon 
})

class Home extends Component { 
...
    getDataList(){
        // 这里可以调用
        this.props.dispatchCommon(params)
  }
...
}
  • 跳转webview打开的h5页面时,有时候参数会解析不出来需要encode和decode

  • 项目体积过大, 在开发后上传代码时,提示代码体积过大,要采用分包加载的方式;分包后代码体积减少700kb;

subPackages: [
     {
       name: 'user',
       root: "pages/user/",
       pages: [
         'pages/user/address/address',//我的地址列表
       ]
     }
   ],
   preloadRule: {
     "pages/tabbar/user/user": {  //进入我的界面预加载user分包
       network: "all",
       packages: ["user"]
     }
   },

二. node中后台的运用;

  • 使用koa框架搭建node服务
 "dependencies": {
    "axios": "^0.17.1",
    "cross-env": "^5.2.0",
    "debug": "^4.1.1",
    "koa": "^2.4.1",
    "koa-bodyparser": "^3.2.0",
    "koa-json": "^2.0.2",
    "koa-onerror": "^1.3.1",
    "koa-router": "^7.1.1",
    "log4js": "^4.3.1",
    "md5": "^2.2.1"
  },
  "devDependencies": {
    "chalk": "^2.4.2",
    "nodemon": "^1.14.11"
  }
  • 小程序需要使用https协议;因此需要配置证书
申请的免费SSL证书压缩包解压后有4种证书,分别是Tomcat、Nginx、IIS、Apache的证书。
nodejs代码中key和cert是需要使用Nginx里的key和cert文件
把解压的Nginx文件夹放到项目根目录,只需要修改下bin目录下的www文件就能完成https的配置!
#!/usr/bin/www
var https = require('https');

/**
 * add credentials
 */

var privateKey  = fs.readFileSync('./certificate/1922253_.com.key','utf8');
var certificate = fs.readFileSync('./certificate/1922253_.com.pem','utf8');
var credentials = {key: privateKey, cert: certificate};

/**
 * Create HTTPS server.
 */
  var server = https.createServer(credentials, app.callback()).listen(port);
  server.on('error', onError);
  server.on('listening', onListening);
  console.log(`\n https server is running at:`)
}

  • 中台使用一致的签名算法
  • 中台的日志监控, 便于定位问题
const logError = (ctx, error, time) => {
  if (ctx && error) {
    // errorLogger.error(formatError(ctx, error, time));
    console.log(formatError(ctx, error, time))
  }
};

const logResponse = (ctx, time) => {
  if (ctx) {
    // resLogger.info(formatRes(ctx, time));
    console.log(formatRes(ctx, time))
  }
};

const formatRes = (ctx, time) => {
  let logText = new String();
  logText += "\n" + "*************** response log start ***************" + "\n";

  // 添加请求日志
  logText += formatReqLog(ctx, time);

  // 响应状态码
  logText += "response status: " + ctx.status + "\n";

  // 响应内容
  logText += "response body: " + "\n" + JSON.stringify(ctx.body) + "\n";

  // 响应日志结束
  logText += "*************** response log end ***************" + "\n";

  return logText;
}

const formatError = function (ctx, err, time) {
  let logText = new String();
  logText += "\n" + "*************** error log start ***************" + "\n";

  // 添加请求日志
  logText += formatReqLog(ctx, time);

  // 错误名称
  logText += "err name: " + err.name + "\n";
  // 错误信息
  logText += "err message: " + err.message + "\n";
  // 错误详情
  logText += "err stack: " + err.stack + "\n";

  // 错误信息结束
  logText += "*************** error log end ***************" + "\n";

  return logText;
};

const formatReqLog = function (ctx, time) {
  let logText = new String();
  let req = ctx.request;
  let method = req.method;
  let startTime = `${time.start.toLocaleString()}:${time.start.getMilliseconds()}`;
  let endTime = `${time.end.toLocaleString()}:${time.end.getMilliseconds()}`;

  // 访问方法
  logText += "request method: " + method + "\n";

  // 请求原始地址
  logText += "request originalUrl:  " + req.originalUrl + "\n";

  // 客户端ip
  logText += "request client ip:  " + req.ip + "\n";

  // 请求参数
  if (method === 'GET') {
    logText += "request query:  " + JSON.stringify(req.query) + "\n";
  } else {
    logText += "request body: " + "\n" + JSON.stringify(req.body) + "\n";
  }

  // 请求开始时间
  logText += "request start time: " + startTime + "\n";

  // 请求结束时间
  logText += "request end time: " + endTime + "\n";

  // 服务器响应时间
  logText += "response time: " + `${time.end - time.start}` + " ms" + "\n";

  // node服务tid
  logText += "response ntid: " + ctx.state.ntid + "\n";

  return logText;
}

module.exports = {
    logResponse,
    logError
};

  • 中台转发涉及到负载均衡的问题, 通过cos的内网访问解决;

三. 微信小程序的问题;

  • 微信小程序页面添加分享功能;在需要分享的页面添加代码
    onShareAppMessage() {}

  • 微信小程序web-view组件嵌入的h5页面内的请求是否必须都是https

    在webview里面的h5页面如果有ajax网络请求获取数据,那么这个请求的api地址需要在微信平台的后台管理系统配置request域名
    所有的网络请求都需要支持https://
    所有的加载网络资源要配置uploadFile合法域名
    
  • 微信小程序分享页面的生成海报需要canvas

  • 微信小程序版本有的问题会拒审

  • 难点 是 在小程序里面打开h5页面,h5页面跳转到小程序内的某个页面.同时h5 要支持在小程序里面.app客户端和web浏览器里面的打开逻辑不受影响;