|
|
// scripts/clean-dev.ts
|
|
|
import fs from "fs/promises";
|
|
|
import path from "path";
|
|
|
|
|
|
// 现代化颜色主题
|
|
|
const theme = {
|
|
|
// 基础颜色
|
|
|
reset: "\x1b[0m",
|
|
|
bold: "\x1b[1m",
|
|
|
dim: "\x1b[2m",
|
|
|
|
|
|
// 前景色
|
|
|
primary: "\x1b[38;5;75m", // 亮蓝色
|
|
|
success: "\x1b[38;5;82m", // 亮绿色
|
|
|
warning: "\x1b[38;5;220m", // 亮黄色
|
|
|
error: "\x1b[38;5;196m", // 亮红色
|
|
|
info: "\x1b[38;5;159m", // 青色
|
|
|
purple: "\x1b[38;5;141m", // 紫色
|
|
|
orange: "\x1b[38;5;208m", // 橙色
|
|
|
gray: "\x1b[38;5;245m", // 灰色
|
|
|
white: "\x1b[38;5;255m", // 白色
|
|
|
|
|
|
// 背景色
|
|
|
bgDark: "\x1b[48;5;235m", // 深灰背景
|
|
|
bgBlue: "\x1b[48;5;24m", // 蓝色背景
|
|
|
bgGreen: "\x1b[48;5;22m", // 绿色背景
|
|
|
bgRed: "\x1b[48;5;52m", // 红色背景
|
|
|
};
|
|
|
|
|
|
// 现代化图标集
|
|
|
const icons = {
|
|
|
rocket: "🚀",
|
|
|
fire: "🔥",
|
|
|
star: "⭐",
|
|
|
gem: "💎",
|
|
|
crown: "👑",
|
|
|
magic: "✨",
|
|
|
warning: "⚠️",
|
|
|
success: "✅",
|
|
|
error: "❌",
|
|
|
info: "ℹ️",
|
|
|
folder: "📁",
|
|
|
file: "📄",
|
|
|
image: "🖼️",
|
|
|
code: "💻",
|
|
|
data: "📊",
|
|
|
globe: "🌐",
|
|
|
map: "🗺️",
|
|
|
chat: "💬",
|
|
|
bolt: "⚡",
|
|
|
shield: "🛡️",
|
|
|
key: "🔑",
|
|
|
link: "🔗",
|
|
|
clean: "🧹",
|
|
|
trash: "🗑️",
|
|
|
check: "✓",
|
|
|
cross: "✗",
|
|
|
arrow: "→",
|
|
|
loading: "⏳",
|
|
|
};
|
|
|
|
|
|
// 格式化工具
|
|
|
const fmt = {
|
|
|
title: (text: string) => `${theme.bold}${theme.primary}${text}${theme.reset}`,
|
|
|
subtitle: (text: string) => `${theme.purple}${text}${theme.reset}`,
|
|
|
success: (text: string) => `${theme.success}${text}${theme.reset}`,
|
|
|
error: (text: string) => `${theme.error}${text}${theme.reset}`,
|
|
|
warning: (text: string) => `${theme.warning}${text}${theme.reset}`,
|
|
|
info: (text: string) => `${theme.info}${text}${theme.reset}`,
|
|
|
highlight: (text: string) => `${theme.bold}${theme.white}${text}${theme.reset}`,
|
|
|
dim: (text: string) => `${theme.dim}${theme.gray}${text}${theme.reset}`,
|
|
|
orange: (text: string) => `${theme.orange}${text}${theme.reset}`,
|
|
|
|
|
|
// 带背景的文本
|
|
|
badge: (text: string, bg: string = theme.bgBlue) =>
|
|
|
`${bg}${theme.white}${theme.bold} ${text} ${theme.reset}`,
|
|
|
|
|
|
// 渐变效果模拟
|
|
|
gradient: (text: string) => {
|
|
|
const colors = ["\x1b[38;5;75m", "\x1b[38;5;81m", "\x1b[38;5;87m", "\x1b[38;5;159m"];
|
|
|
const chars = text.split("");
|
|
|
return chars.map((char, i) => `${colors[i % colors.length]}${char}`).join("") + theme.reset;
|
|
|
},
|
|
|
};
|
|
|
|
|
|
// 创建现代化标题横幅
|
|
|
function createModernBanner() {
|
|
|
console.log();
|
|
|
console.log(
|
|
|
fmt.gradient(" ╔══════════════════════════════════════════════════════════════════╗")
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ║ ║")
|
|
|
);
|
|
|
console.log(
|
|
|
` ║ ${icons.rocket} ${fmt.title("ART DESIGN PRO")} ${fmt.subtitle("· 代码精简程序")} ${icons.magic} ║`
|
|
|
);
|
|
|
console.log(
|
|
|
` ║ ${fmt.dim("为项目移除演示数据,快速切换至开发模式")} ║`
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ║ ║")
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ╚══════════════════════════════════════════════════════════════════╝")
|
|
|
);
|
|
|
console.log();
|
|
|
}
|
|
|
|
|
|
// 创建分割线
|
|
|
function createDivider(char = "─", color = theme.primary) {
|
|
|
console.log(`${color}${" " + char.repeat(66)}${theme.reset}`);
|
|
|
}
|
|
|
|
|
|
// 创建卡片样式容器
|
|
|
function createCard(title: string, content: string[]) {
|
|
|
console.log(` ${fmt.badge("", theme.bgBlue)} ${fmt.title(title)}`);
|
|
|
console.log();
|
|
|
content.forEach((line) => {
|
|
|
console.log(` ${line}`);
|
|
|
});
|
|
|
console.log();
|
|
|
}
|
|
|
|
|
|
// 进度条动画
|
|
|
function createProgressBar(current: number, total: number, text: string, width = 40) {
|
|
|
const percentage = Math.round((current / total) * 100);
|
|
|
const filled = Math.round((current / total) * width);
|
|
|
const empty = width - filled;
|
|
|
|
|
|
const filledBar = "█".repeat(filled);
|
|
|
const emptyBar = "░".repeat(empty);
|
|
|
|
|
|
process.stdout.write(
|
|
|
`\r ${fmt.info("进度")} [${theme.success}${filledBar}${theme.gray}${emptyBar}${theme.reset}] ${fmt.highlight(percentage + "%")})}`
|
|
|
);
|
|
|
|
|
|
if (current === total) {
|
|
|
console.log();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 统计信息
|
|
|
const stats = {
|
|
|
deletedFiles: 0,
|
|
|
deletedPaths: 0,
|
|
|
failedPaths: 0,
|
|
|
startTime: Date.now(),
|
|
|
totalFiles: 0,
|
|
|
};
|
|
|
|
|
|
// 清理目标
|
|
|
const targets = [
|
|
|
"README.md",
|
|
|
"README.zh-CN.md",
|
|
|
"CHANGELOG.md",
|
|
|
"CHANGELOG.zh-CN.md",
|
|
|
"src/views/safeguard",
|
|
|
"src/views/dashboard/analysis",
|
|
|
"src/views/dashboard/ecommerce",
|
|
|
"src/mock/json",
|
|
|
"src/mock/temp/articleList.ts",
|
|
|
"src/mock/temp/commentDetail.ts",
|
|
|
"src/mock/temp/commentList.ts",
|
|
|
"src/assets/images/cover",
|
|
|
"src/assets/images/safeguard",
|
|
|
"src/assets/images/3d",
|
|
|
"src/components/charts/art-map-chart",
|
|
|
"src/components/business/comment-widget",
|
|
|
];
|
|
|
|
|
|
// 递归统计文件数量
|
|
|
async function countFiles(targetPath: string): Promise<number> {
|
|
|
const fullPath = path.resolve(process.cwd(), targetPath);
|
|
|
|
|
|
try {
|
|
|
const stat = await fs.stat(fullPath);
|
|
|
|
|
|
if (stat.isFile()) {
|
|
|
return 1;
|
|
|
} else if (stat.isDirectory()) {
|
|
|
const entries = await fs.readdir(fullPath);
|
|
|
let count = 0;
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
const entryPath = path.join(targetPath, entry);
|
|
|
count += await countFiles(entryPath);
|
|
|
}
|
|
|
|
|
|
return count;
|
|
|
}
|
|
|
} catch {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// 统计所有目标的文件数量
|
|
|
async function countAllFiles(): Promise<number> {
|
|
|
let totalCount = 0;
|
|
|
|
|
|
for (const target of targets) {
|
|
|
const count = await countFiles(target);
|
|
|
totalCount += count;
|
|
|
}
|
|
|
|
|
|
return totalCount;
|
|
|
}
|
|
|
|
|
|
// 删除文件和目录
|
|
|
async function remove(targetPath: string, index: number) {
|
|
|
const fullPath = path.resolve(process.cwd(), targetPath);
|
|
|
|
|
|
createProgressBar(index + 1, targets.length, targetPath);
|
|
|
|
|
|
try {
|
|
|
const fileCount = await countFiles(targetPath);
|
|
|
await fs.rm(fullPath, { recursive: true, force: true });
|
|
|
stats.deletedFiles += fileCount;
|
|
|
stats.deletedPaths++;
|
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
|
} catch (err) {
|
|
|
stats.failedPaths++;
|
|
|
console.log();
|
|
|
console.log(` ${icons.error} ${fmt.error("删除失败")}: ${fmt.highlight(targetPath)}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 重置前端内置动态路由为空(`MenuProcessor.ts` 内 `builtinFrontendRoutes`;异常页在 staticRoutes)
|
|
|
async function cleanRouteModules() {
|
|
|
const routesPath = path.resolve(process.cwd(), "src/router");
|
|
|
|
|
|
try {
|
|
|
try {
|
|
|
await fs.rm(path.join(routesPath, "dashboard.ts"), { force: true });
|
|
|
} catch {
|
|
|
// 忽略
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
await fs.rm(path.join(routesPath, "builtinFrontendRoutes.ts"), { force: true });
|
|
|
} catch {
|
|
|
// 忽略(旧独立文件可能已不存在)
|
|
|
}
|
|
|
|
|
|
const menuProcessorPath = path.join(routesPath, "MenuProcessor.ts");
|
|
|
const mp = await fs.readFile(menuProcessorPath, "utf-8");
|
|
|
const reset = mp.replace(
|
|
|
/export const builtinFrontendRoutes: AppRouteRecord\[\] = \[[\s\S]*?\];/,
|
|
|
"export const builtinFrontendRoutes: AppRouteRecord[] = [];"
|
|
|
);
|
|
|
if (reset === mp) {
|
|
|
console.log(
|
|
|
` ${icons.warning} ${fmt.dim("MenuProcessor.ts 中未找到 builtinFrontendRoutes,跳过重置")}`
|
|
|
);
|
|
|
} else {
|
|
|
await fs.writeFile(menuProcessorPath, reset, "utf-8");
|
|
|
}
|
|
|
|
|
|
console.log(` ${icons.success} ${fmt.success("清理路由演示模块完成")}`);
|
|
|
} catch (err) {
|
|
|
console.log(` ${icons.error} ${fmt.error("清理路由演示模块失败")}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 路由占位常量已写在 src/router/staticRoutes.ts 顶部,清理脚本不再单独重写
|
|
|
async function cleanRouterConstants() {
|
|
|
console.log(
|
|
|
` ${icons.info} ${fmt.dim("路由常量(ROUTE_*)位于 staticRoutes.ts 顶部,请按需手动修改")}`
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// 清理变更日志
|
|
|
async function cleanChangeLog() {
|
|
|
const changeLogPath = path.resolve(process.cwd(), "src/mock/upgrade/changeLog.ts");
|
|
|
|
|
|
try {
|
|
|
const cleanedChangeLog = `import { ref } from 'vue'
|
|
|
|
|
|
interface UpgradeLog {
|
|
|
version: string // 版本号
|
|
|
title: string // 更新标题
|
|
|
date: string // 更新日期
|
|
|
detail?: string[] // 更新内容
|
|
|
requireReLogin?: boolean // 是否需要重新登录
|
|
|
remark?: string // 备注
|
|
|
}
|
|
|
|
|
|
export const upgradeLogList = ref<UpgradeLog[]>([])
|
|
|
`;
|
|
|
|
|
|
await fs.writeFile(changeLogPath, cleanedChangeLog, "utf-8");
|
|
|
console.log(` ${icons.success} ${fmt.success("清空变更日志数据完成")}`);
|
|
|
} catch (err) {
|
|
|
console.log(` ${icons.error} ${fmt.error("清理变更日志失败")}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 清理语言文件
|
|
|
async function cleanLanguageFiles() {
|
|
|
const languageFiles = [
|
|
|
{ path: "src/locales/langs/zh.json", name: "中文语言文件" },
|
|
|
{ path: "src/locales/langs/en.json", name: "英文语言文件" },
|
|
|
];
|
|
|
|
|
|
for (const { path: langPath, name } of languageFiles) {
|
|
|
try {
|
|
|
const fullPath = path.resolve(process.cwd(), langPath);
|
|
|
const content = await fs.readFile(fullPath, "utf-8");
|
|
|
const langData = JSON.parse(content);
|
|
|
|
|
|
const menusToRemove = [
|
|
|
"widgets",
|
|
|
"template",
|
|
|
"article",
|
|
|
"examples",
|
|
|
"safeguard",
|
|
|
"plan",
|
|
|
"help",
|
|
|
];
|
|
|
|
|
|
if (langData.menus) {
|
|
|
menusToRemove.forEach((menuKey) => {
|
|
|
if (langData.menus[menuKey]) {
|
|
|
delete langData.menus[menuKey];
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if (langData.menus.dashboard) {
|
|
|
if (langData.menus.dashboard.analysis) {
|
|
|
delete langData.menus.dashboard.analysis;
|
|
|
}
|
|
|
if (langData.menus.dashboard.ecommerce) {
|
|
|
delete langData.menus.dashboard.ecommerce;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (langData.menus.system) {
|
|
|
const systemKeysToRemove = [
|
|
|
"nested",
|
|
|
"menu1",
|
|
|
"menu2",
|
|
|
"menu21",
|
|
|
"menu3",
|
|
|
"menu31",
|
|
|
"menu32",
|
|
|
"menu321",
|
|
|
];
|
|
|
systemKeysToRemove.forEach((key) => {
|
|
|
if (langData.menus.system[key]) {
|
|
|
delete langData.menus.system[key];
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
await fs.writeFile(fullPath, JSON.stringify(langData, null, 2), "utf-8");
|
|
|
console.log(` ${icons.success} ${fmt.success(`清理${name}完成`)}`);
|
|
|
} catch (err) {
|
|
|
console.log(` ${icons.error} ${fmt.error(`清理${name}失败`)}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 清理快速入口组件
|
|
|
async function cleanFastEnterComponent() {
|
|
|
const fastEnterPath = path.resolve(process.cwd(), "src/config/fastEnter.ts");
|
|
|
|
|
|
try {
|
|
|
const cleanedFastEnter = `/**
|
|
|
* 快速入口配置
|
|
|
* 包含:应用列表、快速链接等配置
|
|
|
*/
|
|
|
import { WEB_LINKS } from "@utils/constants";
|
|
|
import type { FastEnterConfig } from '@/types/config'
|
|
|
|
|
|
const fastEnterConfig: FastEnterConfig = {
|
|
|
// 显示条件(屏幕宽度)
|
|
|
minWidth: 1200,
|
|
|
// 应用列表
|
|
|
applications: [
|
|
|
{
|
|
|
name: '工作台',
|
|
|
description: '系统概览与数据统计',
|
|
|
icon: 'ri:pie-chart-line',
|
|
|
iconColor: '#377dff',
|
|
|
enabled: true,
|
|
|
order: 1,
|
|
|
routeName: 'Console'
|
|
|
},
|
|
|
{
|
|
|
name: '官方文档',
|
|
|
description: '使用指南与开发文档',
|
|
|
icon: 'ri:bill-line',
|
|
|
iconColor: '#ffb100',
|
|
|
enabled: true,
|
|
|
order: 2,
|
|
|
link: WEB_LINKS.DOCS
|
|
|
},
|
|
|
{
|
|
|
name: '技术支持',
|
|
|
description: '技术支持与问题反馈',
|
|
|
icon: 'ri:user-location-line',
|
|
|
iconColor: '#ff6b6b',
|
|
|
enabled: true,
|
|
|
order: 3,
|
|
|
link: WEB_LINKS.COMMUNITY
|
|
|
},
|
|
|
{
|
|
|
name: '哔哩哔哩',
|
|
|
description: '技术分享与交流',
|
|
|
icon: 'ri:bilibili-line',
|
|
|
iconColor: '#FB7299',
|
|
|
enabled: true,
|
|
|
order: 4,
|
|
|
link: WEB_LINKS.BILIBILI
|
|
|
}
|
|
|
],
|
|
|
// 快速链接
|
|
|
quickLinks: [
|
|
|
{
|
|
|
name: '登录',
|
|
|
enabled: true,
|
|
|
order: 1,
|
|
|
routeName: 'Login'
|
|
|
},
|
|
|
{
|
|
|
name: '注册',
|
|
|
enabled: true,
|
|
|
order: 2,
|
|
|
routeName: 'Login'
|
|
|
},
|
|
|
{
|
|
|
name: '忘记密码',
|
|
|
enabled: true,
|
|
|
order: 3,
|
|
|
routeName: 'Login'
|
|
|
},
|
|
|
{
|
|
|
name: '个人中心',
|
|
|
enabled: true,
|
|
|
order: 4,
|
|
|
routeName: 'Profile'
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
|
|
|
export default Object.freeze(fastEnterConfig)
|
|
|
`;
|
|
|
|
|
|
await fs.writeFile(fastEnterPath, cleanedFastEnter, "utf-8");
|
|
|
console.log(` ${icons.success} ${fmt.success("清理快速入口配置完成")}`);
|
|
|
} catch (err) {
|
|
|
console.log(` ${icons.error} ${fmt.error("清理快速入口配置失败")}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 更新菜单接口
|
|
|
async function updateMenuApi() {
|
|
|
const apiPath = path.resolve(process.cwd(), "src/api/system-manage.ts");
|
|
|
|
|
|
try {
|
|
|
const content = await fs.readFile(apiPath, "utf-8");
|
|
|
const updatedContent = content.replace(
|
|
|
"url: '/api/v3/system/menus'",
|
|
|
"url: '/api/v3/system/menus/simple'"
|
|
|
);
|
|
|
|
|
|
await fs.writeFile(apiPath, updatedContent, "utf-8");
|
|
|
console.log(` ${icons.success} ${fmt.success("更新菜单接口完成")}`);
|
|
|
} catch (err) {
|
|
|
console.log(` ${icons.error} ${fmt.error("更新菜单接口失败")}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 用户确认函数
|
|
|
async function getUserConfirmation(): Promise<boolean> {
|
|
|
const { createInterface } = await import("readline");
|
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
const rl = createInterface({
|
|
|
input: process.stdin,
|
|
|
output: process.stdout,
|
|
|
});
|
|
|
|
|
|
console.log(
|
|
|
` ${fmt.highlight("请输入")} ${fmt.success("yes")} ${fmt.highlight("确认执行清理操作,或按 Enter 取消")}`
|
|
|
);
|
|
|
console.log();
|
|
|
process.stdout.write(` ${icons.arrow} `);
|
|
|
|
|
|
rl.question("", (answer: string) => {
|
|
|
rl.close();
|
|
|
resolve(answer.toLowerCase().trim() === "yes");
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 显示清理警告
|
|
|
async function showCleanupWarning() {
|
|
|
createCard("安全警告", [
|
|
|
`${fmt.warning("此操作将永久删除以下演示内容,且无法恢复!")}`,
|
|
|
`${fmt.dim("请仔细阅读清理列表,确认后再继续操作")}`,
|
|
|
]);
|
|
|
|
|
|
const cleanupItems = [
|
|
|
{
|
|
|
icon: icons.image,
|
|
|
name: "图片资源",
|
|
|
desc: "演示用的封面图片、3D图片、运维图片等",
|
|
|
color: theme.orange,
|
|
|
},
|
|
|
{
|
|
|
icon: icons.file,
|
|
|
name: "演示页面",
|
|
|
desc: "widgets、article、examples、safeguard 等页面",
|
|
|
color: theme.purple,
|
|
|
},
|
|
|
{
|
|
|
icon: icons.code,
|
|
|
name: "路由模块文件",
|
|
|
desc: "删除演示路由模块,只保留核心模块(dashboard、system、result、exception)",
|
|
|
color: theme.primary,
|
|
|
},
|
|
|
{
|
|
|
icon: icons.link,
|
|
|
name: "路由常量",
|
|
|
desc: "占位路径见 staticRoutes.ts 顶部(脚本不自动覆盖)",
|
|
|
color: theme.info,
|
|
|
},
|
|
|
{
|
|
|
icon: icons.data,
|
|
|
name: "Mock数据",
|
|
|
desc: "演示用的JSON数据、文章列表、评论数据等",
|
|
|
color: theme.success,
|
|
|
},
|
|
|
{
|
|
|
icon: icons.globe,
|
|
|
name: "多语言文件",
|
|
|
desc: "清理中英文语言包中的演示菜单项",
|
|
|
color: theme.warning,
|
|
|
},
|
|
|
{ icon: icons.map, name: "地图组件", desc: "移除art-map-chart地图组件", color: theme.error },
|
|
|
{ icon: icons.chat, name: "评论组件", desc: "移除comment-widget评论组件", color: theme.orange },
|
|
|
{
|
|
|
icon: icons.bolt,
|
|
|
name: "快速入口",
|
|
|
desc: "移除分析页、礼花效果、聊天、更新日志、定价、留言管理等无效项目",
|
|
|
color: theme.purple,
|
|
|
},
|
|
|
];
|
|
|
|
|
|
console.log(` ${fmt.badge("", theme.bgRed)} ${fmt.title("将要清理的内容")}`);
|
|
|
console.log();
|
|
|
|
|
|
cleanupItems.forEach((item, index) => {
|
|
|
console.log(` ${item.color}${theme.reset} ${fmt.highlight(`${index + 1}. ${item.name}`)}`);
|
|
|
console.log(` ${fmt.dim(item.desc)}`);
|
|
|
});
|
|
|
|
|
|
console.log();
|
|
|
console.log(` ${fmt.badge("", theme.bgGreen)} ${fmt.title("保留的功能模块")}`);
|
|
|
console.log();
|
|
|
|
|
|
const preservedModules = [
|
|
|
{ name: "Dashboard", desc: "工作台页面" },
|
|
|
{ name: "System", desc: "系统管理模块" },
|
|
|
{ name: "Result", desc: "结果页面" },
|
|
|
{ name: "Exception", desc: "异常页面" },
|
|
|
{ name: "Auth", desc: "登录注册功能" },
|
|
|
{ name: "Core Components", desc: "核心组件库" },
|
|
|
];
|
|
|
|
|
|
preservedModules.forEach((module) => {
|
|
|
console.log(` ${icons.check} ${fmt.success(module.name)} ${fmt.dim(`- ${module.desc}`)}`);
|
|
|
});
|
|
|
|
|
|
console.log();
|
|
|
createDivider();
|
|
|
console.log();
|
|
|
}
|
|
|
|
|
|
// 显示统计信息
|
|
|
async function showStats() {
|
|
|
const duration = Date.now() - stats.startTime;
|
|
|
const seconds = (duration / 1000).toFixed(2);
|
|
|
|
|
|
console.log();
|
|
|
createCard("清理统计", [
|
|
|
`${fmt.success("成功删除")}: ${fmt.highlight(stats.deletedFiles.toString())} 个文件`,
|
|
|
`${fmt.info("涉及路径")}: ${fmt.highlight(stats.deletedPaths.toString())} 个目录/文件`,
|
|
|
...(stats.failedPaths > 0
|
|
|
? [
|
|
|
`${icons.error} ${fmt.error("删除失败")}: ${fmt.highlight(stats.failedPaths.toString())} 个路径`,
|
|
|
]
|
|
|
: []),
|
|
|
`${fmt.info("耗时")}: ${fmt.highlight(seconds)} 秒`,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
// 创建成功横幅
|
|
|
function createSuccessBanner() {
|
|
|
console.log();
|
|
|
console.log(
|
|
|
fmt.gradient(" ╔══════════════════════════════════════════════════════════════════╗")
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ║ ║")
|
|
|
);
|
|
|
console.log(
|
|
|
` ║ ${icons.star} ${fmt.success("清理完成!项目已准备就绪")} ${icons.rocket} ║`
|
|
|
);
|
|
|
console.log(
|
|
|
` ║ ${fmt.dim("现在可以开始您的开发之旅了!")} ║`
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ║ ║")
|
|
|
);
|
|
|
console.log(
|
|
|
fmt.gradient(" ╚══════════════════════════════════════════════════════════════════╝")
|
|
|
);
|
|
|
console.log();
|
|
|
}
|
|
|
|
|
|
// 主函数
|
|
|
async function main() {
|
|
|
// 清屏并显示横幅
|
|
|
console.clear();
|
|
|
createModernBanner();
|
|
|
|
|
|
// 显示清理警告
|
|
|
await showCleanupWarning();
|
|
|
|
|
|
// 统计文件数量
|
|
|
console.log(` ${fmt.info("正在统计文件数量...")}`);
|
|
|
stats.totalFiles = await countAllFiles();
|
|
|
|
|
|
console.log(` ${fmt.info("即将清理")}: ${fmt.highlight(stats.totalFiles.toString())} 个文件`);
|
|
|
console.log(` ${fmt.dim(`涉及 ${targets.length} 个目录/文件路径`)}`);
|
|
|
console.log();
|
|
|
|
|
|
// 用户确认
|
|
|
const confirmed = await getUserConfirmation();
|
|
|
|
|
|
if (!confirmed) {
|
|
|
console.log(` ${fmt.warning("操作已取消,清理中止")}`);
|
|
|
console.log();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
console.log();
|
|
|
console.log(` ${icons.check} ${fmt.success("确认成功,开始清理...")}`);
|
|
|
console.log();
|
|
|
|
|
|
// 开始清理过程
|
|
|
console.log(` ${fmt.badge("步骤 1/6", theme.bgBlue)} ${fmt.title("删除演示文件")}`);
|
|
|
console.log();
|
|
|
for (let i = 0; i < targets.length; i++) {
|
|
|
await remove(targets[i], i);
|
|
|
}
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 2/6", theme.bgBlue)} ${fmt.title("清理路由模块")}`);
|
|
|
console.log();
|
|
|
await cleanRouteModules();
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 3/6", theme.bgBlue)} ${fmt.title("重写路由常量")}`);
|
|
|
console.log();
|
|
|
await cleanRouterConstants();
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 4/6", theme.bgBlue)} ${fmt.title("清空变更日志")}`);
|
|
|
console.log();
|
|
|
await cleanChangeLog();
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 5/6", theme.bgBlue)} ${fmt.title("清理语言文件")}`);
|
|
|
console.log();
|
|
|
await cleanLanguageFiles();
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 6/7", theme.bgBlue)} ${fmt.title("清理快速入口")}`);
|
|
|
console.log();
|
|
|
await cleanFastEnterComponent();
|
|
|
console.log();
|
|
|
|
|
|
console.log(` ${fmt.badge("步骤 7/7", theme.bgBlue)} ${fmt.title("更新菜单接口")}`);
|
|
|
console.log();
|
|
|
await updateMenuApi();
|
|
|
|
|
|
// 显示统计信息
|
|
|
await showStats();
|
|
|
|
|
|
// 显示成功横幅
|
|
|
createSuccessBanner();
|
|
|
}
|
|
|
|
|
|
main().catch((err) => {
|
|
|
console.log();
|
|
|
console.log(` ${icons.error} ${fmt.error("清理脚本执行出错")}`);
|
|
|
console.log(` ${fmt.dim("错误详情: " + err)}`);
|
|
|
console.log();
|
|
|
process.exit(1);
|
|
|
});
|