前言最近在研究Uniapp开发小程序,把自己的研究成果整理成文章,一方面新手可以借鉴,一方面做归档方便以后查阅,有错误之处请各位看官指正。一. 文章内容 Uniapp介绍
Uniapp开发环境搭建 二. Uniapp介绍1. 为什么要使用Uniapp就目前而言,小程序已经非常的流行了,市面上的小程序众多:微信小程序、百度小程序、支付宝小程序、字节跳动小程序等等,各种平台的小程序的开发规划不一致导致给程序员带来很大的负担,因为我们需要学习不同平台小程序开发规范,尽管他们的语法看起来都差不多。为了解决这一问题,Uniapp横空出世,它的目的是让开发者编写一套代码就可以发布到IOS、Android、Web、以及各种小程序平台,达到一次开发到处运行的目的。微信小程序官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/支付宝小程序官方文档:https://opendocs.alipay.com/mini/framework百度小程序官方文档:https://smartprogram.baidu.com/docs/develop/component/component/字节跳动小程序文档:https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/guide/directory-structure2. 什么是UniappUniapp官网:https://uniapp.dcloud.io/uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。DCloud公司拥有800万开发者用户,几十万应用案例、12亿手机端月活用户,数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app(详见),腾讯课堂官方为uni-app录制培训课程(详见),开发者可以放心选择。uni-app在手,做啥都不愁。即使不跨端,uni-app也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。为什么选择Uniapp三. Uniapp环境安装1. 软件安装Uniapp需要有HBuilderX的支持,HBuilderX是通用的前端开发工具,但为uni-app做了特别强化,所以我们需要先安装HBuilderX,然后我们还要安装一个“微信小程序”开发工具,主要是借助它的模拟器来启动Uniapp小程序,所以开始之前,开发者需先下载安装如下工具:1.1.HBuilderX安装HBuilderX:官方IDE下载地址,下载之后安装启动,启动界面选择暂不登录,然后进入软件主界面1.2.微信小程序开发工具安装通过 微信小程序开发工具下载地址下载好之后安装启动,可以使用测试号,创建一个小程序到这,微信小程序开发工具就装好了2. Uniapp项目创建2.1. 新建项目使用HbuilderX, 在菜单栏选择:文件 -> 新建 -> 项目然后创建项目2.2. 目录结构认识结构说明2.3. 启动UniappUniapp可以使用各平台的开发工具的模拟器来启动测试,我这里选择“微信开发工具”如下第一次启动,这里需要选择微信开发工具的安装目录观察控制台然而在HBuilder的控制台这里出现了错误,意思是需要我们去开启“微信开发工具”的服务端口,否则HBuilder是没有办法使用“微信开发工具的”,按照提示打开微信开发工具 -> 设置 -> 安全设置打开服务端口再次运行,观察微信开发工具的模拟器,如下说明已经启动成功当然我们说uniapp是一次编码到处运行,它除了可以打包成微信小程序运行还可以打包成其他的小程序,或者web端去运行,比如:效果如下:文章结束,喜欢的话就给个好评吧}
使用uniapp开发字节跳动小程序的微信支付和支付宝支付(后端PHP,tp5)准备工作微信支付配置支付宝支付配置字节跳动配置1,微信支付配置:开通微信支付的h5支付,关联APPID,保存key,商户ID(mch_id ),配置回调域名,记得把字节跳动的回调域名也写进h5支付的域名配置当中:snssdk.com2,支付宝支付配置:开通支付宝的app支付,在网页&移动应用中创建一个应用接入app支付,并且签约并且保证生效。我是通过支付宝证书进行支付的,所以支付宝这边需要自己去配置证书并且下载下来,后面要用到。3,字节跳动配置开通字节跳动的支付,获得字节跳动的商户号,appid,支付secret业务代码:1,后端2,前端1,后端上传参数,通过支付宝和微信配置订单信息传给前端uniapp,,微信和支付宝的回调正确的话,自己配置正确,按自己的情况添加订单到数据库就可以了,这里就不写了。aliUrlZhengshu方法是支付宝支付,unifiedOrder方法是微信支付。抖音的配置我写在了config.php里面 'douyin'=>[
'appId'=>'*****',
'appSecret'=>'*****',
'url'=>'*****',//抖音授权链接
'payAppId' =>'*****',
'tt_pay_app_secret'=>'*****',//支付secret
'merchant_id'=>'*****',//支付secret
],
public function _initialize()
{
$this->appid = '*****';//微信的appid
$this->mch_id = '*****';//微信的商户id
$this->key = '*****';//key
$this->notify_url = '*****';//自己配置的微信支付回调地址
}
public function payReady(){
$config = config('douyin');
$openid = $this->request->post('openid');
$truePrice = $this->request->post('price');
$video_id = $this->request->post('video_id');
$user_id = $this->request->post('user_id');
$subject = $this->request->post('subject');
$body = $this->request->post('body');
$truePrice = (int)$truePrice;
$tt_result = $this->ttOrder($user_id,$video_id,$truePrice,$subject,$body,$openid);
$out_order_no = $tt_result['out_order_no'];//自定义的订单号
$arr = [
'merchant_id' =>$config['merchant_id'],//字节跳动商户号 前提条件->字节跳动->4 完成填写后
'app_id' => $config['payAppId'],//字节跳动APPID
前提条件->字节跳动->4 完成填写后
'sign_type' => 'MD5',//定死的别动!!!
'timestamp' => strval($tt_result['time']),//需要为字符串类型的时间戳
'version' => '2.0',//定死的别动!!!
'trade_type' => 'H5',//定死的别动!!!
'product_code' => 'pay',//定死的别动!!!
'payment_type' => 'direct',//定死的别动!!!
'out_order_no' => strval($out_order_no),//自定义的订单号
'uid' => $openid,// 用户的openid 登录后可以获取到
'total_amount' => $tt_result['fee'],//金额 这里单位:分
'currency' => 'CNY',//定死的别动!
'trade_no' => $tt_result['out_order_no'],//刚刚获取的字节跳动订单 忘了往上找找
'subject' => $tt_result['subject'],//之前定好的标题
'body' => $tt_result['body'],//之前定好的内容
'trade_time' => strval($tt_result['time']),//一定要和 上面的 timestamp 字段相同
'valid_time' => '3000',//测试留的时间长
'notify_url' => 'https://tp-pay.snssdk.com/paycallback',//定死的别动!!!
];
$aliurl = $this->aliUrlZhengshu($tt_result);//获取 alipay_url
$arr['alipay_url'] = $aliurl;
$wx_res = $this->unifiedOrder($tt_result['out_order_no'],$body,$subject);
if(!empty($wx_res)){
$pay_url
= $wx_res;
}
$arr['wx_type'] = 'MWEB';
$arr['wx_url'] = $pay_url;
$stringToBeSigned = $this->getSignContent($arr);//这里待签名处理.方法下面
$sign = md5($stringToBeSigned . $config['tt_pay_app_secret']);//这生成签名咯, 不要乱, 签名好多的
//这两个字段的写入原因: 在待签名字符串 getSignContent 方法中不能有 sign和risk_info 所以在生成签名($sign)之后写入到里面
$arr['sign'] = $sign;
$arr['risk_info'] = json_encode(['ip' => request()->ip()]);
//这两个字段的写入原因: 在待签名字符串
getSignContent 方法中不能有 sign和risk_info 所以在生成签名($sign)之后写入到里面
$res = htmlspecialchars_decode(json_encode($arr));//这里html的编译解析, 防止html编译
//
$this->success('返回orderinfo', $res);
$this->success('返回orderinfo', ['list' => $res]);
}
/**
* 获取抖音订单号
*/
public function ttOrder($user_id,$video_id,$order_price,$subject,$body,$openid){
$config = config('douyin');
$time = time();
//
if(!$user_id){
//
$this->error('请先授权登录');
//
}
$price = $order_price*100;
//$price = 1;测试的时候使用0.01元
//------------------自定义订单信息--------------------------
$data = [
'out_order_no' =>
$time, //随便搞个订单号
'openid' => $openid,
//抖音用户openid
'fee' => $price,
//金额 单位:分!分!分!
'cid' => 1,
'time' => $time,
'body' => $body,
//支付的内容(支付宝)
'subject' => $subject,
//支付的标题(支付宝)
//body 和 subject 刚开始先用数字(中文会有其他问题)
];
//------------------自定义订单信息--------------------------
//TP5框架 fastadmin
//------------------组合请求sign信息--------------------------
//↓↓↓获取用户真实IP
$risk_info = request()->ip();
//↓↓↓头条支付分配给业务方的ID(不是头条小程序的appid)
$payload['app_id'] = $config['payAppId'];
//↓↓↓头条支付分配给业务方的支付秘钥
$app_secret = $config['tt_pay_app_secret'];
//↓↓↓请求使用的编码格式
$payload['charset'] = "utf-8";
//↓↓↓接口名称
$payload['method'] = "tp.trade.create";
//↓↓↓发送请求的时间
$payload['timestamp'] = $time;
// 请求参数的集合
json
$biz_content = [
//商户订单号
"out_order_no" => $data['out_order_no'],
//唯一标识用户open_id
"uid" => $data['openid'],
//金额,分为单位,应传整型
"total_amount" => $data['fee'],
//商户订单名称
"subject" => $data['subject'],
//商户订单详情
"body" => $data['body'],
//头条支付分配给业务方的商户号
"merchant_id" => $config['merchant_id'],
//货币种类
"currency" => "CNY",
//下单时间戳
"trade_time" => $time,
//订单有效时间(此处测试 时间留的长)
单位:秒
"valid_time" => "3000",
//服务器异步通知地址尽量https 没试过http
"notify_url" => 'https://admin.shitutu.com/public/api/Dou_alipay/notify',
//用户的真实ip 一定要json序列化
"risk_info" => json_encode(['ip' => $risk_info]),
];
$payload['biz_content'] = json_encode($biz_content);
//字节跳动采用的是MD5加密
$payload['sign_type'] = "MD5";
$payload['format'] = "json";
$payload['version'] = "1.0";
//这里写了一个签名的方法, 千万别乱, 此处签名用来请求的, 与其他签名没有任何关联;(共3个签名)
$stringToBeSigned = $this->getSignContent($payload, $payload['charset']);
$payload["sign"] = md5($stringToBeSigned . $app_secret);
$url = "https://tp-pay.snssdk.com/gateway"; // 请求地址正式环境
// $url = "$url?app_id=$payload[app_id]&secret=$appSecret&code=$code&anonymous_code=$anonymous_code";
$result = $this->file_get_contents_post($url, $payload);
/*返回示例:
{"response":{"code":"10000","msg":"Success","trade_no":"SP2020081509594510822988870791"},"sign":"E7RRJSJCVAhA4DMyMPr/Q1IOc1RKpyQNikl9l8b3ObW6dAYzep7rK6wY5YVjSubhmINsI0iWb/cu+YCqp1D+amifkXh4nX2JG3D0xgi2eWJrTv3Ou27zuEPbEb5y10SBG1f4QCYoa7r2upmOL5xbjY6kG5iDPjiS4JIthsojR5Q="}*/
$result = json_decode($result, true);
//------------------组合请求sign信息--------------------------
$res['out_order_no'] = $result['response']['trade_no'];
$res['fee'] = $price;
$res['cid'] = 1;
$res['time'] = $time;
$res['body'] = $body;
$res['subject'] = $subject;
$order_res = $this->order_create($user_id,$video_id,$order_price,$res['out_order_no']);//这里是我自己的创建订单到本地数据库,这个方法就不展示了。
if ($result['response']['code'] != 10000) {
$this->error('错误', $res['response']['code']);
} elseif ($res) {
return $res;
}
}
/**
* 签名处理
* @param $params
* @param $charset
* @return string
*/
public function getSignContent($params, $charset = 'utf-8')
{
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = $this->characet($v, $charset);
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
public function file_get_contents_post($url, $post) {
$options = array(
'http' => array(
'method' => 'POST',
// 'content' => 'name=caiknife&email=caiknife@gmail.com',
'header' => "Content-type: application/x-www-form-urlencoded ",
'content' => http_build_query($post),
),
);
$result = file_get_contents($url, false, stream_context_create($options));
return $result;
}
/**
* @param $data
* @return mixed
* 阿里url证书
*/
public function aliUrlZhengshu($data)
{
//需要在AopCertClient.php文件中加入
//namespace app\api\controller;
//use think\Exception;
//引入文件 用来实例化
$config = config('douyin');
//require_once EXTEND_PATH . '/alipay/AopSdk.php';
require_once VENDOR_PATH . 'aop/AopCertClient.php';
// require_once EXTEND_PATH
. 'aop/AopCertClient.php';
$c = new AopCertClient;
$appCertPath = VENDOR_PATH
. 'aop/crt/appCertPublicKey_2021002114608375.crt';//应用证书路径(要确保证书文件可读)
$alipayCertPath = VENDOR_PATH
. 'aop/crt/alipayCertPublicKey_RSA2.crt';//支付宝公钥证书路径(要确保证书文件可读)
$rootCertPath = VENDOR_PATH
. 'aop/crt/alipayRootCert.crt';//支付宝根证书路径(要确保证书文件可读)
$c->gatewayUrl = "https://openapi.alipay.com/gateway.do";
$c->appId = self::APPID;
$c->rsaPrivateKey = self::RSA_PRIVATE_KEY;
$c->format = "json";
$c->charset = "UTF-8";
$c->signType = "RSA2";
//调用getPublicKey从支付宝公钥证书中提取公钥
$c->alipayrsaPublicKey = $c->getPublicKey($alipayCertPath);
//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
$c->isCheckAlipayPublicCert = true;
//调用getCertSN获取证书序列号
$c->appCertSN = $c->getCertSN($appCertPath);
//调用getRootCertSN获取支付宝根证书序列号
$c->alipayRootCertSN = $c->getRootCertSN($rootCertPath);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.open.public.template.message.industry.modify
//文件中加入 namespace app\api\controller; 即可
require_once VENDOR_PATH . 'aop/request/AlipayTradeAppPayRequest.php';
$request = new AlipayTradeAppPayRequest();
//此次只是参数展示,未进行字符串转义,实际情况下请转义
$request->setBizContent($this->getcontent($data));
$response = $c->sdkExecute($request);
return $response;
}
/**
* @param $data
* @return false|string
* 业务数据
*/
public function getcontent($data)
{
$biz_content = array(
'out_trade_no' => $data['out_order_no'],
//之前咱们自定义的订单号 out_trade_no
'product_code' => 'QUICK_MSECURITY_PAY',
//定死了 别动
'total_amount' => $data['fee'] / 100,
//单位换算
'subject' => $data['subject'],
//之前定好的 标题
'method' => 'alipay.trade.app.pay',
//定死了 别动
'notify_url' => '*****',//回调接口需要配置到支付宝
'body' => $data['body'],
//之前定好的 内容
'timeout_express' => '1m',
//支付超时时间 文档去支付宝搜索咯 1m-15d
);
return json_encode($biz_content);
}
/**
* 下单方法
* param
$params 下单参数
*/
public function unifiedOrder($order_no,$body,$subject){
$config = config('douyin');
$params['body'] = $subject; //商品描述
$params['out_trade_no'] = $order_no; //订单号
$params['total_fee'] = 1; //金额是以分为单位,除测试外,需乘以100
$params['trade_type'] = 'MWEB';
//交易类型,h5支付,默认如此
$params['scene_info'] = $body;
//场景信息,h5固定
$params['spbill_create_ip'] = $this->getIp();
//终端IP
$params['appid'] = $this->appid;
$params['mch_id'] = $this->mch_id;
$params['nonce_str'] = $this->genRandomString();
//随机字符串
$params['notify_url'] = $this->notify_url;
//通知地址
//获取签名数据
$params['sign'] = $this->MakeSign( $params );
//签名
$xml = $this->data_to_xml($params);
$uri = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
//请求地址
$response = $this->postXmlCurl($uri,$xml);
//自定义封装的xml请求格式,文章最下面为参考postxml
if( !$response ){
return false;
}
$result = $this->xml_to_data( $response );
if( !empty($result['result_code']) && !empty($result['err_code']) ){
$result['err_msg'] = $this->error_code( $result['err_code'] );
}
if($result['result_code'] == 'SUCCESS' && $result['return_msg'] == 'OK'){
//发起微信支付url
$pay_url = $result['mweb_url'];//.'&redirect_url='.urlencode($this->notify_url)
}else{
$pay_url = '';
}
return $pay_url;
//return $result;
}
/**
* 生成签名
*
@return 签名
*/
public function MakeSign( $params ){
//签名步骤一:按字典序排序数组参数
ksort($params);
$string = $this->ToUrlParams($params);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$this->key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 输出xml字符
* param
$params
参数名称
* return
string
返回组装的xml
**/
public function data_to_xml( $params ){
if(!is_array($params)
count($params) <= 0)
{
return false;
}
$xml = "";
foreach ($params as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."".$key.">";
}else{
$xml.="<".$key.">".$key.">";
}
}
$xml.="";
return $xml;
}
/**
* @param $url
* @param $xml
* @param int $second
* @return bool|string
* xml请求
*/
public function postXmlCurl($url,$xml,$second = 30){
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
//设置 header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post 提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行 curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
}else{
$error = curl_errno($ch);
curl_close($ch);
echo "curl 出错,错误码:$error"."
";
}
}
/**
* 将xml转为array
* param string $xml
* return array
*/
public function xml_to_data($xml){
if(!$xml){
return false;
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
/**
* 校验$value是否非空
* @param $value
* @return
boolean;
*
if not set ,return true;
*
if is null , return true;
**/
public function checkEmpty($value)
{
if (!isset($value))
return true;
if ($value === null)
return true;
if (trim($value) === "")
return true;
return false;
}
/**
* 转换字符集编码
* @param $data
* @param $targetCharset
* @return string
*/
public function characet($data, $targetCharset)
{
if (!empty($data)) {
$fileType = "UTF-8";
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset, $fileType);
}
}
return $data;
}
2,前端,uniapp我是通过字节跳动的收银台吊起的支付的,吊起收银台后可以选择支付宝或者微信支付,然后跳转到微信或者支付宝,所以上面要把微信和支付宝的支付url都传给了前端。gopay(){
wxpay({
'openid':'****',
'price':'****',
'video_id':'****',
'user_id':'****',
'subject':'****',
'body':this.detailList.title,
}).then(e => {
let order = JSON.parse(e.data.data.list);
let order_no = order.trade_no
if(e.data.code == 1){
uni.requestPayment({
service: 1, // 不拉起字节跳动小程序收银台
_debug: 1,
payChannel: {
default_pay_channel: 'alipay' // wx
alipay
},
orderInfo: order, // 订单信息
getOrderStatus(res) {
let { out_order_no } = res;
return new Promise(function (resolve, reject) {
})
},
success: (res) => {
console.log(res)
if(res.code == 0){
uni.showToast({
title: '支付成功',
duration: 2000
});
}
if(res.code == 1){
uni.showToast({
title: '支付超时',
duration: 2000
});
}
if(res.code == 2){
uni.showToast({
title: '支付失败',
duration: 2000
});
}
if(res.code == 2){
uni.showToast({
title: '支付失败',
duration: 2000
});
}
if(res.code == 4){
orderQuery({
'order_no':order_no,
}).then(e => {
if(e.data.code == 1){
uni.showToast({
title: '支付成功',
duration: 2000
});
}else{
uni.showToast({
title: '支付失败',
duration: 2000
});
}
});
}
if(res.code == 9){
uni.showToast({
title: '订单状态未知',
duration: 2000
});
}
},
fail: (res) => {
console.log("失败1");
console.log(res);
// 错误代码:CD0015 CD0025
},
complete: (res) => {
console.log("结束")
}
})
// _this.loadModal = false;
}
})
},
这里有一个问题我不知道是不是字节官方的原因,我通过收银台支付,使用支付宝支付的时候,支付成功,返回小程序是有字节的支付回调页面并且提示成功的。但是微信支付没有显示这个支付回调的页面提示,并且code一直是4,所以我在code等于4的时候去后端验证了一下支付状态,手动给用户提示了支付状态,如果有朋友知道原因可以麻烦告知我一下,有问题也欢迎留言。}
@[TOC](开发微信小程序所遇问题 uni.previewImage())1.小程序生命周期onlaunch:当小程序初始化完成时,会触发onlaunch ,全局只触发一次(app.js)onLoad:页面加载 ---- 页面注册完成后加载页面,触发onLoad方法,一个页面只会调用一次,可以在onLoad中回去打开当前页面所调用的query参数,onShow:页面显示 — 页面加载后触发onShow。显示页面。每次打开页面都会调用一次onReady:首次显示页面,页面初次渲染完成,会触发onReady 方法,渲染页面元素和样式,一个只会调用一次,代表页面已经准备完成,可以和视图层进行交互。对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。onHide:页面隐藏------ 当navigateTo、底部tab切换、上传文件选择图片时调用。onUnload:页面加载当返回上一页wx.navigateBack、wx.relanch、wx.redirectTo时都会被调用(这里的坑有点深)。基本上可以说执行顺序为onLaunch–onLoad–onShow–onReady–onHide.虽然说onLaunch在onLoad之前执行,但是在onLaunch里请求获取是否有权限,等待返回值的时候Page里的onLoad事件就已经执行了。解决办法:在APP里面onLanch中的网络请求中设置判断
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
在page的onLoad中设置一个回调app.userInfoReadyCallback = res => {
if (res != '') {
console.log("app.globalData.userInfo")
}
}
getImgSrc() {
return `${base}${mineQrcode}&openid=${this.$store.state.Info.token}` //获取后端返回小程序二维码接口
},
const urls = [this.getImgSrc()] // https:xxxxx
uni.previewImage({
urls,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function (data) {
},
fail: function (err) {
uni.showToast({
title:err,
icon:'none'
})
}
}
});
可能的问题this.getImgSrc()未获取到数据url 必须是一个数组http的原因 Ios端只支持httpshttps本来就显示的,wifi中有配置代理,导致ssl证书不过(1.取消代理,2.切换使用数据,退出重新登录)(可以通过把https加载到图片地址中,报错就替换成http)3.uni.showModal() 中content内容换行可以使用“\r\n”换行 在真机预览中查看效果 uni.showModal({
content:"内容:\r\n 1.工作重点 \r\n 2.注意事项",
showCancel:false,
confirmText:'知道了',
success:()=>{
}
})
4. 把二进制流数据转换成base64格式 const param ={}
//
arrayBuffer
uni.request({})
要带有 responseType: arraybuffer请求头
this.$api.Http(mineQrcode, 'get',param,'arrayBuffer').then(r => {
let arrayBuffer = new Uint8Array(r.data)
this.imageList = 'data:image/jpg;base64,' + uni.arrayBufferToBase64(arrayBuffer);
}
}