@mldong/jeeflow 1.8.15 → 1.8.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/facade.js +41 -12
- package/dist/jdbc/mysql.js +7 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -49,6 +49,7 @@ const repo = new JdbcRepository(new MysqlAdapter(pool), new TsIDGenerator())
|
|
|
49
49
|
|
|
50
50
|
- MySQL 连接池必须带 `supportBigNumbers: true, bigNumberStrings: true`;PostgreSQL 的 int8 默认即字符串,无此要求
|
|
51
51
|
- 引擎侧已做驱动兜底:`rowId()` 把驱动返回的 number/string 统一归一化为 string,未开 `bigNumberStrings` 时小 id(Node 自建)仍可用
|
|
52
|
+
- `MysqlAdapter` 走 `query()` 不走 `execute()`:mysql2 预处理绑 `LIMIT ?` 会失败,分页整段 99999999(issues/66)
|
|
52
53
|
|
|
53
54
|
## 运行演示
|
|
54
55
|
|
package/dist/facade.js
CHANGED
|
@@ -288,8 +288,10 @@ export class JeeflowFacade {
|
|
|
288
288
|
}
|
|
289
289
|
// ── 流程设计(需扩展仓储) ───────────────────────────────────────────────
|
|
290
290
|
async designPage(args) {
|
|
291
|
-
const
|
|
292
|
-
|
|
291
|
+
const pageNum = toInt(args.pageNum ?? 1);
|
|
292
|
+
const pageSize = toInt(args.pageSize ?? 10);
|
|
293
|
+
const [rows, total] = await this.ext().pageDesigns(pageNum, pageSize, undefined, parseMQuery(args));
|
|
294
|
+
return pageData(pageNum, pageSize, total, rows.map(r => designRowToMap(r)));
|
|
293
295
|
}
|
|
294
296
|
/** 修改流程设计基本信息(对齐 boot3 ProcessDesignController.update,不写设计稿快照) */
|
|
295
297
|
async designUpdate(args) {
|
|
@@ -571,8 +573,10 @@ export class JeeflowFacade {
|
|
|
571
573
|
// ── 委托代理(需扩展仓储) ───────────────────────────────────────────────
|
|
572
574
|
async surrogatePage(args) {
|
|
573
575
|
const filters = args.operator != null ? { operator: String(args.operator) } : undefined;
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
+
const pageNum = toInt(args.pageNum ?? 1);
|
|
577
|
+
const pageSize = toInt(args.pageSize ?? 10);
|
|
578
|
+
const [rows, total] = await this.ext().pageSurrogates(pageNum, pageSize, filters, parseMQuery(args));
|
|
579
|
+
return pageData(pageNum, pageSize, total, rows);
|
|
576
580
|
}
|
|
577
581
|
async surrogateSave(args) {
|
|
578
582
|
const ext = this.ext();
|
|
@@ -792,7 +796,7 @@ export class JeeflowFacade {
|
|
|
792
796
|
const pageSize = toInt(args.pageSize ?? 10);
|
|
793
797
|
const actorId = String(args.operator ?? 'user1');
|
|
794
798
|
const { rows, total } = await this.repo.pageCcInstances(pageNum, pageSize, actorId, parseMQuery(args));
|
|
795
|
-
return
|
|
799
|
+
return pageData(pageNum, pageSize, total, rows.map(r => ccRowToMap(r)));
|
|
796
800
|
}
|
|
797
801
|
async taskDetail(args) {
|
|
798
802
|
const taskId = toId(args.id);
|
|
@@ -819,7 +823,12 @@ export class JeeflowFacade {
|
|
|
819
823
|
const flow = JSON.parse(toStr(def.content));
|
|
820
824
|
for (const n of flow.nodes ?? []) {
|
|
821
825
|
if (n.id === task.taskName) {
|
|
822
|
-
|
|
826
|
+
// issues/62:taskModel 补 form/ext(节点字段权限,对齐 boot2)
|
|
827
|
+
vo.taskModel = {
|
|
828
|
+
name: n.id, displayName: n.text?.value ?? '', type: n.type,
|
|
829
|
+
form: n.properties?.form ?? null,
|
|
830
|
+
ext: n.properties?.field ?? null,
|
|
831
|
+
};
|
|
823
832
|
break;
|
|
824
833
|
}
|
|
825
834
|
}
|
|
@@ -845,6 +854,8 @@ export class JeeflowFacade {
|
|
|
845
854
|
return rows;
|
|
846
855
|
}
|
|
847
856
|
async candidatePage(args) {
|
|
857
|
+
const pageNum = toInt(args.pageNum ?? 1);
|
|
858
|
+
const pageSize = toInt(args.pageSize ?? 10);
|
|
848
859
|
const taskId = toId(args.processTaskId ?? args.id);
|
|
849
860
|
const task = await this.repo.findTaskById(taskId);
|
|
850
861
|
if (!task)
|
|
@@ -864,13 +875,13 @@ export class JeeflowFacade {
|
|
|
864
875
|
}
|
|
865
876
|
if (candidates.length > 0) {
|
|
866
877
|
const rows = candidates.map(c => ({ userId: c, realName: c }));
|
|
867
|
-
return
|
|
878
|
+
return pageData(pageNum, pageSize, rows.length, rows);
|
|
868
879
|
}
|
|
869
880
|
// 无模型候选 → 用户分页搜索(依赖 userSearch 钩子)
|
|
870
881
|
if (!this.userSearch)
|
|
871
882
|
throw new Error('未配置 userSearch(用户搜索钩子)');
|
|
872
883
|
const [rows, total] = await this.userSearch(args);
|
|
873
|
-
return
|
|
884
|
+
return pageData(pageNum, pageSize, total, rows);
|
|
874
885
|
}
|
|
875
886
|
async nextTaskCandidates(flow, taskName) {
|
|
876
887
|
const result = [];
|
|
@@ -946,7 +957,7 @@ export class JeeflowFacade {
|
|
|
946
957
|
const pageNum = toInt(args.pageNum ?? 1);
|
|
947
958
|
const pageSize = toInt(args.pageSize ?? 10);
|
|
948
959
|
const { rows, total } = await this.repo.pageDefines(pageNum, pageSize, parseMQuery(args));
|
|
949
|
-
return
|
|
960
|
+
return pageData(pageNum, pageSize, total, rows.map(r => defineRowToMap(r)));
|
|
950
961
|
}
|
|
951
962
|
async defineDetail(args) {
|
|
952
963
|
const id = toId(args.id);
|
|
@@ -964,7 +975,7 @@ export class JeeflowFacade {
|
|
|
964
975
|
const pageSize = toInt(args.pageSize ?? 10);
|
|
965
976
|
const operator = String(args.operator ?? 'user1');
|
|
966
977
|
const { rows, total } = await this.repo.pageInstances(pageNum, pageSize, operator, parseMQuery(args));
|
|
967
|
-
return
|
|
978
|
+
return pageData(pageNum, pageSize, total, rows.map(r => instanceRowToMap(r)));
|
|
968
979
|
}
|
|
969
980
|
async instanceDetail(args) {
|
|
970
981
|
const id = toId(args.id);
|
|
@@ -1029,14 +1040,14 @@ export class JeeflowFacade {
|
|
|
1029
1040
|
const pageSize = toInt(args.pageSize ?? 10);
|
|
1030
1041
|
const actorId = String(args.operator ?? 'user1');
|
|
1031
1042
|
const { rows, total } = await this.repo.pageTodoTasks(pageNum, pageSize, actorId, parseMQuery(args));
|
|
1032
|
-
return
|
|
1043
|
+
return pageData(pageNum, pageSize, total, rows.map(r => taskRowToMap(r)));
|
|
1033
1044
|
}
|
|
1034
1045
|
async doneList(args) {
|
|
1035
1046
|
const pageNum = toInt(args.pageNum ?? 1);
|
|
1036
1047
|
const pageSize = toInt(args.pageSize ?? 10);
|
|
1037
1048
|
const operator = String(args.operator ?? 'user1');
|
|
1038
1049
|
const { rows, total } = await this.repo.pageDoneTasks(pageNum, pageSize, operator, parseMQuery(args));
|
|
1039
|
-
return
|
|
1050
|
+
return pageData(pageNum, pageSize, total, rows.map(r => taskRowToMap(r)));
|
|
1040
1051
|
}
|
|
1041
1052
|
/** 定义 content 解析为 LogicFlow JSON(issues/05 jsonObject) */
|
|
1042
1053
|
parseGraph(content) {
|
|
@@ -1090,6 +1101,15 @@ function defineRowToMap(r) {
|
|
|
1090
1101
|
updateTime: fmtTime(r.updateTime), updateUser: r.updateUser,
|
|
1091
1102
|
};
|
|
1092
1103
|
}
|
|
1104
|
+
/** 设计行:时间格式化(issues/63) */
|
|
1105
|
+
function designRowToMap(r) {
|
|
1106
|
+
return {
|
|
1107
|
+
id: r.id, name: r.name, displayName: r.displayName,
|
|
1108
|
+
type: r.type, icon: r.icon, isDeployed: r.isDeployed, remark: r.remark,
|
|
1109
|
+
createTime: fmtTime(r.createTime), createUser: r.createUser,
|
|
1110
|
+
updateTime: fmtTime(r.updateTime), updateUser: r.updateUser,
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1093
1113
|
/** 实例行:ext(实例变量对象)+ displayName/version(定义) */
|
|
1094
1114
|
function instanceRowToMap(r) {
|
|
1095
1115
|
return {
|
|
@@ -1197,3 +1217,12 @@ function toInt(v) {
|
|
|
1197
1217
|
throw new Error('数值缺失或非法');
|
|
1198
1218
|
return n;
|
|
1199
1219
|
}
|
|
1220
|
+
/** issues/64:对齐 mldong 分页五键(Java pageResult / Go pageData) */
|
|
1221
|
+
function pageData(pageNum, pageSize, total, rows) {
|
|
1222
|
+
const pn = pageNum || 1;
|
|
1223
|
+
const ps = pageSize || 10;
|
|
1224
|
+
let totalPage = 0;
|
|
1225
|
+
if (total > 0 && ps > 0)
|
|
1226
|
+
totalPage = Math.ceil(total / ps);
|
|
1227
|
+
return { pageNum: pn, pageSize: ps, recordCount: total, totalPage, rows };
|
|
1228
|
+
}
|
package/dist/jdbc/mysql.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
// MySQL 适配器(mysql2)——连接池 + `?` 占位符(与核心一致,无需转换)。
|
|
2
|
+
//
|
|
3
|
+
// 必须用 query() 而不是 execute():mysql2 execute 走预处理协议,
|
|
4
|
+
// LIMIT ? / OFFSET ? 会失败(Incorrect arguments / LIMIT 被绑成字符串),
|
|
5
|
+
// 分页接口整段变成 facade 99999999(issues/66)。Postgres 适配器本来就走 query()。
|
|
2
6
|
export class MysqlConnection {
|
|
3
7
|
raw;
|
|
4
8
|
constructor(raw) {
|
|
5
9
|
this.raw = raw;
|
|
6
10
|
}
|
|
7
11
|
async execute(sql, args) {
|
|
8
|
-
await this.raw.
|
|
12
|
+
await this.raw.query(sql, args);
|
|
9
13
|
}
|
|
10
14
|
async fetchOne(sql, args) {
|
|
11
|
-
const [rows] = await this.raw.
|
|
15
|
+
const [rows] = await this.raw.query(sql, args);
|
|
12
16
|
return rows[0] ?? null;
|
|
13
17
|
}
|
|
14
18
|
async fetchAll(sql, args) {
|
|
15
|
-
const [rows] = await this.raw.
|
|
19
|
+
const [rows] = await this.raw.query(sql, args);
|
|
16
20
|
return rows;
|
|
17
21
|
}
|
|
18
22
|
async begin() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mldong/jeeflow",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.17",
|
|
4
4
|
"description": "jeeflow workflow engine — Node.js / TypeScript implementation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "tsc",
|
|
21
21
|
"test": "node --import tsx __tests__/spec.test.ts",
|
|
22
|
+
"test-mysql": "node --import tsx --test __tests__/jdbc.test.ts",
|
|
22
23
|
"demo": "node --import tsx demo/main.ts",
|
|
23
24
|
"prepublishOnly": "npm run build"
|
|
24
25
|
},
|