feat: 添加使用脚本切换小程序的替换

This commit is contained in:
2025-09-22 22:07:18 +08:00
parent 5975914e55
commit 4503e487f1
7 changed files with 521 additions and 66 deletions

29
client-configs.json Normal file
View File

@@ -0,0 +1,29 @@
{
"zhinian": {
"clientId": "2",
"appId": "wx5e79df5996572539",
"name": "智念",
"placeholder": "快告诉智念您在想什么~",
"loginDesc": "您好,欢迎来到智念科技",
"logo": "@/pages/login/images/dh.png",
"subLogo": "@/pages/login/images/dhwq.png"
},
"duohua": {
"clientId": "2",
"appId": "wx23f86d809ae80259",
"name": "朵花",
"placeholder": "快告诉朵朵您在想什么~",
"loginDesc": "您好,欢迎来到朵花温泉",
"logo": "@/pages/login/images/dh.png",
"subLogo": "@/pages/login/images/dhwq.png"
},
"tianmu": {
"clientId": "4",
"appId": "wx0be424e1d22065a9",
"name": "天沐",
"placeholder": "快告诉沐沐您在想什么~",
"loginDesc": "您好,欢迎来到天沐温泉",
"logo": "@/pages/login/images/tm.png",
"subLogo": "@/pages/login/images/wsmm.png"
}
}

View File

@@ -37,7 +37,8 @@
"build:mp-xhs": "uni build -p mp-xhs",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"switch-client": "node scripts/update-appid.js"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4070620250821001",

View File

@@ -1,31 +1,31 @@
{
"appid": "wx0be424e1d22065a9",
"compileType": "miniprogram",
"libVersion": "3.8.10",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"ignoreDevUnusedFiles": false,
"ignoreUploadUnusedFiles": false,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"projectArchitecture": "miniProgram"
}
{
"appid": "wx0be424e1d22065a9",
"compileType": "miniprogram",
"libVersion": "3.8.10",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"ignoreDevUnusedFiles": false,
"ignoreUploadUnusedFiles": false,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"projectArchitecture": "miniProgram"
}

View File

@@ -0,0 +1,173 @@
# 客户端配置切换脚本使用说明
这个脚本用于在不同客户端配置之间快速切换,支持智念、朵花、天沐等多个客户端。
## 主要功能
- 支持通过客户端名称切换配置
- 自动更新相关配置文件
- 统一的JSON配置文件管理
- 完整的错误处理和验证
## 配置文件结构
配置文件位于项目根目录的 `client-configs.json`,包含所有客户端的完整配置信息:
```json
{
"zhinian": {
"clientId": "2",
"appId": "wx5e79df5996572539",
"name": "智念",
"placeholder": "快告诉智念您在想什么~",
"loginDesc": "您好,欢迎来到智念科技",
"logo": "@/pages/login/images/dh.png",
"subLogo": "@/pages/login/images/dhwq.png"
},
"duohua": {
"clientId": "2",
"appId": "wx23f86d809ae80259",
"name": "朵花",
"placeholder": "快告诉朵朵您在想什么~",
"loginDesc": "您好,欢迎来到朵花温泉",
"logo": "@/pages/login/images/dh.png",
"subLogo": "@/pages/login/images/dhwq.png"
},
"tianmu": {
"clientId": "4",
"appId": "wx0be424e1d22065a9",
"name": "天沐",
"placeholder": "快告诉沐沐您在想什么~",
"loginDesc": "您好,欢迎来到天沐温泉",
"logo": "@/pages/login/images/tm.png",
"subLogo": "@/pages/login/images/wsmm.png"
}
}
```
## 支持的客户端
| 客户端名称 | 显示名称 | AppID |
| ---------- | -------- | ------------------ |
| `zhinian` | 智念 | wx5e79df5996572539 |
| `duohua` | 朵花 | wx23f86d809ae80259 |
| `tianmu` | 天沐 | wx0be424e1d22065a9 |
## 使用方法
### 使用客户端名称切换
```bash
# 切换到天沐客户端
npm run switch-client tianmu
# 切换到智念客户端
npm run switch-client zhinian
# 切换到朵花客户端
npm run switch-client duohua
```
### 直接运行脚本
```bash
# 使用客户端名称
node scripts/update-appid.js tianmu
```
## AppID 信息
微信小程序的 AppID 通常格式为:
-`wx` 开头
- 后跟 16 位字符(数字和字母)
- 总长度 18 位
示例:`wx1234567890abcdef`
## 更新的文件
1. **src/manifest.json**
- 更新 `mp-weixin.appid` 字段
- 保持文件中的注释不变
2. **project.config.json**
- 更新根级别的 `appid` 字段
- 保持 JSON 格式化
3. **src/constant/base.js**
- 更新 `getCurrentConfig()` 函数返回的客户端配置
4. **client-configs.json**
- 统一的配置文件,所有客户端配置的单一数据源
## 执行结果示例
### 使用客户端名称切换:
```
🚀 开始更新配置...
🎯 检测到客户端配置: 天沐 (tianmu)
目标客户端: 天沐 (tianmu)
目标appid: wx0be424e1d22065a9
📝 正在更新 base.js...
✅ base.js 更新成功,切换到 天沐 配置
📝 正在更新 manifest.json...
✅ manifest.json 更新成功
📝 正在更新 project.config.json...
✅ project.config.json 更新成功
旧appid: wx5e79df5996572539
新appid: wx0be424e1d22065a9
🎉 所有文件更新完成!
💡 已切换到 天沐 客户端配置
💡 提示: 请检查文件内容确认更新正确
```
## 错误处理
脚本包含以下验证和错误处理:
- 检查必需参数是否提供
- 验证客户端名称是否有效
- 检查目标文件是否存在
- 捕获文件读写错误
- 智能跳过不需要的更新
## 注意事项
1. **配置同步**: 确保 `client-configs.json``src/constant/client-config.js` 中的基础配置保持同步
2. **测试建议**: 切换配置后建议先进行测试,确认功能正常
3. **备份建议**: 重要更新前建议备份相关配置文件
## 常见问题
**Q: 脚本提示文件不存在怎么办?**
A: 请确保在项目根目录执行脚本,并检查文件路径是否正确。
**Q: 脚本提示不支持的客户端名称怎么办?**
A: 请检查输入的客户端名称是否正确支持的客户端名称有zhinian、duohua、tianmu。
**Q: 如何恢复到之前的配置?**
A: 可以使用版本控制系统恢复,或者再次运行脚本切换到其他客户端配置。
**Q: 如何添加新的客户端配置?**
A: 在 `client-configs.json` 中添加新的客户端配置:
```json
"new_client": {
"clientId": "客户端ID",
"appId": "微信小程序AppID",
"name": "客户端显示名称",
"placeholder": "输入框占位符文本",
"loginDesc": "登录页面描述文本",
"logo": "@/pages/login/images/logo.png",
"subLogo": "@/pages/login/images/sublogo.png"
}
```
`src/constant/client-config.js` 会自动读取并处理新配置,无需手动修改。
**Q: 脚本提示"读取配置文件失败"怎么办?**
A: 检查 `client-configs.json` 文件是否存在且格式正确。

220
scripts/update-appid.js Executable file
View File

@@ -0,0 +1,220 @@
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
/**
* 客户端配置切换脚本
* 支持通过客户端名称来切换配置
*
* 使用方法:
* 1. node scripts/update-appid.js <client-name>
* 2. npm run switch-client <client-name>
*/
// 读取客户端配置文件
const configPath = path.join(__dirname, "../client-configs.json");
let CLIENT_CONFIGS;
try {
const configContent = fs.readFileSync(configPath, "utf8");
CLIENT_CONFIGS = JSON.parse(configContent);
} catch (error) {
console.error("❌ 读取配置文件失败:", error.message);
console.error(" 配置文件路径:", configPath);
process.exit(1);
}
// 获取命令行参数
const args = process.argv.slice(2);
const input = args[0];
// 验证参数
if (!input) {
console.error("❌ 错误: 请提供客户端名称");
console.log("使用方法:");
console.log(" node scripts/update-appid.js <client-name>");
console.log(" npm run switch-client <client-name>");
console.log("");
console.log("支持的客户端名称:");
Object.keys(CLIENT_CONFIGS).forEach((key) => {
console.log(` ${key} - ${CLIENT_CONFIGS[key].name}`);
});
console.log("");
console.log("示例:");
console.log(" node scripts/update-appid.js tianmu");
console.log(" npm run switch-client tianmu");
process.exit(1);
}
// 文件路径
const manifestPath = path.join(__dirname, "../src/manifest.json");
const projectConfigPath = path.join(__dirname, "../project.config.json");
/**
* 更新base.js中的getCurrentConfig函数
*/
function updateBaseJs(clientName) {
const basePath = path.join(__dirname, "../src/constant/base.js");
try {
console.log("📝 正在更新 base.js...");
let content = fs.readFileSync(basePath, "utf8");
// 查找getCurrentConfig函数并替换其中的CLIENT_CONFIGS引用
const regex =
/export const getCurrentConfig = \(\) => CLIENT_CONFIGS\.\w+;/;
const newExport = `export const getCurrentConfig = () => CLIENT_CONFIGS.${clientName};`;
if (regex.test(content)) {
content = content.replace(regex, newExport);
fs.writeFileSync(basePath, content, "utf8");
console.log(
`✅ base.js 更新成功,切换到 ${CLIENT_CONFIGS[clientName].name} 配置`
);
return true;
} else {
console.log("⚠️ base.js 中未找到getCurrentConfig函数跳过更新");
return true;
}
} catch (error) {
console.error("❌ 更新base.js失败:", error.message);
return false;
}
}
/**
* 更新manifest.json中的appid
*/
function updateManifestJson(newAppId) {
try {
console.log("📝 正在更新 manifest.json...");
let content = fs.readFileSync(manifestPath, "utf8");
// 由于manifest.json包含注释需要特殊处理
// 使用正则表达式替换mp-weixin中的appid
const regex = /"mp-weixin":\s*{[^}]*"appid":\s*"[^"]*"/;
if (regex.test(content)) {
content = content.replace(regex, (match) => {
return match.replace(/"appid":\s*"[^"]*"/, `"appid": "${newAppId}"`);
});
fs.writeFileSync(manifestPath, content, "utf8");
console.log("✅ manifest.json 更新成功");
} else {
console.log(" manifest.json 中未找到mp-weixin配置跳过更新");
}
return true;
} catch (error) {
console.error("❌ 更新manifest.json失败:", error.message);
return false;
}
}
/**
* 更新project.config.json中的appid
*/
function updateProjectConfigJson(newAppId) {
try {
console.log("📝 正在更新 project.config.json...");
const content = fs.readFileSync(projectConfigPath, "utf8");
const config = JSON.parse(content);
const oldAppId = config.appid;
if (config.appid !== newAppId) {
config.appid = newAppId;
fs.writeFileSync(
projectConfigPath,
JSON.stringify(config, null, 2),
"utf8"
);
console.log("✅ project.config.json 更新成功");
console.log(` 旧appid: ${oldAppId}`);
console.log(` 新appid: ${newAppId}`);
} else {
console.log(" project.config.json 无需更新");
}
return true;
} catch (error) {
console.error("❌ 更新project.config.json失败:", error.message);
return false;
}
}
/**
* 验证必要文件是否存在
*/
function validateFiles() {
const basePath = path.join(__dirname, "../src/constant/base.js");
const files = [
{ path: basePath, name: "base.js" },
{ path: manifestPath, name: "manifest.json" },
{ path: projectConfigPath, name: "project.config.json" },
];
for (const file of files) {
if (!fs.existsSync(file.path)) {
console.error(`❌ 文件不存在: ${file.name}`);
return false;
}
}
return true;
}
/**
* 主函数
*/
function main() {
console.log("🚀 开始更新配置...");
// 解析输入参数
let newAppId;
let clientName;
// 检查是否为有效的客户端名称
if (CLIENT_CONFIGS[input]) {
// 使用客户端名称
clientName = input;
newAppId = CLIENT_CONFIGS[input].appId;
console.log(
`🎯 检测到客户端配置: ${CLIENT_CONFIGS[input].name} (${clientName})`
);
console.log(
`目标客户端: ${CLIENT_CONFIGS[clientName].name} (${clientName})`
);
console.log(`目标appid: ${newAppId}\n`);
// 验证文件存在
if (!validateFiles()) {
process.exit(1);
}
// 更新文件
const baseSuccess = updateBaseJs(clientName);
const manifestSuccess = updateManifestJson(newAppId);
const projectConfigSuccess = updateProjectConfigJson(newAppId);
if (baseSuccess && manifestSuccess && projectConfigSuccess) {
console.log("\n🎉 所有文件更新完成!");
console.log(`💡 已切换到 ${CLIENT_CONFIGS[clientName].name} 客户端配置`);
console.log("💡 提示: 请检查文件内容确认更新正确");
} else {
console.log("\n❌ 部分文件更新失败,请检查错误信息");
process.exit(1);
}
} else {
// 不支持的客户端名称
console.error(`❌ 错误: 不支持的客户端名称 "${input}"`);
console.log("");
console.log("支持的客户端名称:");
Object.keys(CLIENT_CONFIGS).forEach((key) => {
console.log(` ${key} - ${CLIENT_CONFIGS[key].name}`);
});
process.exit(1);
}
}
// 执行主函数
main();

View File

@@ -1,39 +1,9 @@
import DH from "@/pages/login/images/dh.png";
import DHWQ from "@/pages/login/images/dhwq.png";
import TM from "@/pages/login/images/tm.png";
import WSMM from "@/pages/login/images/wsmm.png";
// 导入统一的客户端配置
import { CLIENT_CONFIGS } from './client-config.js';
// 小程序特有相关: 同时更改manifest.json和 project.config.json文件中的appid
// 所有用户端的配置
export const CLIENT_CONFIGS = {
// 智念用户端
zhinian: {
clientId: "2",
appId: "wx5e79df5996572539",
placeholder: "快告诉智念您在想什么~",
loginDesc: "您好,欢迎来到智念科技",
logo: DH,
subLogo: DHWQ,
},
// 朵花用户端
duohua: {
clientId: "2",
appId: "wx23f86d809ae80259",
placeholder: "快告诉朵朵您在想什么~",
loginDesc: "您好,欢迎来到朵花温泉",
logo: DH,
subLogo: DHWQ,
},
// 天沐用户端
tianmu: {
clientId: "4",
appId: "wx0be424e1d22065a9",
placeholder: "快告诉沐沐您在想什么~",
loginDesc: "您好,欢迎来到天沐温泉",
logo: TM,
subLogo: WSMM,
},
};
// 重新导出配置供其他模块使用
export { CLIENT_CONFIGS };
// 获取当前用户端配置
export const getCurrentConfig = () => CLIENT_CONFIGS.tianmu;

View File

@@ -0,0 +1,62 @@
/**
* 客户端配置管理模块
*
* 功能说明:
* 所有配置现在从根目录的 client-configs.json 文件中读取
* 支持智能图片路径处理,自动适配不同环境
*/
// 读取完整配置文件
let rawConfigs;
try {
if (typeof window === 'undefined') {
// Node.js环境 - 读取JSON文件
const fs = require('fs');
const path = require('path');
const configPath = path.join(process.cwd(), 'client-configs.json');
const configContent = fs.readFileSync(configPath, 'utf8');
rawConfigs = JSON.parse(configContent);
} else {
// 浏览器环境 - 读取JSON文件需要构建时处理
// 这里应该通过构建工具将JSON内容注入或者通过API获取
throw new Error('浏览器环境需要通过构建工具或API获取配置');
}
} catch (error) {
console.error('读取配置文件失败:', error);
rawConfigs = {};
}
// 动态导入图片的辅助函数
const importImage = (imagePath) => {
try {
// 检查是否在Node.js环境中
if (typeof window === 'undefined') {
// Node.js环境中返回路径字符串
return imagePath;
}
// 将 @/ 路径转换为实际的导入路径
const actualPath = imagePath.replace('@/', '../');
return require(actualPath);
} catch (error) {
console.warn(`无法加载图片: ${imagePath}`, error);
return imagePath; // 返回原路径作为fallback
}
};
// 处理配置,将图片路径转换为实际的导入对象
const processConfigs = (configs) => {
const processedConfigs = {};
for (const [clientName, config] of Object.entries(configs)) {
processedConfigs[clientName] = {
...config,
logo: importImage(config.logo),
subLogo: importImage(config.subLogo),
};
}
return processedConfigs;
};
// 所有用户端的配置 - 从JSON配置文件生成
export const CLIENT_CONFIGS = processConfigs(rawConfigs);