2018-03-20 00:52:10 nookl 阅读数 5101
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27864 人正在学习 去看看 秦子恒

以windows7系统为例,首先点击右下角的微软图标,在下面的搜索框中输入regedit。按照这个目录依次展看:HKEY_CURRENT_USER / Software / Microsoft / Windows / CurrentVersion / Internet_Settings,找到右侧以代理开头的名称全部删掉。注销电脑就好了!

2018-11-01 19:23:07 qq_15556155 阅读数 398
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27864 人正在学习 去看看 秦子恒

开发工具:微信开发者工具,Intellij idea 2018

框架:spring boot 

交易流程图:

下面直接上代码:

1.在wxml添加一个支付按钮,点击监听payMethod方法

<view><button bindtap='payMethod'>支付</button></view>

2.payMethod方法种调用wx.login微信接口,获取code。调用getOpenId方法

/**
   *  支付例子
   * const config = require('../../config')获取全局配置
   * const appInstance = getApp();获取全局上下文实例
   */
  payMethod(){
    let _this = this ;//当前上下文
    //获取登录code  
    wx.login({
      success: result =>{
        console.info(result.code)
        //获取openid 
        _this.getOpenId(result.code) 
      }
    }); 
  },

3.将code作为参数,请求Java服务,获取openId

 /**
   * 用code作为参数请求Java服务,像微信服务换取openId,access_token
   * 此处用到openId,access_token暂时无用,为安全起见,此字段不返回客户端
   */
  getOpenId(code){
    let _this = this;//当前上下文
    wx.request({
      url: config.localServer + 'api/wc/jscode2session.wc',
      data: { code: code},
      method: 'POST',
      success: result =>{
        console.info('返回openId')
        console.info(result.data)
        _this.generateOrder(result.data.data.openid)
      },
      fail:() => {
        console.info('fail')
      },
      complete: () => {
        // complete 
      }
    }) 
  },

4.Java服务jscode2session接口,调用微信sns/jscode2session服务,获取openId,将openid返回给小程序客户端

/**
     * 换取 用户唯一标识 OpenID 和 会话密钥 session_key   ->>>  oopenid 和 session_key 组成会话标识,发给客户端,客户端凭借这个标识进行通信
     * 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。
     * 为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
     * 临时登录凭证 code 只能使用一次
     * @param request
     * @param requestEntity
     * @param code
     * @return
     */
    @PostMapping("/jscode2session.wc")
    public ResponseBean jscode2session(HttpServletRequest request, HttpEntity<String> requestEntity,String code) {

        HttpMethod requestMethod = HttpMethod.resolve(request.getMethod());
        String body = requestEntity.getBody();
        Map<String,String> mapParam = JacksonUtil.fromJson(body,Map.class);
        code = mapParam.get("code");
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        requestEntity = new HttpEntity<>(requestEntity.getBody(), headers);

        ResponseEntity<String> response = null;
        response = restTemplate.exchange(
                wcHost+"sns/jscode2session?appid=wxd0ad6e09b4f09a2a&secret=919f06b91b6adbe682c0bd9edc0a008f&js_code="+code+"&grant_type=authorization_code",
                requestMethod,
                requestEntity,
                String.class);

        String result =  response.getBody();
        LOGGER.info("result="+result);
        Map<String,String> mapResult = JacksonUtil.fromJson(result,Map.class);
        return ResponseBean.response(mapResult);

    }

5.小程序获取openid,调用generateOrder方法,生成订单信息,调用Java服务payOrderPublic.wc接口,以获取支付参数

/**
   * 用openid,在Java服务请求微信服务,获取支付的请求参数
   */
  generateOrder(openid){
    var _this = this 

    var paymentPo={
      openid: openid,
      total_fee: '0.1',
      mch_id: 'mch_id',
      body: '支付测试',
      detail: 'detail',
      attach: '假酒'
    }

    wx.request({
      url: config.localServer + 'api/wc/payOrderPublic.wc',
      method: 'POST',
      data: paymentPo,
      success: result => {
        console.info(result)
        var pay = result.data.data
        //发起支付 
        var timeStamp = pay[0].timeStamp;
        console.info("timeStamp:" + timeStamp)
        var packages = pay[0].package;
        console.info("package:" + packages)
        var paySign = pay[0].paySign;
        console.info("paySign:" + paySign)
        var nonceStr = pay[0].nonceStr;
        console.info("nonceStr:" + nonceStr)
        var param = { "timeStamp": timeStamp, "package": packages, "paySign": paySign, "signType": "MD5", "nonceStr": nonceStr };
        _this.pay(param)
      },
    }) 
  },

6.Java服务payOrderPublic.wc接口,将参数生成签名,打包成xml格式,请求微信的统一下单接口/pay/unifiedorder,将获取的结果进行再次签名,得到支付接口需要的参数,返回给小程序客户端。

/**
     *  商户server调用支付统一下单
//     * @param openid 用户唯一标识
//     * @param mch_id 商品编号
//     * @param total_fee 商品价格
//     * @param body 商品描述
//     * @param detail 商品详情
//     * @param attach 附加数据
//     * @param time_start 交易开始时间
//     * @param time_expire 交易结束时间
     * @return
     */
    @PostMapping("/payOrderPublic.wc")
    public ResponseBean  payOrderPublic(HttpServletRequest request,HttpEntity<String> requestEntity,PaymentPo paymentPo) throws UnsupportedEncodingException, DocumentException {

        paymentPo = JacksonUtil.fromJson(requestEntity.getBody(),PaymentPo.class);
        paymentPo.setBody(new String(paymentPo.getBody().getBytes("UTF-8"),"ISO-8859-1")) ;
//        String appid = "替换为自己的小程序ID";//小程序ID
        //当前时间
        String today = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        //生成8位随机数
        String code = PayUtil.createCode(8);
        //商户订单号
        String out_trade_no = paymentPo.getMch_id()+today+code;//商户订单号
        String spbill_create_ip = HttpUtil.getIpAddress(request);//终端IP
        String notify_url = "http://www.weixin.qq.com/wxpay/pay.php";//通知地址
        String trade_type = "JSAPI";//交易类型

        paymentPo.setAppid(appid);
        //随机字符串 32位
        String str=UUIDHexGeneratorUtil.generate();
        paymentPo.setNonce_str(str);
        paymentPo.setOut_trade_no(out_trade_no);
        paymentPo.setSpbill_create_ip(spbill_create_ip);
        paymentPo.setNotify_url(notify_url);
        paymentPo.setTrade_type(trade_type);

        // 把请求参数放进hashmap
        Map<String,String> sParaTemp = new HashMap<String,String>();
        sParaTemp.put("appid", paymentPo.getAppid());
        sParaTemp.put("mch_id", paymentPo.getMch_id());
        sParaTemp.put("nonce_str", paymentPo.getNonce_str());
        sParaTemp.put("body",  paymentPo.getBody());
        sParaTemp.put("out_trade_no", paymentPo.getOut_trade_no());
        sParaTemp.put("total_fee",paymentPo.getTotal_fee());
        sParaTemp.put("spbill_create_ip", paymentPo.getSpbill_create_ip());
        sParaTemp.put("notify_url",paymentPo.getNotify_url());
        sParaTemp.put("trade_type", paymentPo.getTrade_type());
        sParaTemp.put("openid", paymentPo.getOpenid());

        // 除去map中的空值和签名参数
        Map<String,String> sPara = PayUtil.paraFilter(sParaTemp);
        // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
        String prestr = PayUtil.createLinkString(sPara);
        String key = "&key=替换为商户支付密钥"; // 商户支付密钥
        //MD5运算生成签名
        String mysign = PayUtil.sign(prestr, key, "utf-8").toUpperCase();
        paymentPo.setSign(mysign);
        //打包要发送的xml
        String respXml = MessageUtil.messageToXML(paymentPo);
        // 打印respXml发现,得到的xml中有“__”不对,应该替换成“_”
        respXml = respXml.replace("__", "_");
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//统一下单API接口链接
        String param = respXml;
        String result =PayUtil.httpRequest(url, "POST", param);
        // 将解析结果存储在HashMap中
        Map<String,String> map = new HashMap<String,String>();
        InputStream in = new ByteArrayInputStream(result.getBytes());
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(in);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        @SuppressWarnings("unchecked")
        List<Element> elementList = root.elements();
        for (Element element : elementList) {
            map.put(element.getName(), element.getText());
        }
        // 返回信息
        String return_code = map.get("return_code");//返回状态码
        String return_msg = map.get("return_msg");//返回信息
        System.out.println("return_msg"+return_msg);
        Map<String,Object> resultMap = new HashMap<String,Object>();
        if(return_code=="SUCCESS"||return_code.equals(return_code)){
            // 业务结果
            String prepay_id = map.get("prepay_id");//返回的预付单信息
            String nonceStr=UUIDHexGeneratorUtil.generate();
            resultMap.put("nonceStr", nonceStr);
            resultMap.put("package", "prepay_id="+prepay_id);
            Long timeStamp= System.currentTimeMillis()/1000;
            resultMap.put("timeStamp", timeStamp+"");
            String stringSignTemp = "appId="+appid+"&nonceStr=" + nonceStr + "&package=prepay_id=" + prepay_id+ "&signType=MD5&timeStamp=" + timeStamp;
            //再次签名
            String paySign=PayUtil.sign(stringSignTemp, "&key=替换为自己的密钥", "utf-8").toUpperCase();
            resultMap.put("paySign", paySign);
        }
            return ResponseBean.response(resultMap) ;
    }

7.小程序端得到支付参数,用pay方法调用微信的支付接口,完成支付

/**
   * 支付的动作
   */
  pay(param){
    console.info("支付")
    console.info(param)
    wx.requestPayment({
      timeStamp: param.timeStamp,
      nonceStr: param.nonceStr,
      package: param.package,
      signType: param.signType,
      paySign: param.paySign,
      success: (result) => {
        console.info("支付")
        console.info(result)
     
      },
      fail: (result) => {
        console.info("支付失败")
        console.info(result)
      },
      complete: () => {
        console.info("pay complete")
      }
    }) 
  }

 

2015-11-30 20:30:24 yueqian_scut 阅读数 10281
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27864 人正在学习 去看看 秦子恒

         微信硬件平台使用蓝牙作为近场控制的连接件,并拟定了《微信蓝牙外设协议》。这份协议更像一个标准,用于规范微信和蓝牙外设之间的数据交互场景和接口。但从开发者来看,要完全读懂这份协议,恐怕需要熟读很多遍,并且要结合调试才能真正实现微信Airsync通信。笔者对IOT和微信硬件平台的整个框架和技术都比较熟悉了,并且已经在TI的CC254X和Dialog的DA14580上实现了微信Airsync协议通信。现在回过头来,从开发的角度,对微信Airsync协议进行重新解读,以帮助新进入物联网领域的开发者更快地掌握微信蓝牙设备通信开发,以让产品快速接入微信硬件平台。

       有关微信硬件平台和物联网的架构分析请参考笔者之前的博文,特别是《一张图读懂基于微信硬件平台的物联网架构》和《基于微信硬件公众平台的智能控制开发流程》。

一、微信蓝牙物联的技术需求

软件和协议都是需求驱动的。在物联网、移动互联网领域,理解场景是提炼需求的重要方法。那么,我们从场景分析的角度来理解微信硬件平台的蓝牙物联需求。

1.     微信蓝牙物联是一种近场控制场景

微信硬件平台支持蓝牙和Wifi/3G/GPRS接入。Wifi/3G/GPRS是一种远场控制手段,只要网络可达,那么用户可以在远场(例如办公场所)控制离用户距离很远(例如家里)的物联设备。而蓝牙接入则是一种近场控制手段,用户只能利用微信通过手机的蓝牙来控制20米左右的蓝牙设备。也即是,当蓝牙设备离开手机蓝牙的连接范围,那么用户是控制不了该设备的。

对于蓝牙外设来说,手机就像一个蓝牙网关一样,手机通过蓝牙来跟蓝牙外设进行通信,将得到的数据通过手机的wifi或者3G/4G信号与云后端(微信公众平台、第三方云服务端)交互。前者是基于微信Airsync协议,后者则是微信制定的基于TCP/IP协议的《设备接入接口协议》。

2.     蓝牙外设身份注册

微信硬件平台只提供两部分核心的物联功能,一是身份管理,二是消息推送。任何一个外设,不管是蓝牙还是wifi,它都将拥有一个唯一的设备ID。设备ID的相关描述请参考《一张图读懂基于微信硬件平台的物联网架构》,其包括设备类型(设备厂商的公众号ID)和该设备厂商自行定义的设备ID。这种设计手段和蓝牙MAC地址、网卡MAC地址的设置是一样的。设备ID就是外设的身份。

在外设向微信硬件平台注册身份前,微信硬件平台是不认识这个外设的。所以,我们在使用蓝牙外设前,需要向微信硬件平台注册身份。

对于微信硬件平台而言,设备注册其实就是平台对这个设备进行授权(加入)的过程。接口如下图。其主要通过提交自身的唯一MAC、设备ID来向平台注册。


3.     蓝牙广播

对于蓝牙设备来说,它主要的状态包括未连接和已连接两种状态。在未连接时,它需要进行广播。广播的目的是为了让手机微信能够通过蓝牙扫描得知这是一个支持蓝牙Airsync协议的设备。当手机微信识别到是一个支持该协议的外设时,手机微信会发起连接。

那么,广播数据需要包含什么格式的数据才能被手机微信所识别到呢?这就是蓝牙Airsync协议规定的内容。

4.     蓝牙通信

蓝牙连接之后,自然是数据通信的需求。对蓝牙BLE来说,数据通信都是通过访问某个characteristics来实现的。而characteristics需要支持以下场景:

1)手机微信对外设进行写控制,要求characteristics的write属性。

2)手机微信读取外设的一些信息。当外设和厂商自己研制的APP连上之后,外设处于连接状态,其不会再发出广播信息,此时微信想去连接这个外设怎么办?其是通过读取外设的信息,如MAC,来判断该外设是否支持微信。这要求characteristics的read属性。

以上两种都是手机微信作为主动方,外设是被动。接下来,我们来看看外设是主动时的场景:

3)例如,运动手环需要主动上报用户某个时段的运动步数。在这种情况下,手机微信主动读取运动步数显然是不合适的,因为手机不应该时时刻刻地读这个步数来更新。而应该是手机微信订阅characteristics的信息更新服务,即作为被动方接受外设的信息更新。

对于蓝牙外设来说,characteristics的信息更新有两种,一种是notify,一种是indicate。他们有什么区别呢?对于notify,当蓝牙外设的characteristics的值有变化时,它会主动将新的值告知手机微信,而手机微信收到这个信息更新时不需要回复。而对于indicate属性,手机微信在收到这个信息时需要给蓝牙外设一个简单的回复。

蓝牙BLE通信的characteristics的长度是有限制的,或者说每一帧数据长度是有限的,是20字节。那么,如果蓝牙外设有一串很长的数据要主动传送,很明显,它需要indicate属性才能完成这个任务,即将这段数据按20字节长度进行分帧,每次更新发送之后,需要等手机微信回复之后才能发下一个20字节,直到发完为止。

二、蓝牙微信Airsync协议开发

根据以上对蓝牙微信物联的技术需求分析,再根据蓝牙BLE的应用开发知识,我们来梳理蓝牙微信Airsync协议的开发要点。

1.     广播

蓝牙外设广播的目的是让手机微信能够识别到。微信Airsync协议是这样规定蓝牙外设广播数据格式的:

1) 声明自己的ServiceUUID是0xFEE7。

2) 在自定义厂商数据manufature specific data中需以MAC地址(身份注册时的MAC地址,也是该设备真实的MAC地址)结尾,并且要求manufature specific data的长度大于等于8.

蓝牙的广播数据格式定义请参考《Blutoothspecification 4.0》的P1735页,对应以下两个类型:

另外,微信Airsync协议提到广播设备分为两种,一种是普通设备,没有按钮,需要无时无刻地广播数据;另一种是确认设备,即有按钮,即用户按下按钮后才开始广播数据。事实上,现实生活中为了省功耗,不可能时时刻刻都在广播的,都是在用户拿手机过来后,再按下外设按钮之后才开始广播并连接的。但是微信把这种方式称为确认设备会造成困惑啊,又没解释清楚,以为广播之后还要确认什么的。这里明确解释这一点。

对于确认按钮之后的广播数据需要注意的是,在自定义厂商数据manufature specific data中需以0xfe 0x01 0x01 +MAC地址结尾。

2.     蓝牙通信服务

外设要实现以下特征,并根据具体芯片平台的接口实现各特征字的读写回调过程,以实现具体的应用需求。

即写characteristics的UUID是0xfec7, indicate characteristics的UUID是0xfec8. 这两个是必须的。而read characteristics UUID不支持也没有问题。

3.     蓝牙Airsync协议交互

满足以上两个条件代表已经能够跟手机微信进行数据通信了。但是交互过程是一个协作的过程,就像我们访问业务系统一样也要先登陆,再初始化后,才能进行正常的业务通信啊。那么登陆和初始化我们可以理解为应用控制信令,而后续的数据通信也是应用数据通信。

蓝牙Airsync协议使用protobuf技术进行封包和解包,详见《 Protocolbuffer序列化及其在微信蓝牙协议中的应用》。

1) 登陆

登陆时的数据参数格式是:

微信支持两种登陆身份认证,加密和不加密。这里只讨论简单的不加密认证好了。不加密时,我们一般用MAC地址方式登陆,即将AeSine付空值,AuthMethod赋值为EAM_macNoEncrypt.

Author会收到手机微信的回复,在加密时收到的是一个用于之后通信的秘钥,但在不加密是可以忽略。

2) 初始化

初始化的目的是外设生成一个随机数,以后每次通信后,该数值都会自动加1;另外,在初始化的回复中,手机微信可以告诉外设手机微信当前的用的手机操作系统的版本、当前时间、微信用户ID等等。以便于外设记录用户的信息。

初始化的数据参数格式是:

       初始化成功之后就可以正常通信了。

       微信提供一个叫做airsyncDebug的工具用于调试,如果能正常与它连接通信,那就代表着可以跟微信进行正常通信了。

 

三、蓝牙Airsync协议学习开发步骤      

1.     初步理解微信规范《蓝牙外设协议》。

2.     理解本文

3.     根据本文的分析理解微信官方实现的基于NRF81522平台的外设例程。

4.     在自己的蓝牙单芯片平台开发实现Airsync协议,并结合airsyncDebug进行调试。

你将会事半功倍!祝好运!


更多嵌入式Linux和物联网原创分享,请关注微信公众号:嵌入式企鹅圈

 

2020-01-13 08:43:15 jikeyanxishe 阅读数 67
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27864 人正在学习 去看看 秦子恒

又双叒叕拖更了~

上周我们分享了关于苹果版双开助手的文章,今天我看了一下开发者已经在TestFlight中移除了Beta版,官方发布通知已经上架到了App Store,昨天还可以搜索得到,今天搜索会提示“目前,此App在您所在的国家或地区尚未提供”。感兴趣的可以留意一下,更名为“绿叶工具箱”!

今天,我们分享一个不一样的微信花式昵称,给你的微信昵称加上边框!

20200106微信昵称加边框_公众号封面首图_2020-01-06-0.png

方法非常简单,利用“边框文字生成工具”可以一键快速生成!

1.png

打开“边框文字生成工具”,在下面输入想要转换的昵称,然后点击左下角的“一键转换”进行转换!

2.png

转换完成以后,我们再将转换好的昵称全选拷贝或者剪切,粘贴到个人资料的昵称处保存即可!

3.png

最后我们看看效果!

4.png

今天的分享就到这里!!

2019-06-15 19:07:14 qq_35856490 阅读数 445
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27864 人正在学习 去看看 秦子恒

1. 项目实现

  • 由于是小程序未认证所以只能添加体验者才能预览
  • 项目github地址:https://github.com/historytiger/wx- 请下载放开发者工具食用
  • 数据来源于网络大佬免费提供的网易云音乐接口
    -主页由6个部分组成:搜索栏、热门歌曲、新歌首发、热门歌单、排行榜单、底部导航栏。
    -小程序加载动画由于本小程序初始化加载会用到微信的用户信息,在微信开发者更新后需要用户执行操作才能授权,所以设置一个加载动画,一方面给主页的数据请求增加事件,减少空白页的视觉体验,一方面在酷炫的动画中让用户点击加载logo授权用户信息,才可进入主页面。
  • 搜索框设置fixd定位,中间有个input输入框点击时候跳转详情搜索页,详情搜索页的输入框设置lazy当用户按下回车键input内容才更新,然后监听input内容,发生改变的时候进行关键字接口请求,input内容可以搜索歌手、专辑、歌曲
  • 热门歌曲/新歌首发首页启动时候的一个异步请求,渲染前6首歌曲的图片、歌名、歌手,点击更多进入全部热门歌曲/最新歌曲
  • 热门歌单首页启动时候的一个异步请求,渲染前6个歌单的图片、描述,点击更多进入全部热门歌单,点击任意歌单进入歌单详情页面包括封面图片、歌单描述、歌单创始人、创始人头像、以及全部歌单歌曲
  • 排行榜单首页启动时候的一个异步请求,显示前三热门榜单,每个榜单显示封面图片以及当前榜单排行前三歌曲曲目。
  • 底部导航栏包括三个功能:1.点击乐酷返回主页。2.中间圆形盒子默认显示为用户头像,当有歌曲播放的时候,图片会变为当前播放曲目的logo,并开始旋转动画,点击会跳转到播放详情页面并进行歌词自动滚动显示,当前播放的歌词会高亮,默认显示5句歌词。3.点击跳转我的页面,显示当前播放历史纪录曲目,和我的收藏曲目,使用微信的数据缓存就行保存用户操作

2.项目技术

  • mpvue项目主要基于mpvue框架使用vue-cli脚手架创建并初始化项目以及代码编写。
  • wx.navigateTo微信小程序不支持vue-router,使用WX原生的路由跳转及传参
  • vuex实现不同组件之间的状态共享
  • wx.request使用原生进行Https请求
  • InnerAudioContext使用原生创建audio实例,并基于此实例开发功能
  • wx.set/getStorage微信的本地存储功能用来实现播放记录和收藏歌曲
  • wx.createAnimation实现加载动画、歌曲logo滚动
  • wx.getUserInfo获取用户头像及用户名
  • lyric-parser歌词解析插件,将lrc歌词文件解析成可用状态
  • scroll-view配合lyric-parser插件实现歌词滚动

3.项目截图

  • 加载页
    在这里插入图片描述在这里插入图片描述
  • 首页

在这里插入图片描述

  • 热门歌曲/最新歌曲详情页
    在这里插入图片描述在这里插入图片描述

  • 热门歌单及歌单详情页
    在这里插入图片描述在这里插入图片描述

  • 排行榜及详情页
    在这里插入图片描述在这里插入图片描述

  • 底部导航栏播放详情及我的个人页面
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    歌曲播放高亮显示及收藏功能
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

4.项目详情

  • 主要通过异步请求获得数据进行渲染,由于主页显示数据过多,且网易云歌单详情不支持分页导致加载数据过多,为了优化速度主页请求数据后将所得的数据全部存在vuex中,每个小部分详情都过路由携带参数(自己的下标),然后详情页获取vuex中对应的对象将传入下标所得数据渲染出来。
  • 播放器采用的是微信自带的audio实例,在index页面使用这个实例因为小程序主页不会被销毁只会被隐藏所以也达到全局使用的效果。
  • 所有的歌曲渲染包括播放图标/暂停图标 收藏功能 播放时歌曲信息高亮
  • 底部导航栏中间播放详情圆形盒子,当歌曲播放时候传入当前歌曲的图片并进行无缝旋转,点击则进入歌曲播放详情界面,上方为当前歌曲图片信息也是无缝旋转点击封面即可暂停,暂停后歌曲会暂停 歌词会暂停,主页导航栏中心盒子旋转会暂停。底部导航栏和播放详情暂停后都会出现播放图标 ,二者任意一个点击都会继续播放 并全部进行旋转,及歌词的滚动
    在这里插入图片描述在这里插入图片描述
  • 全局背景图片使用css3滤镜实现高斯模糊,给用户更好的视觉体验

5.遇到的问题

  • 由于网易云不支持数据分页,导致主页加载数据量过大,虽然设置了加载动画,但是如果用户点击过快,还是会出现暂时空白页面。尚未找到解决办法
  • lyric-parser插件提供创建实例进行歌词播放,但是没有提供销毁实例的方法。解决办法每次换歌的时候让上一个实例stop()暂停,然后重新new一个实例方法。出现问题如果用户点击歌曲后立马点击底部导航栏进入播放详情页面,间隔很短的话,会导致上一个实例还未暂停成功就重新new一个新实例 会导致歌词滚动出错
  • 排行榜单页面在网速不好的情况下点击进入 背景文字会出现重叠,我在onUnload和onShow俩个生命周期函数中对背景文字进行初始化但是还是会出错,网速正常的情况下正常显示。
  • 在微信开发者上体验小程序很流畅,在真机上体验时候,在初次加载的时候动画会不流畅,数据缓存后会正常旋转

6.项目总结

  • 微信小程序限制还是很多的
没有更多推荐了,返回首页