完成了 BOM 管理和生产管理,完成部分发料单、采购计划和调拨单。

This commit is contained in:
c
2026-02-28 18:18:01 +08:00
commit 219eef4729
399 changed files with 46113 additions and 0 deletions

61
node/compress.ts Normal file
View File

@@ -0,0 +1,61 @@
import type { Plugin } from "vite";
import compressPlugin from "vite-plugin-compression";
/**
* 打包压缩格式的类型声明
*/
export type ViteCompression = "none" | "gzip" | "brotli" | "both" | "gzip-clear" | "brotli-clear" | "both-clear";
export const configCompressPlugin = (compress: ViteCompression): Plugin | Plugin[] => {
if (!compress || compress === "none") return [];
const gz = {
// 生成的压缩包后缀
ext: ".gz",
// 体积大于 threshold 才会被压缩
threshold: 0,
// 默认压缩 .js|mjs|json|css|html 后缀文件,设置成 true压缩全部文件
filter: () => true,
// 压缩后是否删除原始文件
deleteOriginFile: false,
};
const br = {
ext: ".br",
algorithm: "brotliCompress",
threshold: 0,
filter: () => true,
deleteOriginFile: false,
};
const codeList = [
{ k: "gzip", v: gz },
{ k: "brotli", v: br },
{ k: "both", v: [gz, br] },
];
const plugins: Plugin[] = [];
codeList.forEach((item: any) => {
if (compress.includes(item.k)) {
if (compress.includes("clear")) {
if (Array.isArray(item.v)) {
item.v.forEach((vItem: any) => {
plugins.push(compressPlugin(Object.assign(vItem, { deleteOriginFile: true })));
});
} else {
plugins.push(compressPlugin(Object.assign(item.v, { deleteOriginFile: true })));
}
} else {
if (Array.isArray(item.v)) {
item.v.forEach((vItem: any) => {
plugins.push(compressPlugin(vItem));
});
} else {
plugins.push(compressPlugin(item.v));
}
}
}
});
return plugins;
};

72
node/getEnv.ts Normal file
View File

@@ -0,0 +1,72 @@
import fs from "fs";
import path from "path";
import dotenv from "dotenv";
export type Recordable<T = any> = Record<string, T>;
export function isDevFn(mode: string): boolean {
return mode === "development";
}
export function isProdFn(mode: string): boolean {
return mode === "production";
}
/**
* 是否开启生成 package 报告
*/
export function isReportMode(): boolean {
return process.env.VITE_REPORT === "true";
}
/**
* 重新解析 .env 的内容,重新封装类型,比如 .env 定义了 truefalse默认为字符串类型需要转换为 boolean 类型
*/
export function wrapperEnv(envConf: Recordable): ImportMetaEnv {
const ret: any = {};
for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, "\n");
// 将 true 和 false 字符串转换为布尔值
realName = realName === "true" ? true : realName === "false" ? false : realName;
// 指定变量名进行类型转换
if (envName === "VITE_PORT") realName = Number(realName);
ret[envName] = realName;
process.env[envName] = realName;
}
return ret;
}
/**
* 从环境变量文件里获取变量值
*
* @param match 前缀
* @param confFiles 文件列表
*/
export function getEnvConfig(match = "VITE_", confFiles = [".env", ".env.production", ".env.sit", ".env.uat"]) {
let envConfig = {};
confFiles.forEach(item => {
try {
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
envConfig = { ...envConfig, ...env };
} catch (error) {
console.error(`Error in parsing ${item}`, error);
}
});
Object.keys(envConfig).forEach(key => {
const reg = new RegExp(`^(${match})`);
if (!reg.test(key)) {
Reflect.deleteProperty(envConfig, key);
}
});
return envConfig;
}
/**
* 获取项目根路径
*/
export function getRootPath(...dir: string[]) {
return path.resolve(process.cwd(), ...dir);
}

23
node/optimize.ts Normal file
View File

@@ -0,0 +1,23 @@
/**
* 此文件作用于 `vite.config.ts` 的 `optimizeDeps.include` 依赖预构建配置项
* 依赖预构建,`vite` 启动时会将下面 include 里的模块,编译成 esm 格式并缓存到 node_modules/.vite 文件夹,页面加载到对应模块时如果浏览器有缓存就读取浏览器缓存,如果没有会读取本地缓存并按需加载
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里否则会遇到开发环境切换页面卡顿的问题vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
*/
const include = [
"qs",
"mitt",
"axios",
"pinia",
"vue-i18n",
"sortablejs",
"@vueuse/core",
"pinia-plugin-persistedstate",
];
/**
* 在预构建中强制排除的依赖项
*/
const exclude = ["@iconify-icons/ant-design"];
export { include, exclude };

76
node/plugins.ts Normal file
View File

@@ -0,0 +1,76 @@
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import { resolve } from "path";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import { createStyleImportPlugin, ElementPlusResolve } from "vite-plugin-style-import";
import eslintPlugin from "vite-plugin-eslint";
import progress from "vite-plugin-progress";
import ServerUrlCopy from "vite-plugin-url-copy";
import vueDevTools from "vite-plugin-vue-devtools";
import { visualizer } from "rollup-plugin-visualizer";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { configCompressPlugin } from "./compress";
export function getPluginsList(command: string, viteEnv: ImportMetaEnv) {
const lifecycle = process.env.npm_lifecycle_event;
return [
vue(),
vueJsx(),
viteEnv.VITE_DEVTOOLS && vueDevTools(),
eslintPlugin({ cache: false }), // EsLint 报错信息显示在浏览器界面上
ServerUrlCopy({
qrcode: {
disabled: true, // 是否生成二维码
},
}),
progress(),
!viteEnv.VITE_LOAD_ALL_EP_STYLE
? createStyleImportPlugin({
resolves: [ElementPlusResolve()],
libs: [
{
libraryName: "element-plus",
esModule: true,
resolveStyle: name => {
if (!name.startsWith("el-")) return "";
return `element-plus/theme-chalk/src/${name.replace(/^el-/, "")}.scss`;
},
},
],
})
: undefined,
AutoImport({
imports: ["vue", "vue-router", "pinia"], // 自动引入 vue 的 ref、toRefs、onMounted 等,无需在页面中再次引入
dts: "src/types/auto-import.d.ts", // 生成在 src 路径下名为 auto-import.d.ts 的声明文件
eslintrc: {
enabled: false, // 改为 true 用于生成 eslint 配置。生成后改回 false避免重复生成消耗
},
resolvers: !viteEnv.VITE_LOAD_ALL_EP_COMPONENTS ? [ElementPlusResolver()] : [],
}),
!viteEnv.VITE_LOAD_ALL_EP_COMPONENTS
? Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
dirs: "src/components", // 自定引入需要扫描的组件路径
dts: "src/types/auto-components.d.ts", // 生成在 src 路径下名为 auto-components.d.ts 的声明文件
directoryAsNamespace: true,
})
: undefined,
// 使用 svg 图标
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), "src/common/assets/icons")],
symbolId: "icon-[dir]-[name]",
}),
viteEnv.VITE_BUILD_GZIP && configCompressPlugin(viteEnv.VITE_COMPRESSION),
// 打包分析
(lifecycle === "report" || viteEnv.VITE_REPORT) &&
visualizer({ open: true, brotliSize: true, filename: "report.html" }),
];
}