NetEase Cloud Music Development -- その他のコンテンツ (小規模プログラムの支払いプロセスを含む)

カスタムモジュールの使用

 テンプレート機能を試してみる

 テンプレート ページを配置するための新しいテンプレート ディレクトリを作成します 

まず、テンプレート ページでテンプレートを定義します。name 属性をテンプレートの名前として使用します。次に、<template/>内に。ただし、他のページでテンプレート ページを使用する必要がある場合は、 is 属性を使用して必要なテンプレートを宣言します。

しかし、これは不可能であることがわかり、テンプレート「myTmp」が見つからないというエラーが報告されました。これはテンプレートを参照していないためです

このようにして、基本的なテンプレート効果が実現されます。 

テンプレートにスタイルを設定しても、効果はありません。これは、スタイルで参照していないためです。

スタイルは @import を使用する必要があります

テンプレートにデータを動的に挿入する

  テンプレートで data キーワードを使用するだけで、データを動的に直接渡すことができます。 

ユーザーのログイン認証コードを取得する

 ユーザーIDを取得する

handleGetOpendId(){
        // 1.获取登录凭证
        wx.login({
          success: (res) => {
            console.log(res);
            let code=res.code
            // 2.将登录凭证发送给服务器
          },
        })
    }

wx.login のコールバックが成功した後のリソースです。

サーバーインターフェイスの登録、フロントエンドおよびバックエンドの通信

完全なコードは次のとおりです。

const fs = require('fs')
const path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const request = require('./util/request')
const packageJSON = require('./package.json')
const exec = require('child_process').exec
const cache = require('apicache').middleware
const Fly=require("flyio/src/node");
const jwt = require('jsonwebtoken');
const fly=new Fly;


const app = express()

// CORS & Preflight request
app.use((req, res, next) => {
  if(req.path !== '/' && !req.path.includes('.')){
    res.set({
      'Access-Control-Allow-Credentials': true,
      'Access-Control-Allow-Origin': req.headers.origin || '*',
      'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type',
      'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
      'Content-Type': 'application/json; charset=utf-8'
    })
  }
  req.method === 'OPTIONS' ? res.status(204).end() : next()
})

// cookie parser
app.use((req, res, next) => {
  req.cookies = {}, (req.headers.cookie || '').split(/\s*;\s*/).forEach(pair => {
    let crack = pair.indexOf('=')
    if(crack < 1 || crack == pair.length - 1) return
    req.cookies[decodeURIComponent(pair.slice(0, crack)).trim()] = decodeURIComponent(pair.slice(crack + 1)).trim()
  })
  next()
})

// body parser
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

// cache
app.use(cache('2 minutes', ((req, res) => res.statusCode === 200)))

// static
app.use(express.static(path.join(__dirname, 'public')))


// 注册获取用户唯一标识的接口
app.use('/getOpenId', async (req, res, next) => {
  let code = req.query.code;
  let appId = 'wx810e8b1fde386fde';
  let appSecret = '8bb909649da12002fba7a47f5ac3791b';
  let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appId}&secret=${appSecret}&js_code=${code}&grant_type=authorization_code`
  // 发请求给微信服务器获取openId
  let result = await fly.get(url);
  let openId = JSON.parse(result.data).openid;
   console.log('openId', openId);
   // 自定义登录态
   let person = {
     username: '北方汉子',
     age: 18,
     openId
   }
   // 对用户的数据进行加密,生成token返回给客户端
  let token = jwt.sign(person, 'atguigu');
  console.log(token);
  // 验证身份,反编译token
  let result2 = jwt.verify(token, 'atguigu');
  console.log(result2);
  res.send(token);
});



// router
const special = {
  'daily_signin.js': '/daily_signin',
  'fm_trash.js': '/fm_trash',
  'personal_fm.js': '/personal_fm'
}

fs.readdirSync(path.join(__dirname, 'module')).reverse().forEach(file => {
  // console.log(file);
  if(!file.endsWith('.js')) return
  // album_newest.js  ---> /album_newest.js ---> /album_newest ---> /album/newest
  let route = (file in special) ? special[file] : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/')
  let question = require(path.join(__dirname, 'module', file))

  app.use(route, (req, res) => {
    console.log(route);
    console.log(req)
    console.log('------');
    console.log(req.cookies)
    let query = Object.assign({}, req.query, req.body, {cookie: req.cookies})
    question(query, request)
      .then(answer => {
        console.log('[OK]', decodeURIComponent(req.originalUrl))
        res.append('Set-Cookie', answer.cookie)
        res.status(answer.status).send(answer.body)
      })
      .catch(answer => {
        console.log('[ERR]', decodeURIComponent(req.originalUrl))
        if(answer.body.code == '301') answer.body.msg = '需要登录'
        res.append('Set-Cookie', answer.cookie)
        res.status(answer.status).send(answer.body)
      })
  })
})

const port = process.env.PORT || 3000
const host = process.env.HOST || ''

app.server = app.listen(port, host, () => {
  console.log('欢迎使用音乐服务器');
  console.log('服务器地址: http://localhost:3000')
})

module.exports = app

WeChatサーバーに接続してopenIdを取得します 

このライブラリを使用するには

wendux/fly: すべての JavaScript ランタイムのリクエスト転送と Promise ベースの HTTP クライアントをサポートします。(github.com)

npm install flyio

jsonwebtoken暗号化、逆コンパイル

auth0/node-jsonwebtoken:node.js の JsonWebToken 実装 http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html (github.com)

npm install jsonwebtoken

 

 データを暗号化する

これは逆コンパイルです 

従来の下請け

なぜ下請けをするのか

1. アプレットの圧縮パッケージのサイズは 2M を超えてはなりません。2M を超えないとリリースできません。

2. 実際の開発における小規模プログラムのサイズが 2M を超える場合、公開およびアップロードには下請けメカニズムを使用する必要があります。

3. 2M 制限は外注後に解決でき、コンテンツを外注してロードしてパフォーマンスを向上させることができます。

4. 下請け後、単一のパッケージの体積は 2M を超えることはできません

5. 下請け後、すべてのパッケージの量は 16M を超えてはなりません

下請契約形態

1. 通常のサブパッケージ2. 独立したサブパッケージ3. サブパッケージの事前ダウンロード

従来の下請け

1. 開発者は、app.json サブパッケージ フィールドでプロジェクトのサブパッケージ構造を宣言します。

2. 特徴:

a) アプレットをロードするとき、メインパッケージが最初にロードされ、サブパッケージのページにアクセスする必要がある場合にのみサブパッケージのコンテンツがロードされます。

b) サブパッケージ ページは、メイン パッケージ内のファイル、データ、画像などのリソースにアクセスできます。

c) メインパッケージ:

i. メイン パッケージのソース: サブパッケージを除くすべてのコンテンツがメイン パッケージにパッケージ化されます ii. 通常、スタートアップ ページ/タブバー ページが配置されます

  

 まず、ページ配下のパッケージをそれぞれ SongPackage と otherPackage に移動します。この場合、ページの下にあるパッケージがメイン パッケージになります。

 次に、app.json で構成を設定します

この下請けは成功しました

独立した下請け

1.independent を true に設定します

2. 特徴:

a) 独立したサブパッケージは、メイン パッケージをダウンロードせずに、サブパッケージのコンテンツに独立してアクセスできます。

b) 独立したサブパッケージはメインパッケージや他のパッケージの内容に依存できません。

3. 利用シーン

a) 一般に、一部のページは、現在のアプレットの他のページと密接に関連していない場合、独立して下請けに出すことができます。

b) 例: 一時的に追加された広告ページ || アクティビティ ページ

 サブパッケージの事前ダウンロード

1. 構成

a) app.json で preloadRule オプションを設定します。

b) キー (ページ パス): {packages: [事前ダウンロードされたパッケージ名|| 事前ダウンロードされたパッケージのルート パス])}

2. 特徴:

a) 現在のパッケージをロードするときに、他のパッケージを事前にダウンロードするように設定できます。 b) ユーザーの待ち時間を短縮し、ユーザー エクスペリエンスを向上させます。 

サブパッケージの読み込み | WeChat オープン ドキュメント (qq.com)

理解する(支払い手続き)

現在、私たちは皆個人アカウントを使用していますが、これでは支払い機能を実現できません。ビジネスアカウントが必要です。

お支払いの流れ 公式サイト図

 詳しい支払いの流れ

1. ユーザーは、ミニ プログラム カスタマー サービス端末で注文します (ユーザー情報および製品情報を含む)。

2. ミニ プログラム クライアントは、注文支払いリクエストをマーチャント サーバーに送信します。

3. マーチャントサーバーは WeChat サーバーに接続して、一意の openID を取得します。

4. マーチャントサーバーは、openId に従ってマーチャント注文 (マーチャント情報を含む) を生成します。

5. マーチャントサーバーは、統合注文 API を呼び出すリクエストを送信して、前払い注文情報を取得します

6. 加盟店は前払い情報に署名して暗号化し、それをミニ プログラム クライアントに返します。

a) 署名方法: MD5 b) 署名フィールド: アプレット ID、タイムスタンプ、ランダム文字列、データ パケット、署名方法 c) 参照アドレス:

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3

7. ユーザーは支払いを確認します(認証は支払いを呼び出します) a) API: wx.requestPayment() 、

8. WeChat サーバーは支払い結果をミニ プログラム クライアントに返します。

9. WeChat サーバーは支払い結果を販売者サーバーにプッシュします 

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

おすすめ

転載: blog.csdn.net/weixin_64612659/article/details/130825792