feat:提交

This commit is contained in:
2025-07-30 17:59:40 +08:00
commit 60f31b9299
16 changed files with 1995 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
mes-processors-libs-*.tgz

16
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "针对 localhost 启动 Chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
// libs工作区必须使用相对路径进行导入
"typescript.preferences.importModuleSpecifier": "relative",
"javascript.preferences.importModuleSpecifier": "relative"
}

111
README.md Normal file
View File

@@ -0,0 +1,111 @@
# @mes-processors/libs
这是一个用于处理MES制造执行系统相关工作流的处理器类库。
## 安装
在内网环境下执行以下脚本进行安装
```sh
pnpm add http://gitea.cf/MES-FE/mes-packages/releases/download/0.1/mes-processors-libs-0.1.0.tgz
```
> [!CAUTION]
> 在安装库之前,请确认以下信息:
>
> - 该库发布于内网gitea仓库的release中所以你需要提前在gitea中进行登录并确保你有该仓库的访问权限。
> - 库的版本需要手动进行控制,注意上述链接中的版本信息,在安装前需要主动修改版本号,请前往<http://gitea.cf/MES-FE/mes-packages/releases>来确认最新版本。
## 使用
该库提供了MES/iMES公用的处理器并已配置为导出项请参考以下Typescript代码进行使用
```ts
// 引入矩形优化处理器
import { RectLayoutProcConfig } from 'cut-abstractions';
import { RectLayoutProc } from '@mes-processors/libs';
// 实例化处理器
const proc = new RectLayoutProc();
// 构建上下文f proc.exec>[0] = {
input: testObj,
params: new RectLayoutProcConfig()
};
// 异步执行
const ctx: Parameters<typeo
await proc.exec(ctx);
// 从上下文对象中获取输出内容
console.log("RESULT: ", ctx.output);
```
## Q&A
### 运行某些处理器时出现404(Not Found)错误
**错误描述**
当执行处理器时,出现类似下面的错误:
```log
GET http://localhost:5173/node_modules/.vite/deps/assets/RectOptimizeMachine.worker-BO2fmpVH.js 404 (Not Found)
```
**根本原因**
该库中某些处理器使用了Web Worker来实现多线程异步处理例如矩形优化处理器
Web Worker为单独打包的资产文件但某些打包工具可能会对`node_modules`中的依赖进行预构建来提高性能如果Worker文件被视为了预构建的一部分就可能导致处理器无法正确地处理Worker文件的相对引用路径导致在运行时尝试从`node_modules/.vite/deps/assets/`这样的内部路径加载,而这个路径在实际部署或服务时是不存在的。
**解决方法**
在打包工具中对该库进行配置,禁用对该库的优化和预构建,以`vite`为例:
```ts
// vite.config.ts
...
optimizeDeps: {
exclude: ["@mes-processors/libs"] // 从optimizeDeps中排除该库
}
...
```
## 开发
### 发布并打包项目
```sh
pnpm build
pnpm pack
```
> [!NOTE]
> 发布前记得更改版本号
### 约定
**目录**
```
src
├── modules 项目模块分组
├── processors 处理器
└── utils 公用的工具类
```
**导出和打包**
- 编写的处理器请在`src/index.ts`中进行导出
- 编写的工具类请在`src/utils/index.ts`中进行导出
- 在打包时项目仅会对`src/index.ts`进行打包,工具类相关模块不会进行打包
- 关于打包相关明细请自行查看相关文件
- [package.json](package.json)
- [vite.config.ts](vite.config.ts)
> [!WARNING]
> 在该工作区中编写模块时,禁止使用绝对路径进行导入,禁止在`tsconfig.json`或`vite.config.ts`中添加"@"别名所有导入语句请使用相对路径进行引入否则会因monorepo内部导入混乱导致模块解析失败。
### 测试
项目使用[Vitest](http://vitest.dev/)作为单元测试框架若要对TS文件编写单元测试请在文件的同目录下创建`<文件名>.test.ts`文件并遵循Vitest规范编写单元测试。
要执行单元测试,请运行下面的命令:
```sh
pnpm test
```

38
package.json Normal file
View File

@@ -0,0 +1,38 @@
{
"name": "@imes-procesor/libs",
"version": "0.1.0",
"description": "",
"type": "module",
"scripts": {
"build": "vite build",
"test": "vitest",
"check": "tsc --noEmit --skipLibCheck -p tsconfig.app.json"
},
"files": [
"dist",
"package.json",
"src",
"tsconfig.json",
"tsconfig.app.json",
"tsconfig.node.json"
],
"exports": {
".": "./src/index.ts",
"./utils": "./src/utils/index.ts"
},
"dependencies": {
"cut-abstractions": "http://gitea.cf/MES-FE/cut-abstractions/releases/download/0.2/cut-abstractions-0.2.0.tgz"
},
"devDependencies": {
"@types/node": "^24.0.10",
"typescript": "~5.8.3",
"vite": "^7.0.0",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-node-polyfills": "^0.24.0",
"vite-plugin-resolve": "^2.5.2",
"vitest": "^3.2.4"
},
"keywords": [],
"author": "",
"license": "ISC"
}

8
src/index.ts Normal file
View File

@@ -0,0 +1,8 @@
/**
* @package @mes-processors/libs
* @author LX
* @description 工作流处理器类库,在这个文件中使用导出时,不要在路径中使用'@',否则模块无法加载
*/
// CutOrder
export * from "./processors/cutOrder/CutOrder";

2
src/modules/README.md Normal file
View File

@@ -0,0 +1,2 @@
### react-layout
矩形优化算法(陈总新优化)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
import { ProcessorBase, ProcessorContext, CutOrderInput, CutorderOutput, CutorderConfig } from "cut-abstractions";
import { KLSC, YH_bang } from "../../modules/cutOrder/KLSCclass";
/**
* 开料顺序 --新算法
*/
export class CutOrderProc extends ProcessorBase<CutOrderInput, CutorderOutput, CutorderConfig> {
get name(): string {
return 'imes-cutOrder';
}
get version(): string {
return '1.0.0';
}
exec(context: ProcessorContext<CutOrderInput, CutorderOutput, CutorderConfig>): Promise<void> | void {
return new Promise(async (resolve, reject) => {
try {
/** 验证入参 */
let check = this.checkInput(context?.input)
if (check.isOk == false) {
reject(check.msg)
return
} else {
let bangs: YH_bang[] = []
let blocks = new Array()
let length = context.input?.blocks.length || 0
let beginId = 0;
let dt = context.input?.gap || 6;
let k = context.input?.boardWidth || 0;
let g = context.input?.boardHeight || 0;
for (let i = 0; i < length; i++) {
let block = context.input?.blocks[i];
let bangid = i + 1;
let x = block?.x;
let y = block?.y;
let pbg = block?.length;
let pbk = block?.width;
blocks[bangid] = block;
if (x == undefined) {
reject(`block ${block?.id} x is undefined`)
return
} else if (y == undefined) {
reject(`block ${block?.id} y is undefined`)
return
}
else if (pbg == undefined) {
reject(`block ${block?.id} pbg is undefined`)
return
} else if (pbk == undefined) {
reject(`block ${block?.id} pbk is undefined`)
return
}
bangs.push({
bangid,
line: 0,
pbg,
pbk,
x,
y,
ishb: false,
hb: [],
isbig: false,
isqg: false,
isgr: false,
gr: [],
grid: -1
});
}
let xdsc = new KLSC(bangs, k, g, dt, 0, 0, 1);
let rt = xdsc.SCid;
if (rt.length < length) {
reject('开料顺序算法异常,计算结果与板件数不匹配。')
return
};
for (let i = 0; i < rt.length; i++) {
let bid = rt[i];
beginId++;
blocks[bid].cutOrder = beginId;
}
context.output = {
blocks
}
}
resolve()
} catch (error) {
reject(error);
}
});
}
private checkInput(input?: CutOrderInput) {
let info: any = {
isOk: true,
msg: ''
}
if (input == undefined) {
info.isOk = false
info.msg = 'context.input is undefind'
} else if (input.blocks == undefined) {
info.isOk = false
info.msg = 'context.input.blocks is undefind'
} else if (input.gap == undefined) {
info.isOk = false
info.msg = 'context.input.gap is undefind'
} else if (input.boardWidth == undefined) {
info.isOk = false
info.msg = 'context.input.boardWidth is undefind'
} else if (input.boardHeight == undefined) {
info.isOk = false
info.msg = 'context.input.boardHeight is undefind'
}
return info
}
}

View File

@@ -0,0 +1,61 @@
import { test } from 'vitest'
import { CutOrderProc } from './CutOrder';
import { CutorderConfig, CutOrderInput, CutorderInputBlock } from 'cut-abstractions';
test('cutOrderTest', async () => {
let cutOrderProc = new CutOrderProc()
let params: CutorderConfig = new CutorderConfig()
let blocks: CutorderInputBlock[] = [
{
id: 25030882560,
length: 598,
width: 398,
x: 3.005,
y: 4,
},
{
id: 25030882561,
length: 598,
width: 398,
x: 3.005,
y: 610,
},
{
id: 25030882562,
length: 598,
width: 398,
x: 3.005,
y: 1216,
},
{
id: 25030882563,
length: 598,
width: 398,
x: 3.005,
y: 1821.005,
},
{
id: 25030882564,
length: 598,
width: 398,
x: 407.015,
y: 3.005,
},
]
let input: CutOrderInput = {
boardWidth: 1220,
boardHeight: 2440,
gap: 6,
blocks
}
const context = {
input,
params
}
await cutOrderProc.exec(context)
// 将在context的output中显示结果
console.log(context);
})

View File

1
src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />

39
tsconfig.app.json Normal file
View File

@@ -0,0 +1,39 @@
{
// TODO: Warn: 在进行TS类型检查的时候会检查到workflow工作区中的文件原因未知
"compilerOptions": {
"lib": [
"ES2020",
"ES2021",
"ESNext",
"DOM",
"DOM.Iterable"
],
"noEmit": true,
"target": "esnext",
"module": "ESNext",
"moduleResolution": "Bundler",
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
// 为了保证导入不与被引入项目冲突,不应该配置'@/*'别名
"@libs/*": [
"./src/*"
]
},
/* Linting */
"strict": true,
"erasableSyntaxOnly": false,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"composite": true
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
],
"exclude": [
"src/**/__tests__/*",
"dist",
"node_modules/**"
]
}

7
tsconfig.json Normal file
View File

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

25
tsconfig.node.json Normal file
View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
},
"include": ["vite.config.ts"]
}

34
vite.config.ts Normal file
View File

@@ -0,0 +1,34 @@
/// <reference types="vitest/config" />
import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import { resolve } from 'node:path';
import dts from 'vite-plugin-dts';
let basePath = process.env.basePath ?? '';
// https://vite.dev/config/
export default defineConfig({
base: basePath,
plugins: [
nodePolyfills(),
dts({rollupTypes: true, tsconfigPath: './tsconfig.app.json',insertTypesEntry: true}),
],
build: {
modulePreload: {
resolveDependencies() {
return [];
}
},
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MesCutorder',
fileName(format) {
return `mes-cutorder.${format}.js`
},
formats: ['es', 'umd', 'iife']
}
},
esbuild: {
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
},
})