第一:第三方支付原理

第二:支付接口申请流程

地址:https://docs.open.alipay.com/270/105899/ ;

参考地址:https://blog.csdn.net/november22/article/details/54233269#comments

1. 注册是支付宝商家账号 —— 注册地址:https://memberprod.alipay.com/account/reg/index.htm;

2. 注册成功后,找到蚂蚁金服开放平台,点击支付应用

3、创建应用

4、 添加应用中的电脑支付功能

5、开发配置

说明:

(1)其中的支付宝网关地址不用改;

(2)应用网关设置为你网站的域名(如:https://www.xxx.com/),所以这个位置的设置就决定了你的网站首先要上线、然后域           名解析到服务器上才可以申请支付宝的支付接口;

(3)授权回调地址不用设置,一般如果涉及到第三方访问应用的时候才需要设置;

(4)设置应用公钥 —— 获取应用公钥【支付宝公钥】和私钥【商户私钥】的参考文档。

下载地址:https://docs.open.alipay.com/291/105971

下载、解压,然后生成秘钥,注意:文件夹的目录中一定不能带有中文字符吗,不然工具不能使用,这个步骤我就不一步步的说了。,将生成的公钥如下图,配置到查看应用公钥那儿,第一次登陆的应该现实的是配置公钥。点击确定,然后会生成支付宝公钥【这里一定 不要配置错误了,不然后面的程序会跑不起来的】

6、 当配置好后,直接提交审核,之后就等待审核了。

7、配置参数

1.  app_id :应用ID,在这个地址中查看:https://openhome.alipay.com/platform/keyManage.htm;2. merchant_private_key:商户私钥。这个在获取应用公钥和私钥时就已经获取到,公钥上传到支付宝中,私钥就在项目中与之匹配验证;3. notify_url : 异步通知回调地址。支付成功后,支付宝回调服务器的地址;4. return_url:同步跳转地址。支付成功回调了服务器的地址后,自动跳转到目标地址;5. charset:编码格式,一般为“UTF-8”;6. sign_type:签名方式,一般为“RSA2”;7. gatewayUrl:支付宝网关,https://openapi.alipay.com/gateway.do;8. alipay_public_key:支付宝公钥,在这个地址查看:https://openhome.alipay.com/platform/keyManage.htm。

第三:PC扫码支付实现【以TP5为例】

1、下载支付宝支付demo,下载地址:https://docs.open.alipay.com/270/106291/;

2、解压放入Vendor文件夹下

3、在配置文件中配置支付宝配置参数

【app_id、alipay_public_key、merchant_private_key、charset、sign_type、alipay_public_key与APP支付宝支付的配置参数一致】

'alipay' => [//应用ID,您的APPID。'app_id' => "",//商户私钥'merchant_private_key' => "",//异步通知地址'notify_url' => \think\Request::instance()->domain()."/order/pay/alipay_notify",//同步跳转'return_url' => \think\Request::instance()->domain()."/order/pay/alipay_notify",//编码格式'charset' => "UTF-8",//签名方式'sign_type'=>"RSA2",//支付宝网关'gatewayUrl' => "https://openapi.alipay.com/gateway.do",//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。'alipay_public_key' => "",],

4、生成支付二维码

 // 支付public function orderpay($ordersn){$config = Config::get('alipay');$order = db('shop_order');$where = ['uid'=>$this->uid,'ordersn'=>$ordersn];$orderinfo = $order->field('ordersn,pay_price,status')->where($where)->find();if(empty($orderinfo)) return $this->error('抱歉,指定订单找不到!');if($orderinfo['status']==1) return $this->error('订单已支付成功,请前往订单中心查看!');//商户订单号,商户网站订单系统中唯一订单号,必填$out_trade_no = trim($orderinfo['ordersn']);//订单名称,必填$subject = empty($orderinfo['title']) ? '购买雄松智课课程' : $orderinfo;//付款金额,必填$total_amount = trim($orderinfo['pay_price']);//商品描述,可空$body = empty($orderinfo['remark']) ? '' : $orderinfo['remark'];Vendor('alipay.AopSdk');Vendor('alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder');Vendor('alipay.pagepay.service.AlipayTradeService');// 构造参数$payRequestBuilder = new \AlipayTradePagePayContentBuilder();$payRequestBuilder->setBody($body);$payRequestBuilder->setSubject($subject);$payRequestBuilder->setTotalAmount($total_amount);$payRequestBuilder->setOutTradeNo($out_trade_no);$aop = new \AlipayTradeService($config);/*** pagePay 电脑网站支付请求* @param $builder 业务参数,使用buildmodel中的对象生成。* @param $return_url 同步跳转地址,公网可以访问* @param $notify_url 异步通知地址,公网可以访问* @return $response 支付宝返回的信息*/$response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);//输出二维码// var_dump($response);}

HTML代码:

<div class="outer-wrap"><div class="inner-wrap"><p class="order-txt">订单提交成功!订单号:<span id="ordersn">{$ordersn}</span></p><div class="xzyhq-wrap wx_pay" style="display:none"><div class="zf-wrap"><span class="zf-wrap-txt1">微信支付</span><span class="zf-wrap-txt2">距离二维码过期还剩<i id="count_down">60</i>秒,过期后请刷新页面重新获取二维码。</span></div><div class="syt-content"><img src="/static/mba/images/syt_wxzf_ewm.png"/></div></div><div class="xzyhq-wrap"><div class="xzyhq-title">选择其他支付方式</div><div class="xzzf-list-wrap"><div class="xzzf-list-inner"><div class="xzzf-list xzzf-list2" data-flag="wechatpay"><i class="xxzf-icon"></i><span>微信支付</span></div><div class="xzzf-list" data-flag="alipay"><i class="zfb-icon"></i><span>支付宝支付</span></div><div class="xzzf-list margin-r0" data-flag="bank_cart"><i class="yhk-icon"></i><span>银行卡支付</span></div>    </div></div></div></div></div>

JavaScript代码:

JavaScript:
$(".xzzf-list").on("click",function(){var paytype=$(this).attr('data-flag');if (paytype=='wechatpay') {$('.wx_pay').css('display','block');default_paytype();}else if(paytype == 'alipay'){$('.wx_pay').css('display','none');if(pay_flag){window.clearInterval(paycheck); //销毁定时器}var url = "{:url('order/pay/orderpay')}";var ordersn = $("#ordersn").html();console.log(ordersn);url += '?ordersn=' + ordersn;window.location.href=url;}else{}
});

5、支付宝回调,更新支付状态

public function alipay_notify(){$arr = Request::instance()->param(); //file_get_contents("php://input");empty($arr) ? $arr=$_GET : $arr;$config = Config::get('alipay');Vendor('alipay.pagepay.service.AlipayTradeService');$alipaySevice = new \AlipayTradeService($config);$result = $alipaySevice->check($arr);/* 实际验证过程建议商户添加以下校验。1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)4、验证app_id是否为该商户本身。*/if($result) {//验证成功//请在这里加上商户的业务逻辑程序代//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——//获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表//商户订单号$out_trade_no = $arr['out_trade_no'];//支付宝交易号$trade_no = $arr['trade_no'];// 交易金额$money = $arr['total_amount'];$order = db('shop_order');$order_info = $order->where("ordersn='{$out_trade_no}'")->find();// 判断是否是同一订单if($out_trade_no != $order_info['ordersn']){//验证失败echo "fail";}if($money == $order_info['pay_price']){if($order_info['status'] == 0){//更新支付状态和支付时间$OrderObj = new Order();$result = $OrderObj->UpdateOrder($order_info['ordersn'],1);}if(empty($out_trade_no)) $this->error('订单状态已改变,请到个人中心查看!');$OrderObj = new Order();$order = $OrderObj->GetOneOrder($out_trade_no,$this->uid);if(empty($order)) $this->error('订单状态已改变,请到个人中心查看!');$this->assign('order',$order);return view('pay/ordersuccess');}else{//验证失败echo "fail";}echo "success"; //请不要修改或删除}else {//验证失败echo "fail";}}

第四:APP实现支付宝支付接口

参考:https://www.jianshu.com/p/178324ca2561

APP官方文档:https://docs.open.alipay.com/204/105465/

1、配置config文件的信息

【app_id、alipay_public_key、merchant_private_key、charset、sign_type、alipay_public_key与PC端扫码支付的配置参数一致】

'appAlipay' => [//应用ID,您的APPID。'app_id' => "",//  //商户私钥'merchant_private_key' => "",//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。'alipay_public_key' => "",//异步通知地址【设置该接口无需token验证】'notify_url' => \think\Request::instance()- >domain()."/app/paynotify/alipy_notify",//同步跳转【设置该接口无需token验证】'return_url' => \think\Request::instance()- >domain()."/app/paynotify/alipy_notify",//编码格式'charset' => "UTF-8",//签名方式'sign_type'=>"RSA2",//支付宝网关'gatewayUrl' => "https://openapi.alipay.com/gateway.do",//收款支付宝用户ID。 如果该值为空,则默认为商户签约账号对应的支付宝用户ID'seller_id' => '',//商品信息'body'=>"雄松智课",//商品信息'subject'=>"智课方案",'format' =>'json',],

2、商户APP端请求商户服务器接口,提交订单数据。

3、商户服务器端接收数据,然后对数据进行签名,返回请求参数到商户APP端

//引入Alipay的SDK
vendor('alipay/aop/AopClient');
vendor('alipay/aop/request/AlipayTradeAppPayRequest');/*** 支付宝支付[添加订单],商户服务器端接收数据,对数据进行签名,返回请求参数到商户APP端*/public function aliBuyPlans(){$rule = ['orderSn'    => 'require','plans'      => 'require','payPrice'   => 'require|float|egt:0.01',];$msg = ['orderSn.require'   => '订单号不能为空','plans.require'     => '请选择购买方案信息','payPrice.require'  => '请填写正确的金额','payPrice.float'    => '请填写正确的金额',];//验证$data = $this->params;$validate = new Validate($rule, $msg);!$validate->check($data) and $this->returnError($validate->getError());//购买方案$uid = $this->user['id'];$data['payPrice'] = number_format($data['payPrice'],2);$plans  = json_decode(htmlspecialchars_decode($this->params['plans']), true);if (!is_array($plans)) $this->returnError('方案信息格式错误');// 启动事务Db::startTrans();$title = '推荐方案';$body = config('appAlipay.body');$subject = config('appAlipay.subject');$orderModel = new OrderModel();$orderInfo = $orderModel->checkOrdsn($data['orderSn'], $uid);// 该订单号不存在if (empty($orderInfo)){$orderid = (int)$orderModel->addOrder($uid, $data['orderSn'], $data['payPrice'], 1, $title,0);$flag = $orderModel->addOrderGoods($uid, $orderid, $plans);if ($flag){// 提交事务Db::commit();$wxData['orderId'] = $orderid;$wxData['orderSn'] = $data['orderSn'];//数据进行签名,返回请求参数到商户APP端$orderString = $this->alipay($body, $subject, $data['orderSn'], $data['payPrice']);$wxData['orderString'] = $orderString;$this->returnSuccess('添加订单成功',$wxData);}else{// 回滚事务Db::rollback();$this->returnError('添加订单失败');}}else{$wxData['orderId'] = $orderInfo['id'];$wxData['orderSn'] = $orderInfo['ordersn'];//数据进行签名,返回请求参数到商户APP端$orderString = $this->alipay($body, $subject, $data['orderSn'], $data['payPrice']);$wxData['orderString'] = $orderString;$this->returnSuccess('添加订单成功',$wxData);}}/*** 对数据进行签名,返回请求参数到商户APP端* @param string $body 商品描述* @param string $subject 商品名称* @param string $outTradeNo 交易订单号* @param float $totalAmount 支付金额*/protected function alipay($body, $subject, $outTradeNo, $totalAmount){$aop = new \AopClient();//正式环境网关 https://openapi.alipay.com/gateway.do$aop->gatewayUrl = config('appAlipay.gatewayUrl');//沙箱环境网关$aop->format = "json";$aop->charset = "UTF-8";$aop->signType = "RSA2";$aop->appId = config('appAlipay.app_id');$aop->rsaPrivateKey = config('appAlipay.merchant_private_key');//rsaPrivateKey私钥$aop->alipayrsaPublicKey = config('appAlipay.alipay_public_key');//alipayrsaPublicKey请填写支付宝公钥//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay$request = new \AlipayTradeAppPayRequest();//SDK已经封装掉了公共参数,这里只需要传入业务参数$bizcontent =  "{\"body\":\"{$body}\",". "\"subject\": \"{$subject}\",". "\"out_trade_no\": \"{$outTradeNo}\",". "\"timeout_express\": \"30m\",". "\"total_amount\": \"{$totalAmount}\",". "\"product_code\":\"QUICK_MSECURITY_PAY\"". "}";$request->setNotifyUrl(config('appAlipay.notify_url'));//异步通知地址$request->setBizContent($bizcontent);//这里和普通的接口调用不同,使用的是sdkExecute,sdkExecute()方法,作用生成签名,$response = $aop->sdkExecute($request);//htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,//实际打印到日志以及http传输不会有这个问题//就是orderString 可以直接给客户端请求,无需再做处理。//$response =  json_encode(array("res"=>htmlspecialchars($response)));return $response;}

说明:sdkExecute()方法,作用生成签名,详细步骤如下:

将请求参数组装分下列3步,以最后第三步获取到的请求为准。

1)将请求参数的键按字典排序,然后按照key=value&key=value方式拼接,得到未签名原始字符串如下:

app_id=2015052600090779&biz_content={"timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"IQJZSRC1YMQB5HU"}&charset=utf-8&format=json&method=alipay.trade.app.pay&notify_url=http://domain.merchant.com/payment_notify&sign_type=RSA2&timestamp=2016-08-25 20:26:31&version=1.0

2)再对原始字符串进行签名

app_id=2015052600090779&biz_content={"timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"IQJZSRC1YMQB5HU"}&charset=utf-8&format=json&method=alipay.trade.app.pay&notify_url=http://domain.merchant.com/payment_notify&sign_type=RSA2&timestamp=2016-08-25 20:26:31&version=1.0&sign=cYmuUnKi5QdBsoZEAbMXVMmRWjsuUj+y48A2DvWAVVBuYkiBj13CFDHu2vZQvmOfkjE0YqCUQE04kqm9Xg3tIX8tPeIGIFtsIyp/M45w1ZsDOiduBbduGfRo1XRsvAyVAv2hCrBLLrDI5Vi7uZZ77Lo5J0PpUUWwyQGt0M4cj8g=

3)最后对请求字符串的所有一级value(biz_content作为一个value)进行encode,编码格式按请求串中的charset为准,没传charset按UTF-8处理,获得最终的请求字符串:

app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22IQJZSRC1YMQB5HU%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fdomain.merchant.com%2Fpayment_notify&sign_type=RSA2&timestamp=2016-08-25%2020%3A26%3A31&version=1.0&sign=cYmuUnKi5QdBsoZEAbMXVMmRWjsuUj%2By48A2DvWAVVBuYkiBj13CFDHu2vZQvmOfkjE0YqCUQE04kqm9Xg3tIX8tPeIGIFtsIyp%2FM45w1ZsDOiduBbduGfRo1XRsvAyVAv2hCrBLLrDI5Vi7uZZ77Lo5J0PpUUWwyQGt0M4cj8g%3D

4、商户APP接收从商户服务器端返回的请求参数,然后调起支付宝支付面板。

若用户支付成功,支付宝会同步给商户APP端返回一个支付结果。相应地,支付宝也会通过异步通知给商户服务器端返回一个支付结果。

注意:由于同步通知和异步通知都可以作为支付完成的凭证,且异步通知支付宝一定会确保发送给商户服务端。为了简化集成流程,商户可以将同步结果仅仅作为一个支付结束的通知(忽略执行校验),实际支付是否成功,完全依赖服务端异步通知。

5、服务端异步通知处理机制(支付宝主动发起通知,该方式才会被启用)

官方接口文档:https://docs.open.alipay.com/204/105301/

注意点:

1)必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;

2)支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如:$_POST[‘out_trade_no’];

3)程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);

4)当商户收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。

/*** 支付异步通知*/public function notify(){$aop = new \AopClient;$aop->alipayrsaPublicKey = config('alipay.alipay_public_key');$flag = $aop->rsaCheckV1($_POST, NULL, "RSA2");if($flag){//校验通知数据的正确性$out_trade_no = $_POST['out_trade_no'];  //商户订单号$trade_no = $_POST['trade_no'];          //支付宝交易号$trade_status = $_POST['trade_status'];  //交易状态$total_amount = $_POST['total_amount'];  //订单的实际金额$app_id = $_POST['app_id'];//验证app_id是否为该商户本身if($app_id != $this->config['app_id']){echo 'fail';}//只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。if ($trade_status != 'TRADE_FINISHED' && $trade_status != 'TRADE_SUCCESS'){echo 'fail';}//校验订单的正确性if(!empty($out_trade_no)){//1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号;//2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额);//3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)。//上述1、2、3有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。//校验成功后在response中返回success,校验失败返回failure}echo 'fail';}echo 'fail';//验证签名失败}

6、当商户APP端接收到支付宝的同步返回结果为成功时,商户APP端再请求商户服务器端API,判断订单最终支付结果,并做出最终响应。

第五:微信公众号接入支付宝支付

地址:https://www.cnblogs.com/luokakale/p/8029614.html

PHP 支付PC端扫码支付、APP接口调起支付宝支付、微信公众号接入支付宝支付相关推荐

  1. php 微信公众号接入支付宝支付

    真是无力吐槽这个需求了,好端端的非要在微信公众号接入支付宝,都知道微信公众号是拒绝支付宝的,屏蔽了支付宝,所以在微信公众号接入支付宝的话就必须手动复制链接跳出微信内置浏览器,强制性打开web浏览器完成 ...

  2. 微信公众号接入H5支付

    一.概述 1.H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付.主要用于触屏版的手机浏览器请求微信支付的场景.可以方便的 ...

  3. php接入微信支付宝支付,php 微信公众号接入支付宝支付

    首先登录支付宝开发者平台申请接入了,如下图: 创建应用查看,添加APP支付功能,需要签约上线,如图: 本人主要用到了demo_get.htm和pay.htm,加上ap.js来实现的,pdf仅做参考,可 ...

  4. 微信支付—微信H5支付「PC端扫码支付」

    前言 微信支付-微信H5外部浏览器支付 微信支付-微信H5内部浏览器支付 微信支付-PC端扫码支付「本文」 本篇是微信支付系列的第三篇,PC端扫码支付. 开发环境:Java + SpringBoot ...

  5. 微信公众号:支付宝支付

    微信公众号:支付宝支付 微信公众号:支付宝支付 由于支付宝月微信是两个对立的企业,支付宝想介入微信的充值,微信发现就将其规避,在支付宝与微信博弈的过程中,双方一直是处于你争我赶的地步. 微信公众号接入 ...

  6. Java后端对接微信支付(微信小程序、APP、PC端扫码)非常全,包含查单、退款

    首先我们要明确目标,我们点击 微信支付官网 ,我们主要聚焦于这三种支付方式,其中JSPAI与APP主要与uniapp开发微信小程序与APP对接,而NATIVE主要与网页端扫码支付对接 1.三种支付统一 ...

  7. 微信PC端扫码支付 java 模式二的扫码支付

    前言 这次分享的是java对接微信的支付接口,实现电脑端扫码支付后,跳转支付成功页面的例子.之所以分享是微信的Api太坑了.留下的文档也少,对接过程中容易出现各种各样的问题,在实现这扫码支付功能的时候 ...

  8. 支付宝支付-支付宝PC端扫码支付

    前言 支付宝支付-沙箱环境使用 支付宝支付-支付宝PC端扫码支付「本文」 支付宝支付-手机浏览器H5支付「待写」 PC端扫码支付,其实就是就是 电脑网站支付,本文基于支付宝沙箱环境,不了解的可以看一下 ...

  9. JAVA PC端扫码支付(一)微信支付

    微信支付从配置到开发 一.配置 1.开通公众平台支付功能 商户号 微信支付功能先要申请微信(企业)公众平台,然后开通企业公众平台付功能.下图为微信(企业)公众平台页面,可以看到商户号等信息 微信公众号 ...

最新文章

  1. Linux 启动过程详解
  2. ajax post 参数说明
  3. ecmall挂件开发
  4. 常见的问题:https://localhost:1158/em 无法打开
  5. 嵌入式Linux系统编程学习之二十八线程的等待退出
  6. python实现以及所有排序大总结【转】
  7. angular分页插件tm.pagination 解决触发二次请求的问题
  8. python color属性_Python turtle.color方法代码示例
  9. Android【报错】. lang。android.app ClassCastException。SharedPreferencesImpl不能被强制转换为android.content.Shared
  10. docker-machine 下载iso慢的问题
  11. Java 常见面试题
  12. Win10 最下面的任务栏不显示正在打开的窗口了,打开任何东西任务栏都不显示
  13. C语言编程练习:约分最简分式
  14. Python量化分析财务指标,教你用净资产收益率选股!
  15. python之数据库-表操作
  16. textureview 放大缩小的坑
  17. python字典键盘添加元素_对python字典元素的添加与修改方法详解
  18. 关于svchost占用巨大内存的问题
  19. 知了堂笔记之html+CSS动画万花筒
  20. 解析 EXCEL 去重

热门文章

  1. VMware Workstation Pro安装教程
  2. HANDLE 和 COORD
  3. redis做mysql缓存的优点_面试官:如何保障数据库和redis缓存的一致性
  4. 卸载java时遇见的问题
  5. 为什么与Yes乐队最相似的歌手是Coda(小田和奏)?
  6. Java源码分析 AbstractList的迭代器实现(Itr和ListItr)
  7. 如何设计一个完整的交互流程,提升产品用户体验
  8. 【Python爬虫】百度指数爬取+导入数据库+QuickBI展示
  9. 昨天、今天、明天的写法
  10. textmeshpro文字有阴影