完成consumer端同步

This commit is contained in:
2026-05-14 15:28:09 +08:00
parent 612fb3d360
commit 0ffbc53902
197 changed files with 92657 additions and 7564 deletions

View File

@@ -1,10 +1,8 @@
@echo off
chcp 65001 >nul 2>&1
if exist pages.json copy /y pages.json pages.json.bak >nul 2>&1
if exist manifest.json copy /y manifest.json manifest.json.bak >nul 2>&1
copy /y config\consumer\pages.json pages.json >nul 2>&1
copy /y config\consumer\manifest.json manifest.json >nul 2>&1
echo 消费者端配置已应用,可以编译小程序了
call npm run pages:consumer
if errorlevel 1 exit /b 1
echo Consumer pages config applied.

View File

@@ -7,21 +7,16 @@ echo "========================================"
echo ""
echo "[1/3] 备份原配置文件..."
if [ -f "pages.json" ]; then
cp pages.json pages.json.bak
echo " 已备份 pages.json -> pages.json.bak"
fi
if [ -f "manifest.json" ]; then
cp manifest.json manifest.json.bak
echo " 已备份 manifest.json -> manifest.json.bak"
fi
echo ""
echo "[2/3] 复制消费者端配置文件..."
cp config/consumer/pages.json pages.json
echo " 已复制 config/consumer/pages.json -> pages.json"
echo "[2/3] 应用消费者端配置文件..."
cp config/consumer/manifest.json manifest.json
echo " 已复制 config/consumer/manifest.json -> manifest.json"
npm run pages:consumer
echo ""
echo "[3/3] 配置完成!"

View File

@@ -1,10 +1,8 @@
@echo off
chcp 65001 >nul 2>&1
if exist pages.json.bak copy /y pages.json.bak pages.json >nul 2>&1
if exist manifest.json.bak copy /y manifest.json.bak manifest.json >nul 2>&1
if exist pages.json.bak del pages.json.bak >nul 2>&1
if exist manifest.json.bak del manifest.json.bak >nul 2>&1
echo 公共配置已恢复
call npm run pages:full
if errorlevel 1 exit /b 1
echo Shared config restored.

View File

@@ -7,16 +7,12 @@ echo "========================================"
echo ""
echo "[1/2] 恢复配置文件..."
if [ -f "pages.json.bak" ]; then
cp pages.json.bak pages.json
rm pages.json.bak
echo " 已恢复 pages.json"
fi
if [ -f "manifest.json.bak" ]; then
cp manifest.json.bak manifest.json
rm manifest.json.bak
echo " 已恢复 manifest.json"
fi
npm run pages:full
echo ""
echo "[2/2] 完成!"

View File

@@ -1,8 +1,10 @@
/**
* 切换 pages.json 在「完整模式」和「商家端专属模式」之间
* 切换 pages.json 到不同端的专属编译模式。
*
* 用法:
* npm run pages:merchant → 仅编译 merchant 相关页面(大幅缩短编译时间)
* npm run pages:consumer → 仅编译 consumer 相关页面
* npm run pages:merchant → 仅编译 merchant 相关页面
* npm run pages:admin → 仅编译 admin 相关页面
* npm run pages:full → 恢复完整 pages.json
*/
const fs = require("fs");
@@ -11,35 +13,415 @@ const path = require("path");
const root = path.resolve(__dirname, "..");
const pagesJson = path.join(root, "pages.json");
const pagesFull = path.join(root, "pages.full.json");
const pagesMerchant = path.join(root, "pages.merchant.json");
const backupDir = path.join(root, ".pages-backup");
const pageExtensions = [".uvue", ".vue", ".nvue"];
const mode = process.argv[2]; // 'merchant' | 'full'
const consumerUserPages = [
"pages/user/boot",
"pages/user/login",
"pages/user/register",
"pages/user/forgot-password",
"pages/user/terms",
"pages/user/center",
"pages/user/profile",
"pages/user/change-password",
"pages/user/bind-phone",
"pages/user/bind-email",
];
if (mode === "merchant") {
if (!fs.existsSync(pagesMerchant)) {
console.error("❌ pages.merchant.json 不存在,请先创建该文件。");
const merchantUserPages = [
"pages/user/login",
"pages/user/boot",
"pages/user/register",
"pages/user/forgot-password",
"pages/user/terms",
"pages/user/change-password",
];
const adminUserPages = [
"pages/user/login",
"pages/user/boot",
"pages/user/forgot-password",
"pages/user/terms",
"pages/user/change-password",
];
const targetConfigs = {
consumer: {
fileName: "pages.consumer.json",
label: "消费者端",
entryPath: "pages/main/index",
orderedTopLevelPaths: [
"pages/main/index",
...consumerUserPages,
"pages/main/category",
"pages/main/messages",
"pages/main/cart",
"pages/main/profile",
],
topLevelMatcher(pagePath) {
return (
pagePath.startsWith("pages/main/") ||
consumerUserPages.includes(pagePath)
);
},
subPackageMatcher(rootPath) {
return rootPath === "pages/mall/consumer";
},
tabBarMatcher(pagePath) {
return pagePath.startsWith("pages/main/");
},
defaultCondition() {
return {
current: 0,
list: [
{
name: "consumer端",
path: "pages/main/index",
query: "role=consumer",
},
],
};
},
},
merchant: {
fileName: "pages.merchant.json",
label: "商家端",
entryPath: "pages/user/login",
orderedTopLevelPaths: [
"pages/user/login",
"pages/user/boot",
"pages/user/register",
"pages/user/forgot-password",
"pages/user/terms",
"pages/user/change-password",
"pages/mall/merchant/index",
"pages/mall/merchant/messages",
"pages/mall/merchant/orders",
"pages/mall/merchant/growth",
"pages/mall/merchant/profile",
],
topLevelMatcher(pagePath) {
return (
merchantUserPages.includes(pagePath) ||
pagePath.startsWith("pages/mall/merchant/")
);
},
subPackageMatcher() {
return false;
},
defaultCondition() {
return {
current: 0,
list: [
{
name: "merchant端",
path: "pages/mall/merchant/index",
query: "role=merchant",
},
],
};
},
},
admin: {
fileName: "pages.admin.json",
label: "管理后台",
entryPath: "pages/user/login",
orderedTopLevelPaths: [
"pages/user/login",
"pages/user/boot",
"pages/user/forgot-password",
"pages/user/terms",
"pages/user/change-password",
"pages/mall/admin/homePage/index",
"pages/mall/admin/userCenter/index",
],
topLevelMatcher(pagePath) {
return (
adminUserPages.includes(pagePath) ||
pagePath === "pages/mall/admin/homePage/index" ||
pagePath === "pages/mall/admin/userCenter/index"
);
},
subPackageMatcher(rootPath) {
return rootPath.startsWith("pages/mall/admin/");
},
defaultCondition() {
return {
current: 0,
list: [
{
name: "admin端",
path: "pages/mall/admin/homePage/index",
query: "role=admin",
},
],
};
},
},
};
const mode = process.argv[2]; // 'consumer' | 'merchant' | 'admin' | 'full'
function readJson(filePath) {
const rawContent = fs.readFileSync(filePath, "utf8").replace(/^\uFEFF/, "");
return JSON.parse(rawContent);
}
function writeJson(filePath, content) {
fs.writeFileSync(filePath, `${JSON.stringify(content, null, 2)}\n`, "utf8");
}
function ensureFullBackup() {
if (fs.existsSync(pagesFull)) {
return;
}
fs.copyFileSync(pagesJson, pagesFull);
console.log("📦 已备份 pages.json → pages.full.json");
}
function backupCurrentPages(targetName) {
if (!fs.existsSync(pagesJson)) {
return;
}
fs.mkdirSync(backupDir, { recursive: true });
const timestamp = new Date().toISOString().replace(/[.:]/g, "-");
const backupPath = path.join(
backupDir,
`pages.${targetName}.${timestamp}.json`,
);
fs.copyFileSync(pagesJson, backupPath);
console.log(`📦 已备份当前 pages.json → ${path.relative(root, backupPath)}`);
}
function getPageMap(fullConfig) {
return new Map(fullConfig.pages.map((page) => [page.path, page]));
}
function findMatchingPageFile(routePath) {
for (const extension of pageExtensions) {
const candidate = path.join(root, `${routePath}${extension}`);
if (fs.existsSync(candidate)) {
return candidate;
}
}
return null;
}
function clonePage(page) {
return JSON.parse(JSON.stringify(page));
}
function flattenSubPackagePages(fullConfig, rootPath) {
const targetPackage = fullConfig.subPackages.find(
(item) => item.root === rootPath,
);
if (!targetPackage) {
return [];
}
return targetPackage.pages.map((page) => ({
path: `${rootPath}/${page.path}`,
style: page.style ? JSON.parse(JSON.stringify(page.style)) : {},
}));
}
function getTopLevelPages(fullConfig, targetConfig) {
const pageMap = getPageMap(fullConfig);
const matchedFromTopLevel = fullConfig.pages
.filter((page) => targetConfig.topLevelMatcher(page.path))
.map((page) => clonePage(page));
const flattenedPages = (targetConfig.flattenRoots || []).flatMap((rootPath) =>
flattenSubPackagePages(fullConfig, rootPath),
);
const mergedMap = new Map();
for (const page of [...matchedFromTopLevel, ...flattenedPages]) {
mergedMap.set(page.path, page);
}
const orderedPages = [];
for (const pagePath of targetConfig.orderedTopLevelPaths) {
if (mergedMap.has(pagePath)) {
orderedPages.push(mergedMap.get(pagePath));
mergedMap.delete(pagePath);
} else if (pageMap.has(pagePath)) {
orderedPages.push(clonePage(pageMap.get(pagePath)));
}
}
for (const page of [...matchedFromTopLevel, ...flattenedPages]) {
if (mergedMap.has(page.path)) {
orderedPages.push(mergedMap.get(page.path));
mergedMap.delete(page.path);
}
}
return dedupePages(orderedPages);
}
function getSubPackages(fullConfig, targetConfig) {
return fullConfig.subPackages
.filter((item) => targetConfig.subPackageMatcher(item.root))
.map((item) => JSON.parse(JSON.stringify(item)));
}
function dedupePages(pages) {
const seen = new Set();
return pages.filter((page) => {
if (seen.has(page.path)) {
return false;
}
seen.add(page.path);
return true;
});
}
function getCondition(targetConfig, sourceCondition) {
if (sourceCondition && Array.isArray(sourceCondition.list)) {
const filteredList = sourceCondition.list.filter(
(item) => item.path === targetConfig.entryPath,
);
if (filteredList.length > 0) {
return {
current: 0,
list: filteredList,
};
}
}
return targetConfig.defaultCondition();
}
function validateGeneratedConfig(targetName, config) {
const missingRoutes = [];
const routeSet = new Set();
for (const page of config.pages || []) {
routeSet.add(page.path);
if (!findMatchingPageFile(page.path)) {
missingRoutes.push(page.path);
}
}
for (const subPackage of config.subPackages || []) {
for (const page of subPackage.pages || []) {
const fullPath = `${subPackage.root}/${page.path}`;
routeSet.add(fullPath);
if (!findMatchingPageFile(fullPath)) {
missingRoutes.push(fullPath);
}
}
}
for (const tabItem of config.tabBar?.list || []) {
if (!routeSet.has(tabItem.pagePath)) {
missingRoutes.push(`tabBar -> ${tabItem.pagePath}`);
}
}
for (const conditionItem of config.condition?.list || []) {
if (!routeSet.has(conditionItem.path)) {
missingRoutes.push(`condition -> ${conditionItem.path}`);
}
}
if (missingRoutes.length > 0) {
console.error(`${targetName} 配置存在无效页面引用:`);
for (const routePath of missingRoutes) {
console.error(` - ${routePath}`);
}
process.exit(1);
}
// 备份当前 pages.json仅在未备份时执行避免覆盖真正的完整版本
if (!fs.existsSync(pagesFull)) {
fs.copyFileSync(pagesJson, pagesFull);
console.log("📦 已备份 pages.json → pages.full.json");
}
function buildTargetConfig(fullConfig, targetName, sourceCondition) {
const targetConfig = targetConfigs[targetName];
const nextConfig = {};
nextConfig.pages = getTopLevelPages(fullConfig, targetConfig);
nextConfig.subPackages = getSubPackages(fullConfig, targetConfig);
if (targetConfig.tabBarMatcher) {
const filteredTabBarList = (fullConfig.tabBar?.list || []).filter((item) =>
targetConfig.tabBarMatcher(item.pagePath),
);
if (filteredTabBarList.length > 0 && fullConfig.tabBar) {
nextConfig.tabBar = {
...JSON.parse(JSON.stringify(fullConfig.tabBar)),
list: filteredTabBarList,
};
}
}
fs.copyFileSync(pagesMerchant, pagesJson);
console.log("✅ 已切换为【商家端专属编译模式】");
console.log(" 仅包含 merchant 页面,差量编译速度大幅提升。");
for (const key of Object.keys(fullConfig)) {
if (["pages", "subPackages", "tabBar", "condition"].includes(key)) {
continue;
}
nextConfig[key] = JSON.parse(JSON.stringify(fullConfig[key]));
}
nextConfig.condition = getCondition(targetConfig, sourceCondition);
validateGeneratedConfig(targetName, nextConfig);
return nextConfig;
}
function writeTargetConfig(targetName, config) {
const targetPath = path.join(root, targetConfigs[targetName].fileName);
writeJson(targetPath, config);
fs.copyFileSync(targetPath, pagesJson);
const pageCount = config.pages.length;
const subPackageCount = config.subPackages.length;
const tabBarCount = config.tabBar?.list?.length || 0;
console.log(`✅ 已切换为【${targetConfigs[targetName].label}专属编译模式】`);
console.log(` 目标配置:${targetConfigs[targetName].fileName}`);
console.log(` pages${pageCount}`);
console.log(` subPackages${subPackageCount}`);
console.log(` tabBar${tabBarCount}`);
console.log(" 恢复完整版本npm run pages:full");
} else if (mode === "full") {
}
function restoreFullPages() {
if (!fs.existsSync(pagesFull)) {
console.error("❌ pages.full.json 不存在。");
console.error(" 可能当前已经是完整模式,或备份文件已被删除。");
process.exit(1);
}
backupCurrentPages("full");
fs.copyFileSync(pagesFull, pagesJson);
console.log("✅ 已恢复【完整 pages.json】");
console.log(" 包含 consumer + merchant + admin 全部页面。");
}
if (mode === "full") {
restoreFullPages();
} else if (Object.prototype.hasOwnProperty.call(targetConfigs, mode)) {
ensureFullBackup();
backupCurrentPages(mode);
const fullConfig = readJson(pagesFull);
const sourceCondition = fs.existsSync(pagesJson)
? (() => {
try {
return readJson(pagesJson).condition;
} catch (error) {
return null;
}
})()
: null;
const nextConfig = buildTargetConfig(fullConfig, mode, sourceCondition);
writeTargetConfig(mode, nextConfig);
} else {
console.log("用法:");
console.log(" npm run pages:consumer 切换到消费者端专属编译模式");
console.log(" npm run pages:merchant 切换到商家端专属编译模式");
console.log(" npm run pages:admin 切换到管理后台专属编译模式");
console.log(" npm run pages:full 恢复完整编译模式");
}