Prechádzať zdrojové kódy

合并master分支,获取接口调用代码,删除依赖包

Zhenghanjv 3 mesiacov pred
rodič
commit
0161f985f2
10 zmenil súbory, kde vykonal 375 pridanie a 3 odobranie
  1. 1 0
      app.js
  2. 32 0
      js/SM4.js
  3. 50 0
      js/SM4Exten.js
  4. 176 0
      js/api.js
  5. 34 0
      package-lock.json
  6. 6 0
      package.json
  7. 71 0
      pages/login/login.js
  8. 1 1
      pages/login/login.wxml
  9. 2 1
      project.config.json
  10. 2 1
      project.private.config.json

+ 1 - 0
app.js

@@ -12,6 +12,7 @@ App({
         // 发送 res.code 到后台换取 openId, sessionKey, unionId
       }
     })
+    
   },
   globalData: {
     userInfo: null

+ 32 - 0
js/SM4.js

@@ -0,0 +1,32 @@
+const sm4 = require('sm-crypto');
+//const sm4 = require('miniprogram-sm-crypto').sm4;
+function stringToHex(str) {
+  console.log('stringToHex');
+  const buffer = new ArrayBuffer(str.length);
+  const view = new Uint8Array(buffer);
+  for (let i = 0; i < str.length; i++) {
+    view[i] = str.charCodeAt(i);
+  }
+  return Array.from(view, byte => byte.toString(16).padStart(2, '0')).join('');
+}
+
+function sm4EcbEncrypt(plaintext, key) {
+  // 确保密钥是32字符的十六进制字符串
+  if (key.length !== 32 || !/^[0-9a-fA-F]+$/.test(key)) {
+    throw new Error('密钥必须是32字符的十六进制字符串');
+  }
+
+
+  console.log('plaintext :' + plaintext);
+  // 使用 sm-crypto 进行 SM4 ECB 加密
+  const ciphertextHex = sm4.sm4.encrypt(plaintext,key);
+  console.log('ciphertextHex :' + ciphertextHex);
+    // 将明文转换为十六进制字符串
+    const plaintextHex = stringToHex(ciphertextHex);
+    console.log('plaintextHex :' + plaintextHex);
+  return plaintextHex;
+}
+
+module.exports = {
+  sm4EcbEncrypt,
+};

+ 50 - 0
js/SM4Exten.js

@@ -0,0 +1,50 @@
+// 假设我们有一个名为 sm4 的模块,它提供了加密功能
+const sm4 = require('sm-crypto'); // 这里需要替换为实际的路径或库名
+
+function SM4Encrypt_ECB(plainText, secretKey, hexString = false) {
+  const sm4Context = {
+    isPadding: true,
+    mode: 'encrypt', // 使用加密模式
+  };
+
+  let key;
+  if (!hexString) {
+    key = wx.arrayBufferToBase64(new TextEncoder().encode(secretKey));
+  } else {
+    key = decodeHexString(secretKey); // 需要自己实现decodeHexString函数
+  }
+
+  // 设置加密密钥
+  sm4.setKey(sm4Context, key);
+
+  // 加密数据
+  const encryptedData = sm4.encryptECB(sm4Context, new TextEncoder().encode(plainText));
+
+  // 返回编码后的结果
+  return encodeBytesToHex(encryptedData);
+}
+
+function decodeHexString(hexString) {
+  // 实现与C# Decode方法相同的逻辑
+  if (hexString.length % 2 !== 0) {
+    throw new Error("Hexadecimal string must have an even length");
+  }
+  let bytes = [];
+  for (let i = 0; i < hexString.length; i += 2) {
+    bytes.push(parseInt(hexString.substr(i, 2), 16));
+  }
+  return bytes;
+}
+
+function encodeBytesToHex(bytes) {
+  // 实现与C# Encode方法相同的逻辑
+  let hexString = '';
+  for (let byte of bytes) {
+    hexString += ('0' + byte.toString(16)).slice(-2);
+  }
+  return hexString;
+}
+
+module.exports = {
+  SM4Encrypt_ECB,
+};

+ 176 - 0
js/api.js

@@ -0,0 +1,176 @@
+const sm4 = require('../js/SM4');
+const SM4Exten = require('../js/SM4Exten');
+const miniprogramsm4 = require("../miniprogram_npm/miniprogram-sm-crypto/index").sm4;
+const secretId = "D2BCF8DE-AA24-4BF6-9C34-C8DD325E412B";//小程序应用ID
+const Secret = "6C680A47B87740138DFB299FC69A64E1";//小程序应用密钥
+const api_root = 'http://192.168.0.202:5006/'
+const CurrentBuId = '12345678-9abc-def0-1234-56789abcdef0';
+
+function request(path, method = 'GET', data = null) {
+
+  return new Promise((resolve, reject) => { 
+    var sign_method = "HMAC_SM4";
+    var url = api_root +  path;
+    var nonce = generateRandomString();
+    const timestamp = Date.now();
+    let jsonString = (data != null && method != 'GET') ? JSON.stringify(data) : '';
+    console.log('request :' + jsonString);
+    var stringToSign = "sign_method=" +sign_method + 
+                       "&secret_id=" +secretId+
+                       "&nonce=" +  nonce +
+                       "&timestamp=" + timestamp + 
+                       jsonString;
+                       debugger
+    console.log('加密串 :' + stringToSign);
+    let key =  stringToHex(Secret);//key转16进制
+    key = getFirst32Chars(key);//截取前16位
+    let signature = miniprogramsm4.encrypt(stringToSign, key)//sm4加密
+    //signature = signature.toUpperCase();
+    signature = stringToBase64(signature);//加密字符串转base64
+    console.log('signature :' + signature);
+    wx.request({
+      header: {
+        "sign_method": sign_method,
+        "secret_id": secretId,
+        "nonce": nonce,
+        "timestamp": timestamp,
+        "signature": signature,
+        "CurrentBuId" : CurrentBuId
+      },
+      url: url, 
+      method: method,
+      data: data,
+      success: res => {
+        console.log("success");
+        resolve(res);
+      },
+      fail: res => {
+        console.log("request fail");
+        resolve(res);
+      },
+    })
+
+  });
+
+}
+//字符串转base64
+function stringToBase64(str) {
+  // 定义Base64字符集
+  const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+  
+  // 将字符串转换为UTF-8字节数组
+  let utf8Bytes = [];
+  for (let i = 0; i < str.length; i++) {
+    let charCode = str.charCodeAt(i);
+    
+    if (charCode < 128) { // 1字节字符
+      utf8Bytes.push(charCode);
+    } else if (charCode < 2048) { // 2字节字符
+      utf8Bytes.push((charCode >> 6) | 192);
+      utf8Bytes.push((charCode & 63) | 128);
+    } else if (charCode < 65536) { // 3字节字符
+      utf8Bytes.push((charCode >> 12) | 224);
+      utf8Bytes.push(((charCode >> 6) & 63) | 128);
+      utf8Bytes.push((charCode & 63) | 128);
+    } else { // 4字节字符
+      utf8Bytes.push((charCode >> 18) | 240);
+      utf8Bytes.push(((charCode >> 12) & 63) | 128);
+      utf8Bytes.push(((charCode >> 6) & 63) | 128);
+      utf8Bytes.push((charCode & 63) | 128);
+    }
+  }
+
+  let base64Str = '';
+  let paddingCount = 0;
+
+  // 处理每3个字节(24位),转换为4个Base64字符
+  for (let i = 0; i < utf8Bytes.length; i += 3) {
+    let byte1 = utf8Bytes[i];
+    let byte2 = i + 1 < utf8Bytes.length ? utf8Bytes[i + 1] : 0;
+    let byte3 = i + 2 < utf8Bytes.length ? utf8Bytes[i + 2] : 0;
+
+    let chunk = (byte1 << 16) | (byte2 << 8) | byte3;
+
+    let char1 = base64Chars[(chunk >> 18) & 63];
+    let char2 = base64Chars[(chunk >> 12) & 63];
+    let char3 = i + 1 < utf8Bytes.length ? base64Chars[(chunk >> 6) & 63] : '=';
+    let char4 = i + 2 < utf8Bytes.length ? base64Chars[chunk & 63] : '=';
+
+    base64Str += char1 + char2 + char3 + char4;
+
+    // 计算需要填充的'='号数量
+    if (i + 2 >= utf8Bytes.length) {
+      paddingCount = (utf8Bytes.length - i) % 3;
+    }
+  }
+
+  return base64Str;
+}
+//截取字符串
+function getFirst32Chars(str) {
+  if (typeof str !== 'string') {
+    throw new Error('Input must be a string');
+  }
+  
+  // 如果字符串长度小于等于32,则返回整个字符串;否则返回前32个字符
+  return str.length <= 32 ? str : str.slice(0, 32);
+}
+
+//字符串转16进制
+function stringToHex(str) {
+  let hex = '';
+  for (let i = 0; i < str.length; i++) {
+    // 获取字符的字符编码
+    const charCode = str.charCodeAt(i);
+    // 将字符编码转换为16进制,并确保始终为两位数(不足两位前面补0)
+    const hexValue = charCode.toString(16).padStart(2, '0');
+    hex += hexValue;
+  }
+  return hex;
+}
+
+function generateRandomString(minLength = 6, maxLength = 10) {
+  // 定义字符集
+  const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+  // 生成随机长度
+  const length = Math.floor(Math.random() * (maxLength - minLength + 1)) + minLength;
+
+  let result = '';
+  for (let i = 0; i < length; i++) {
+    // 随机选择一个字符
+    const randomIndex = Math.floor(Math.random() * charset.length);
+    result += charset[randomIndex];
+  }
+
+  return result;
+}
+
+//获取站点信息
+function request_getSite(data) {
+  return request('api/Nozzle/GetNozzleInfo?Nozzleid='+ data, "GET",data);
+}
+//支付
+function request_wechatPay(data) {
+  return request('api/Transactions/UnifiedOrder?trxid='+ data, "GET",data);
+}
+
+//获取站点信息与用户信息
+function request_GetSiteInfo(data) {
+  return request('api/Site/GetSiteInfo', "GET",data);
+}
+
+//小程序用户查询未支付订单
+function request_GetMiniProgramTransactionsUnpaidQuery(data) {
+  return request('api/Transactions/GetMiniProgramTransactionsUnpaidQuery', "GET",data);
+}
+
+//小程序用户根据抢号查询未支付订单
+function request_GetMiniProgramTransactionsUnpaidNozzle(data) {
+  return request('api/Transactions/GetMiniProgramTransactionsUnpaidNozzle', "GET",data);
+}
+
+export default {
+  request_getSite,
+  request_wechatPay
+}

+ 34 - 0
package-lock.json

@@ -0,0 +1,34 @@
+{
+  "name": "Fuelwx",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "miniprogram-sm-crypto": "^0.3.13",
+        "sm-crypto": "^0.3.13"
+      }
+    },
+    "node_modules/jsbn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
+    },
+    "node_modules/miniprogram-sm-crypto": {
+      "version": "0.3.13",
+      "resolved": "https://registry.npmjs.org/miniprogram-sm-crypto/-/miniprogram-sm-crypto-0.3.13.tgz",
+      "integrity": "sha512-H7qwbCEmIXZzekCSgEWeHh1mb4cnz0E42YH3U5xqpOaJBB2Sj9ySq0hTGv0f+Jwo5SknABR6fw+EtjnMyJ/O/Q==",
+      "dependencies": {
+        "jsbn": "^1.1.0"
+      }
+    },
+    "node_modules/sm-crypto": {
+      "version": "0.3.13",
+      "resolved": "https://registry.npmjs.org/sm-crypto/-/sm-crypto-0.3.13.tgz",
+      "integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
+      "dependencies": {
+        "jsbn": "^1.1.0"
+      }
+    }
+  }
+}

+ 6 - 0
package.json

@@ -0,0 +1,6 @@
+{
+  "dependencies": {
+    "miniprogram-sm-crypto": "^0.3.13",
+    "sm-crypto": "^0.3.13"
+  }
+}

+ 71 - 0
pages/login/login.js

@@ -1,3 +1,6 @@
+
+//const app = require('../../js/api');
+import api from '../../js/api'
 // pages/login/login.js
 Page({
 
@@ -62,5 +65,73 @@ Page({
    */
   onShareAppMessage() {
 
+  },
+  handleAuthLogin() {
+    console.log('一键授权登录按钮被点击');
+     api.request_wechatPay(1)
+     .then(res => {
+      wx.requestPayment({
+        timeStamp: res.data.data.unifiedOrderResult.timeStamp,
+        nonceStr: res.data.data.unifiedOrderResult.nonceStr,
+        package: res.data.data.unifiedOrderResult.package,
+        signType: res.data.data.unifiedOrderResult.signType,
+        paySign: res.data.data.unifiedOrderResult.paySign,
+        success: res => {
+          wx.hideLoading()
+          wx.showToast({
+            title: '支付成功!',
+          })
+          setTimeout(function () {
+            wx.switchTab({
+              url: '../index/index',
+            })
+          }, 2000)
+
+        },
+        fail: res => {
+          wx.hideLoading()
+          wx.showModal({
+            title: '支付失败',
+            content: res.errMsg + '请稍后再试',
+            showCancel: false,
+            success(res) {
+              if (res.confirm) {
+                wx.switchTab({
+                  url: '../home/home',
+                })
+              }
+            }
+          })
+        }
+      })
+     });
+    // 调用微信登录接口
+    wx.login({
+      success(res) {
+        if (res.code) {
+          console.log('登录成功,code:', res.code);
+          // 将 code 发送到服务器,获取用户信息
+          // 例如:wx.request({ url: 'https://example.com/login', data: { code: res.code } })
+        } else {
+          console.log('登录失败:', res.errMsg);
+        }
+      },
+      fail(err) {
+        console.error('登录接口调用失败:', err);
+      },
+    });
+
+    // 获取用户信息授权
+    wx.getUserProfile({
+      desc: '用于完善用户资料', // 声明获取用户信息的目的
+      success(res) {
+        console.log('用户信息:', res.userInfo);
+        // 将用户信息发送到服务器
+        // 例如:wx.request({ url: 'https://example.com/userInfo', data: res.userInfo })
+      },
+      fail(err) {
+        console.error('获取用户信息失败:', err);
+      },
+    });
   }
 })

+ 1 - 1
pages/login/login.wxml

@@ -3,7 +3,7 @@
     <image src="/images/v2_sony48.svg" mode="widthFix" class="auto-image"></image>
   </view>
   <view class="action-text">立码加油</view>
-  <button class="auth-button" style="width: 547rpx; height: 94rpx; display: block; box-sizing: border-box; left: 0rpx; top: 0rpx">一键授权登录</button>
+  <button class="auth-button" style="width: 547rpx; height: 94rpx; display: block; box-sizing: border-box; left: 0rpx; top: 0rpx"  bindtap="handleAuthLogin">一键授权登录</button>
   <view class="agreement">
     <checkbox checked="{{true}}" disabled="{{true}}" />
     <text>我已阅读并同意</text>

+ 2 - 1
project.config.json

@@ -24,5 +24,6 @@
     "tabIndent": "auto",
     "tabSize": 2
   },
-  "appid": "wxb198dafff060e651"
+  "appid": "wxb198dafff060e651",
+  "projectname": "fuelwx"
 }

+ 2 - 1
project.private.config.json

@@ -2,7 +2,8 @@
   "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
   "projectname": "fuelwx",
   "setting": {
-    "compileHotReLoad": true
+    "compileHotReLoad": true,
+    "urlCheck": false
   },
   "libVersion": "2.31.1"
 }