| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Node 脚本:生成携带 storeId 的小程序码(永久码)
- // 使用方法:在命令行设置环境变量并运行
- // Windows PowerShell:
- // $env:WX_APPID="<你的AppID>"; $env:WX_SECRET="<你的AppSecret>"; node server/generate-minicode.js
- // 或在同一命令行:
- // node server/generate-minicode.js
- // 将在 server/output/ 目录下生成 PNG 文件
- const https = require('https');
- const fs = require('fs');
- const path = require('path');
- const APPID = process.env.WX_APPID || 'wxbb048b80cd2a14b9';
- const SECRET = process.env.WX_SECRET; // 必须提供 AppSecret
- const STORE_ID = 'ARhMGM5Y1W';
- const PAGE = 'nova-pbf/pages/index/index';
- function httpGetJson(url) {
- return new Promise((resolve, reject) => {
- https
- .get(url, (res) => {
- let data = '';
- res.on('data', (chunk) => (data += chunk));
- res.on('end', () => {
- try {
- const json = JSON.parse(data);
- resolve(json);
- } catch (e) {
- reject(e);
- }
- });
- })
- .on('error', reject);
- });
- }
- function httpPostBuffer(url, bodyObj) {
- const body = JSON.stringify(bodyObj);
- return new Promise((resolve, reject) => {
- const req = https.request(url, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Length': Buffer.byteLength(body),
- },
- });
- const chunks = [];
- req.on('response', (res) => {
- res.on('data', (chunk) => chunks.push(chunk));
- res.on('end', () => resolve(Buffer.concat(chunks)));
- });
- req.on('error', reject);
- req.write(body);
- req.end();
- });
- }
- async function main() {
- if (!SECRET) {
- console.error('❌ 未提供 WX_SECRET(AppSecret)。请设置环境变量后重试。');
- process.exit(1);
- }
- console.log('🔑 获取 access_token...');
- const tokenResp = await httpGetJson(
- `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${SECRET}`
- );
- if (!tokenResp.access_token) {
- console.error('❌ 获取 access_token 失败:', tokenResp);
- process.exit(1);
- }
- const accessToken = tokenResp.access_token;
- console.log('✅ access_token 获取成功');
- console.log('🖨️ 生成携带参数的小程序码...');
- const apiUrl = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${accessToken}`;
- const payload = {
- scene: `storeId=${STORE_ID}`,
- page: PAGE,
- check_path: false, // 允许未发布页面,仅用于测试/体验
- is_hyaline: true,
- width: 430,
- };
- const buf = await httpPostBuffer(apiUrl, payload);
- // 微信接口在错误时也可能返回 JSON 文本,需要粗略判断
- const isJson = buf.slice(0, 1).toString() === '{';
- if (isJson) {
- try {
- const err = JSON.parse(buf.toString('utf8'));
- console.error('❌ 生成小程序码失败:', err);
- process.exit(1);
- } catch (_) {
- // ignore
- }
- }
- const outDir = path.join(__dirname, 'output');
- if (!fs.existsSync(outDir)) {
- fs.mkdirSync(outDir, { recursive: true });
- }
- const outPath = path.join(outDir, `minicode_store_${STORE_ID}.png`);
- fs.writeFileSync(outPath, buf);
- console.log(`✅ 已生成:${outPath}`);
- console.log('📌 扫码后将进入页面并携带参数:storeId=', STORE_ID);
- }
- main().catch((e) => {
- console.error('程序异常:', e);
- process.exit(1);
- });
|