NetEase Cloud Music Development--Other Contents (including payment process of small programs)

Custom modules use

 Play around with the template function

 Create a new template directory to put our template page 

First define the template in the template page. Use the name attribute as the name of the template. Then define the code snippet <template/>inside . But if we need to use the template page in the other page, use the is attribute to declare the required template

But we found that this is not possible, and reported the error of Template `myTmp` not found. This is because we did not reference the template

In this way, the basic template effect is realized. 

When we set the style in the template, but it has no effect. This is because we didn't reference it in the style

Styles need to use @import

Dynamically inject data into templates

  Just use the data keyword in the template, and then you can directly pass data to it dynamically 

Get user login credential code

 get user id

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

It is the res after the successful callback of wx.login

Server interface registration, front-end and back-end communication

The complete code is as follows:

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

Connect to WeChat server to obtain openId 

To use this library

wendux/fly: Supporting request forwarding and Promise based HTTP client for all JavaScript runtimes. (github.com)

npm install flyio

jsonwebtoken encryption, decompilation

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

npm install jsonwebtoken

 

 encrypt data

This is decompilation 

conventional subcontracting

Why subcontract

1. The size of the compressed package must not exceed 2M for the applet, otherwise it cannot be released

2. If the size of the small program in the actual development is larger than 2M, you need to use the subcontracting mechanism to publish and upload

3. The 2M limit can be solved after subcontracting, and the content can be subcontracted and loaded to improve performance

4. After subcontracting, the volume of a single package cannot exceed 2M

5. After subcontracting, the volume of all packages cannot exceed 16M

Subcontract form

1. Regular subpackage2. Independent subpackage3. Subpackage pre-download

conventional subcontracting

1. The developer declares the project subpackage structure in the app.json subpackages field

2. Features:

a) When loading the applet, the main package is loaded first, and the content of the subpackage is only loaded when the page of the subpackage needs to be accessed

b) Subpackage pages can access resources such as files, data, and pictures in the main package

c) Main package:

i. Source of the main package: all content except subpackages will be packaged into the main package ii. Usually the startup page/tabBar page is placed

  

 First move the packages under page to songPackage and otherPackage respectively. Then the package under the page is the main package.

 Then set configuration in app.json

This subcontract is successful

independent subcontracting

1. Set independent to true

2. Features:

a) The independent subpackage can access the content of the subpackage independently, without downloading the main package

b) Independent subpackages cannot depend on the content of the main package or other packages

3. Usage scenarios

a) Generally, some pages can be subcontracted independently when they are not closely related to other pages of the current applet

b) Such as: temporarily added advertising page || activity page

 Subpackage pre-download

1. Configuration

a) Set the preloadRule option in app.json

b) key (page path): {packages: [pre-downloaded package name|| root path of pre-downloaded package])}

2. Features:

a) Pre-download other packages can be set when loading the current package b) Shorten user waiting time and improve user experience 

Subpackage loading | WeChat Open Documentation (qq.com)

Understand (payment process)

Now we all use personal accounts, which cannot realize the payment function. A business account is required.

Payment Process Official Website Diagram

 Detailed payment process

1. The user places an order on the Mini Program customer service terminal (including user and product information)

2. The Mini Program client sends an order payment request to the merchant server

3. The merchant server connects with the WeChat server to obtain the unique openID

4. Merchant server generates merchant order (including merchant information) according to openId

5. The merchant server sends a request to call the unified order API to obtain prepaid order information

6. The merchant signs and encrypts the prepayment information and returns it to the Mini Program client

a) Signature method: MD5 b) Signature field: applet ID, timestamp, random string, data packet, signature method c) Reference address:

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

7. The user confirms the payment (authentication calls the payment) a) API: wx.requestPayment() 、

8. The WeChat server returns the payment result to the Mini Program client

9. The WeChat server pushes the payment result to the merchant server 

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

Guess you like

Origin blog.csdn.net/weixin_64612659/article/details/130825792