@steedos-labs/plugin-workflow 3.0.40 → 3.0.41
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/designer/dist/amis-renderer/amis-renderer.css +1 -1
- package/designer/dist/amis-renderer/amis-renderer.js +1 -1
- package/designer/dist/assets/index-7cMOmCg4.css +1 -0
- package/designer/dist/assets/{index-DRUi3eGk.js → index-DbYFInYv.js} +164 -164
- package/designer/dist/index.html +2 -2
- package/main/default/applications/approve_workflow.app.yml +3 -160
- package/main/default/applications/desktop.app.yml +21 -0
- package/main/default/client/socket.client.js +2 -5
- package/main/default/manager/handlers_manager.js +5 -2
- package/main/default/objects/instances/buttons/instance_delete.button.yml +7 -1
- package/main/default/objects/instances/buttons/instance_new.button.yml +2 -2
- package/main/default/routes/api_workflow_nav.router.js +1 -0
- package/main/default/test/test_badge_draft.js +12 -26
- package/main/default/test/test_badge_update.js +10 -54
- package/package.json +1 -1
- package/public/amis-renderer/amis-renderer.css +1 -1
- package/public/amis-renderer/amis-renderer.js +1 -1
- package/public/workflow/index.css +0 -276
- package/designer/dist/assets/index-BIbXABqz.css +0 -1
package/designer/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/api/workflow/designer-v2/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>designer</title>
|
|
8
|
-
<script type="module" crossorigin src="/api/workflow/designer-v2/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/api/workflow/designer-v2/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/api/workflow/designer-v2/assets/index-DbYFInYv.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/api/workflow/designer-v2/assets/index-7cMOmCg4.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -23,166 +23,9 @@ nav_schema: {
|
|
|
23
23
|
"ignoreNavSchema": true
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
"type": "
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"body": [
|
|
30
|
-
{
|
|
31
|
-
"type": "button",
|
|
32
|
-
"label": "刷新",
|
|
33
|
-
"className": "instance-nav-reload hidden",
|
|
34
|
-
"onEvent": {
|
|
35
|
-
"click": {
|
|
36
|
-
"actions": [
|
|
37
|
-
{
|
|
38
|
-
"actionType": "reload",
|
|
39
|
-
"componentId": "u:instanceNav"
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"type": "button",
|
|
47
|
-
"label": "刷新树",
|
|
48
|
-
"className": "instance-tree-reload hidden",
|
|
49
|
-
"onEvent": {
|
|
50
|
-
"click": {
|
|
51
|
-
"actions": [
|
|
52
|
-
{
|
|
53
|
-
"actionType": "custom",
|
|
54
|
-
"script": "try{ var opts = window.__latestNavOptions; var data = window.__latestNavData; if(!Array.isArray(opts)){ console.log('[tree-reload] no global options'); return; } opts = JSON.parse(JSON.stringify(opts)); var tree = window.__navTreeComponent; if(!tree || !tree.props || !tree.props.formItem){ console.log('[tree-reload] no saved tree ref, trying amisScoped'); var s = window.amisScoped || (document.querySelector('[data-amisScoped]') && document.querySelector('[data-amisScoped]').__amisScoped); if(s){ tree = s.getComponentById('u:instanceNavTree'); } } if(tree && tree.props && tree.props.formItem){ tree.props.formItem.setOptions(opts, undefined, data || {}); console.log('[tree-reload] setOptions done, count:', opts.length); if(tree.forceUpdate){ tree.forceUpdate(); console.log('[tree-reload] forceUpdate called'); } } else { console.log('[tree-reload] FAIL: cannot find tree component'); } }catch(e){ console.warn('[tree-reload error]', e); }"
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"type": "service",
|
|
62
|
-
"id": "u:instanceNav",
|
|
63
|
-
"className": "bg-white",
|
|
64
|
-
"onEvent": {
|
|
65
|
-
"@data.changed.instances": {
|
|
66
|
-
"actions": [
|
|
67
|
-
{
|
|
68
|
-
"actionType": "reload"
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
|
-
"fetchInited": {
|
|
73
|
-
"actions": [
|
|
74
|
-
{
|
|
75
|
-
"actionType": "custom",
|
|
76
|
-
"script": "try{ var s = event.context && event.context.scoped; if(!s){ var amisScoped = window.amisScoped || (document.querySelector('[data-amisScoped]') && document.querySelector('[data-amisScoped]').__amisScoped); if(amisScoped){ s = amisScoped; } } if(s){ var tree = s.getComponentById('u:instanceNavTree'); if(tree && tree.props && tree.props.formItem){ window.__navTreeComponent = tree; var opts = event.data && event.data.options; if(Array.isArray(opts)){ opts = JSON.parse(JSON.stringify(opts)); tree.props.formItem.setOptions(opts, undefined, event.data); if(tree.forceUpdate){ setTimeout(function(){ tree.forceUpdate(); }, 100); } } } } var _navComp = s && s.getComponentById('u:instanceNav'); if(_navComp && _navComp.props && _navComp.props.store){ window.__instanceNavStore = _navComp.props.store; } if(!window._instanceNavRouteListenerAdded){ window._instanceNavRouteListenerAdded = true; window._wasOnApproveWorkflow = true; window.addEventListener('message', function(evt){ if(!evt.data || !evt.data.type) return; if(evt.data.type === 'ROUTE_CHANGE'){ var isOnApprove = window.location.pathname.indexOf('/app/approve_workflow') === 0; var wasOn = window._wasOnApproveWorkflow; window._wasOnApproveWorkflow = isOnApprove; if(!isOnApprove) return; var isPop = evt.data.navigationType === 'POP'; if(wasOn && !isPop) return; clearTimeout(window._instanceNavReloadTimer); window._instanceNavReloadTimer = setTimeout(function(){ var _val = window.location.pathname + decodeURIComponent(window.location.search); _val = _val.replace(new RegExp('/view/(?!none)[^?#/]+'), '/view/none'); var opts = window.__latestNavOptions; if(opts){ var _fn = function(o,v){ for(var i=0;i<o.length;i++){ if(o[i].value===v) return v; if(o[i].children){ var f=_fn(o[i].children,v); if(f) return f; } } return null; }; var _fl = function(o,sid,sobj){ for(var i=0;i<o.length;i++){ var v=o[i].value; if(v){ var m1=v.match(/side_listview_id=([^&]*)/); var m2=v.match(/side_object=([^&]*)/); if(m1&&m2&&m1[1]===sid&&m2[1]===sobj) return v; } if(o[i].children){ var f=_fl(o[i].children,sid,sobj); if(f) return f; } } return null; }; if(!_fn(opts,_val)){ var lm=_val.match(/side_listview_id=([^&]*)/); var om=_val.match(/side_object=([^&]*)/); if(lm&&om){ var pm=_fl(opts,lm[1],om[1]); if(pm) _val=pm; } } } var store = window.__instanceNavStore; if(store && store.updateData){ store.updateData({ value: _val, _ts: Date.now() }, undefined, false); } var _tree = window.__navTreeComponent; if(_tree && _tree.props && _tree.props.setPrinstineValue){ _tree.props.setPrinstineValue(_val); } }, 300); } }); } }catch(e){ console.warn('[fetchInited error]', e); }"
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
"body": [
|
|
82
|
-
{
|
|
83
|
-
"type": "input-tree",
|
|
84
|
-
"name": "instanceNavTree",
|
|
85
|
-
"treeContainerClassName": "h-full bg-white",
|
|
86
|
-
"className": "instance-box-tree h-full w-full p-0 bg-white",
|
|
87
|
-
"id": "u:instanceNavTree",
|
|
88
|
-
"stacked": true,
|
|
89
|
-
"multiple": false,
|
|
90
|
-
"enableNodePath": false,
|
|
91
|
-
"hideRoot": true,
|
|
92
|
-
"showIcon": true,
|
|
93
|
-
"initiallyOpen": false,
|
|
94
|
-
"virtualThreshold": 100000,
|
|
95
|
-
"value": "${value}",
|
|
96
|
-
"size": "md",
|
|
97
|
-
"onEvent": {
|
|
98
|
-
"change": {
|
|
99
|
-
"actions": [
|
|
100
|
-
{
|
|
101
|
-
"actionType": "setValue",
|
|
102
|
-
"componentId": "instances_list_service",
|
|
103
|
-
"args": {
|
|
104
|
-
"value": {
|
|
105
|
-
"isFlowDataDone": false
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"actionType": "custom",
|
|
111
|
-
"script": "//获取上一次的flowId和categoryId\nconst lastFlowId = event.data.flowId;\nconst lastCategoryId = event.data.categoryId;\n//从value中获取最新的flowId\nvar flowIdRegex = /&flowId=([^&]+)/;\nvar flowIdMatch = event.data.value.match(flowIdRegex);\nconst flowId = flowIdMatch && flowIdMatch.length > 0 ? flowIdMatch[1] : \"\";\n//从value中获取最新的categoryId\nvar categoryIdRegex = /&categoryId=([^&]+)/;\nvar categoryIdMatch = event.data.value.match(categoryIdRegex);\nconst categoryId = categoryIdMatch && categoryIdMatch.length > 0 ? categoryIdMatch[1] : \"\";\n//获取上一次的listname和最新的listname\nconst lastListName = event.data.listName;\nconst listName = event.data.value.split('?')[0].split('instances/grid/')[1];\n//切换流程时清除过滤条件\nif (lastListName == \"monitor\" && listName == \"monitor\" && (flowId != lastFlowId || categoryId != lastCategoryId)) {\n listViewPropsStoreKey = window.location.pathname + \"/crud\";\n sessionStorage.removeItem(listViewPropsStoreKey);\n sessionStorage.removeItem(listViewPropsStoreKey + \"/query\");\n}"
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"actionType": "setValue",
|
|
115
|
-
"componentId": "instances_list_service",
|
|
116
|
-
"args": {
|
|
117
|
-
"value": {
|
|
118
|
-
"additionalFilters": [
|
|
119
|
-
"${event.data.options.name}",
|
|
120
|
-
"=",
|
|
121
|
-
"${event.data.options.value}"
|
|
122
|
-
]
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
"expression": "${event.data.options.level>=10}"
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"args": {
|
|
129
|
-
"link": "${event.data.value}",
|
|
130
|
-
"blank": false
|
|
131
|
-
},
|
|
132
|
-
"actionType": "link"
|
|
133
|
-
}
|
|
134
|
-
]
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
"menuTpl": {
|
|
138
|
-
"type": "wrapper",
|
|
139
|
-
"className": "flex items-center py-1.5 px-3 m-0 rounded-md transition-colors duration-150",
|
|
140
|
-
"body": [
|
|
141
|
-
{
|
|
142
|
-
"type": "tpl",
|
|
143
|
-
"className": "flex-1 leading-6 truncate instance-menu-label",
|
|
144
|
-
"tpl": "${label}",
|
|
145
|
-
"id": "u:9dee51f00db4"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
"type": "tpl",
|
|
149
|
-
"className": "ml-auto",
|
|
150
|
-
"tpl": "",
|
|
151
|
-
"badge": {
|
|
152
|
-
"className": "h-0",
|
|
153
|
-
"offset": [
|
|
154
|
-
-5,
|
|
155
|
-
0
|
|
156
|
-
],
|
|
157
|
-
"mode": "text",
|
|
158
|
-
"text": "${tag | toInt}",
|
|
159
|
-
"overflowCount": 999
|
|
160
|
-
},
|
|
161
|
-
"id": "u:2329cd1fecc2"
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
"id": "u:545154bcc334"
|
|
165
|
-
},
|
|
166
|
-
"unfoldedLevel": 2,
|
|
167
|
-
"source": "${options}"
|
|
168
|
-
}
|
|
169
|
-
],
|
|
170
|
-
"api": {
|
|
171
|
-
"method": "get",
|
|
172
|
-
"url": "${context.rootUrl}/api/${appId}/workflow/nav",
|
|
173
|
-
"headers": {
|
|
174
|
-
"Authorization": "Bearer ${context.tenantId},${context.authToken}"
|
|
175
|
-
},
|
|
176
|
-
"trackExpression": "false",
|
|
177
|
-
"messages": {},
|
|
178
|
-
"adaptor": "var _val = window.location.pathname + decodeURIComponent(window.location.search); _val = _val.replace(new RegExp('/view/(?!none)[^?#/]+'), '/view/none'); console.log('[adaptor] computed value:', _val); function _findNode(opts, val){ for(var i=0;i<opts.length;i++){ if(opts[i].value===val) return opts[i].value; if(opts[i].children){ var f=_findNode(opts[i].children,val); if(f) return f; } } return null; } function _findByListview(opts, sid, sobj){ for(var i=0;i<opts.length;i++){ var v=opts[i].value; if(v){ var m1=v.match(/side_listview_id=([^&]*)/); var m2=v.match(/side_object=([^&]*)/); if(m1&&m2&&m1[1]===sid&&m2[1]===sobj){ return v; } } if(opts[i].children){ var f=_findByListview(opts[i].children,sid,sobj); if(f) return f; } } return null; } if(payload.data.options){ var exactMatch=_findNode(payload.data.options, _val); if(!exactMatch){ console.log('[adaptor] no exact match, trying partial match'); var lm=_val.match(/side_listview_id=([^&]*)/); var om=_val.match(/side_object=([^&]*)/); if(lm&&om){ var partialMatch=_findByListview(payload.data.options, lm[1], om[1]); if(partialMatch){ console.log('[adaptor] partial match found:', partialMatch); _val=partialMatch; } else { console.log('[adaptor] no partial match either, listview='+lm[1]+' object='+om[1]); } } } else { console.log('[adaptor] exact match found'); } } payload.data.value = _val; payload.data._ts = Date.now(); if(payload.data.options){ payload.data.options = JSON.parse(JSON.stringify(payload.data.options)); window.__latestNavOptions = payload.data.options; window.__latestNavData = payload.data; console.log('[adaptor] saved options to global, count:', payload.data.options.length); } return payload;"
|
|
179
|
-
},
|
|
180
|
-
"messages": {},
|
|
181
|
-
"dsType": "api"
|
|
182
|
-
}
|
|
183
|
-
],
|
|
184
|
-
"isFixedHeight": false,
|
|
185
|
-
"isFixedWidth": false
|
|
26
|
+
"type": "approval-tree-menu",
|
|
27
|
+
"apiUrl": "/api/approve_workflow/workflow/nav",
|
|
28
|
+
"navigateMode": "router"
|
|
186
29
|
}
|
|
187
30
|
],
|
|
188
31
|
"isFixedHeight": false,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
code: desktop
|
|
2
|
+
enable_nav_schema: true
|
|
3
|
+
nav_schema: {
|
|
4
|
+
"type": "wrapper",
|
|
5
|
+
"size": "none",
|
|
6
|
+
"body": [
|
|
7
|
+
{
|
|
8
|
+
"type": "steedos-app-menu",
|
|
9
|
+
"stacked": true,
|
|
10
|
+
"appId": "approve_workflow",
|
|
11
|
+
"ignoreNavSchema": true
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "approval-tree-menu",
|
|
15
|
+
"apiUrl": "/api/approve_workflow/workflow/nav",
|
|
16
|
+
"navigateMode": "router"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"isFixedHeight": false,
|
|
20
|
+
"isFixedWidth": false
|
|
21
|
+
}
|
|
@@ -45,11 +45,7 @@ window.waitForThing(window, 'socket').then(()=>{
|
|
|
45
45
|
};
|
|
46
46
|
if (isFirstRun === false && shouldReloadView()) {
|
|
47
47
|
window.$(".list-view-btn-reload").click()
|
|
48
|
-
|
|
49
|
-
clearTimeout(window.__navRetryTimer)
|
|
50
|
-
window.__navReloadTimer = setTimeout(function(){ window.$(".instance-nav-reload").click() }, 500)
|
|
51
|
-
// Retry: reload tree only (no API request) to pick up data already in Service store
|
|
52
|
-
window.__navRetryTimer = setTimeout(function(){ window.$(".instance-tree-reload").click() }, 2000)
|
|
48
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*")
|
|
53
49
|
}
|
|
54
50
|
isFirstRun = false;
|
|
55
51
|
});
|
|
@@ -62,6 +58,7 @@ window.waitForThing(window, 'socket').then(()=>{
|
|
|
62
58
|
};
|
|
63
59
|
if (shouldReloadView()) {
|
|
64
60
|
window.$(".list-view-btn-reload").click()
|
|
61
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*")
|
|
65
62
|
}
|
|
66
63
|
});
|
|
67
64
|
|
|
@@ -159,7 +159,11 @@ getHandlersManager.getHandlers = async function (instance_id, step_id, login_use
|
|
|
159
159
|
|
|
160
160
|
// 拟稿时, 可以设定后续每个步骤的处理人 #1926
|
|
161
161
|
if (instance.step_approve && !_.isEmpty(instance.step_approve[`${step_id}_options`])) {
|
|
162
|
-
|
|
162
|
+
const res = instance.step_approve[`${step_id}_options`];
|
|
163
|
+
|
|
164
|
+
if(res != null && res.length > 0 && res[0] != null){
|
|
165
|
+
return res;
|
|
166
|
+
}
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
let approve_users = [];
|
|
@@ -195,7 +199,6 @@ getHandlersManager.getHandlers = async function (instance_id, step_id, login_use
|
|
|
195
199
|
current_step = _.find(current_steps, function (step) {
|
|
196
200
|
return step._id === step_id;
|
|
197
201
|
});
|
|
198
|
-
|
|
199
202
|
if (current_step.step_type === "condition") {
|
|
200
203
|
const unfinished_trace = _.find(instance.traces, function (trace) {
|
|
201
204
|
return trace.is_finished === false;
|
|
@@ -29,13 +29,19 @@ amis_schema: |-
|
|
|
29
29
|
"actionType": "custom",
|
|
30
30
|
"script": "SteedosWorkflow.Instance.changed=false; navigate('/app/approve_workflow/instances/view/none?side_object=instances&side_listview_id=draft&additionalFilters=&flowId=&categoryId=')"
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
"actionType": "wait",
|
|
34
|
+
"args": {
|
|
35
|
+
"time": 500
|
|
36
|
+
}
|
|
37
|
+
},
|
|
32
38
|
{
|
|
33
39
|
"actionType": "custom",
|
|
34
40
|
"script":"window.$('.list-view-btn-reload').click()"
|
|
35
41
|
},
|
|
36
42
|
{
|
|
37
43
|
"actionType": "custom",
|
|
38
|
-
"script":"window
|
|
44
|
+
"script":"window.postMessage({ type: 'approval-tree-menu:reload' }, '*')"
|
|
39
45
|
}
|
|
40
46
|
],
|
|
41
47
|
"weight": 0
|
|
@@ -68,7 +68,7 @@ amis_schema: |-
|
|
|
68
68
|
{
|
|
69
69
|
"actionType": "wait",
|
|
70
70
|
"args": {
|
|
71
|
-
"time":
|
|
71
|
+
"time": 500
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
{
|
|
@@ -77,7 +77,7 @@ amis_schema: |-
|
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"actionType": "custom",
|
|
80
|
-
"script":"window
|
|
80
|
+
"script":"window.postMessage({ type: 'approval-tree-menu:reload' }, '*')"
|
|
81
81
|
}
|
|
82
82
|
]
|
|
83
83
|
}
|
|
@@ -291,6 +291,7 @@ router.get('/api/:appId/workflow/nav', requireAuthentication, async function (re
|
|
|
291
291
|
"label": t('inbox', {}, userSession.language),
|
|
292
292
|
"icon": "fa fa-download",
|
|
293
293
|
"tag":inboxResult.count,
|
|
294
|
+
"unfolded": true,
|
|
294
295
|
"options":{
|
|
295
296
|
"level":1,
|
|
296
297
|
"to": `/app/${appId}/instance_tasks/view/none?side_object=instance_tasks&side_listview_id=inbox&additionalFilters=`
|
|
@@ -12,11 +12,9 @@
|
|
|
12
12
|
const origLog = console.log;
|
|
13
13
|
|
|
14
14
|
// ---- 前置检查 ----
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!navBtn || !treeBtn || !treeEl) {
|
|
19
|
-
console.error('缺少必要 DOM 元素'); return;
|
|
15
|
+
const menuEl = document.querySelector('.approval-tree-menu');
|
|
16
|
+
if (!menuEl) {
|
|
17
|
+
console.error('❌ 未找到 .approval-tree-menu 组件'); return;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
let baseDraft = null;
|
|
@@ -92,26 +90,16 @@
|
|
|
92
90
|
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
93
91
|
|
|
94
92
|
function getAllBadges() {
|
|
95
|
-
|
|
96
|
-
for (var s of sels) { var e = treeEl.querySelectorAll(s); if (e.length) return e; }
|
|
97
|
-
return [];
|
|
93
|
+
return menuEl.querySelectorAll('.ant-badge-count');
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
function findBadgeByLabel(label) {
|
|
101
|
-
|
|
102
|
-
for (
|
|
103
|
-
|
|
104
|
-
var badge = item.querySelector('[class*="Badge-text"]');
|
|
105
|
-
if (badge) return parseInt(badge.textContent.trim(), 10);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// fallback: 搜索所有tree item
|
|
109
|
-
var allItems = treeEl.querySelectorAll('.cxd-Tree-item, .antd-Tree-item');
|
|
110
|
-
for (var ai of allItems) {
|
|
111
|
-
var labelEl = ai.querySelector('.instance-menu-label');
|
|
97
|
+
const nodes = menuEl.querySelectorAll('.ant-tree-treenode');
|
|
98
|
+
for (const node of nodes) {
|
|
99
|
+
const labelEl = node.querySelector('.approval-tree-menu__label');
|
|
112
100
|
if (labelEl && labelEl.textContent.includes(label)) {
|
|
113
|
-
|
|
114
|
-
if (
|
|
101
|
+
const badge = node.querySelector('.ant-badge-count');
|
|
102
|
+
if (badge) return parseInt(badge.textContent.trim(), 10);
|
|
115
103
|
}
|
|
116
104
|
}
|
|
117
105
|
return null;
|
|
@@ -120,7 +108,7 @@
|
|
|
120
108
|
// ---- 初始化 ----
|
|
121
109
|
origLog.call(console, '%c=== Draft 角标测试 ===', 'color:blue;font-size:14px;font-weight:bold');
|
|
122
110
|
round = 0;
|
|
123
|
-
|
|
111
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*");
|
|
124
112
|
await sleep(4000);
|
|
125
113
|
|
|
126
114
|
if (baseDraft === null) {
|
|
@@ -137,10 +125,8 @@
|
|
|
137
125
|
var expDraft = baseDraft + i;
|
|
138
126
|
origLog.call(console, '--- 第' + i + '轮: 期望 inbox=' + expInbox + ', draft=' + expDraft);
|
|
139
127
|
|
|
140
|
-
|
|
141
|
-
await sleep(
|
|
142
|
-
treeBtn.click();
|
|
143
|
-
await sleep(1500);
|
|
128
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*");
|
|
129
|
+
await sleep(3000);
|
|
144
130
|
|
|
145
131
|
var domInbox = getAllBadges()[0] ? parseInt(getAllBadges()[0].textContent.trim(), 10) : null;
|
|
146
132
|
var domDraft = findBadgeByLabel('草稿') || findBadgeByLabel('Draft') || findBadgeByLabel('draft');
|
|
@@ -25,14 +25,10 @@
|
|
|
25
25
|
console.log('');
|
|
26
26
|
|
|
27
27
|
// 检查前置条件
|
|
28
|
-
const
|
|
29
|
-
const treeReloadBtn = document.querySelector('.instance-tree-reload');
|
|
30
|
-
const treeEl = document.querySelector('.instance-box-tree');
|
|
28
|
+
const menuEl = document.querySelector('.approval-tree-menu');
|
|
31
29
|
|
|
32
|
-
if (!
|
|
33
|
-
|
|
34
|
-
if (!treeEl) { console.error('❌ 未找到 .instance-box-tree 树组件'); return; }
|
|
35
|
-
console.log('✅ 前置条件检查通过: nav-reload, tree-reload, tree DOM 均存在');
|
|
30
|
+
if (!menuEl) { console.error('❌ 未找到 .approval-tree-menu 组件'); return; }
|
|
31
|
+
console.log('✅ 前置条件检查通过: .approval-tree-menu 组件存在');
|
|
36
32
|
|
|
37
33
|
// 状态
|
|
38
34
|
let roundCounter = 0;
|
|
@@ -42,16 +38,9 @@
|
|
|
42
38
|
let apiCallCount = 0;
|
|
43
39
|
let fetchInitedCount = 0;
|
|
44
40
|
|
|
45
|
-
//
|
|
41
|
+
// ---- 监听日志 ----
|
|
46
42
|
const origConsoleLog = console.log;
|
|
47
43
|
const fetchInitedLogs = [];
|
|
48
|
-
console.log = function() {
|
|
49
|
-
if (arguments[0] && typeof arguments[0] === 'string' && arguments[0].includes('[fetchInited]')) {
|
|
50
|
-
fetchInitedCount++;
|
|
51
|
-
fetchInitedLogs.push(Array.from(arguments).join(' '));
|
|
52
|
-
}
|
|
53
|
-
return origConsoleLog.apply(console, arguments);
|
|
54
|
-
};
|
|
55
44
|
|
|
56
45
|
// ======== 篡改 options 的通用函数 ========
|
|
57
46
|
function tamperOptions(json, source) {
|
|
@@ -170,12 +159,7 @@
|
|
|
170
159
|
|
|
171
160
|
// ======== DOM 读取 ========
|
|
172
161
|
function findBadgeElements() {
|
|
173
|
-
|
|
174
|
-
for (const sel of selectors) {
|
|
175
|
-
const els = treeEl.querySelectorAll(sel);
|
|
176
|
-
if (els.length > 0) return els;
|
|
177
|
-
}
|
|
178
|
-
return [];
|
|
162
|
+
return menuEl.querySelectorAll('.ant-badge-count');
|
|
179
163
|
}
|
|
180
164
|
|
|
181
165
|
function getInboxBadgeFromDOM() {
|
|
@@ -196,10 +180,8 @@
|
|
|
196
180
|
// 初始化:获取基准值(模拟完整 socket 流程:nav reload + tree reload)
|
|
197
181
|
origConsoleLog.call(console, '%c[初始化] 获取基准角标值...', 'color: orange;');
|
|
198
182
|
roundCounter = 0;
|
|
199
|
-
|
|
200
|
-
await sleep(
|
|
201
|
-
treeReloadBtn.click();
|
|
202
|
-
await sleep(2000);
|
|
183
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*");
|
|
184
|
+
await sleep(4000);
|
|
203
185
|
const initDom = getInboxBadgeFromDOM();
|
|
204
186
|
origConsoleLog.call(console, `%c[初始化] 基准值: API=${baseInboxTag}, DOM=${initDom}, fetchInited=${fetchInitedCount}次`, 'color: orange;');
|
|
205
187
|
|
|
@@ -208,7 +190,6 @@
|
|
|
208
190
|
window.fetch = originalFetch;
|
|
209
191
|
XHR.open = origXHROpen;
|
|
210
192
|
XHR.send = origXHRSend;
|
|
211
|
-
console.log = origConsoleLog;
|
|
212
193
|
return;
|
|
213
194
|
}
|
|
214
195
|
origConsoleLog.call(console, '');
|
|
@@ -224,14 +205,9 @@
|
|
|
224
205
|
origConsoleLog.call(console, `%c[第 ${round}/${TOTAL_ROUNDS} 轮]`, 'color: #888; font-weight: bold;',
|
|
225
206
|
`期望角标: ${baseInboxTag} + ${round} = ${expectedInboxTag}`);
|
|
226
207
|
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
await sleep(1500); // 等待 API 返回 + fetchInited 事件处理
|
|
231
|
-
|
|
232
|
-
// 2. Tree reload(从 Service 数据域读取 options)
|
|
233
|
-
treeReloadBtn.click();
|
|
234
|
-
await sleep(1500); // 等待 Tree reloadOptions 完成
|
|
208
|
+
// 触发刷新
|
|
209
|
+
window.postMessage({ type: "approval-tree-menu:reload" }, "*");
|
|
210
|
+
await sleep(3000); // 等待 API 返回 + React 重新渲染
|
|
235
211
|
|
|
236
212
|
// 3. 读取结果
|
|
237
213
|
const apiCalls = apiCallCount - apiCountBefore;
|
|
@@ -270,25 +246,6 @@
|
|
|
270
246
|
origConsoleLog.call(console, ' API篡改后值:', actualApiInboxTag);
|
|
271
247
|
origConsoleLog.call(console, ' DOM当前值:', domValue);
|
|
272
248
|
origConsoleLog.call(console, ' DOM全部角标:', Array.from(findBadgeElements()).map(el => el.textContent.trim()));
|
|
273
|
-
// 检查 tree-reload 增强是否生效
|
|
274
|
-
origConsoleLog.call(console, ' 检查 tree-reload 增强...');
|
|
275
|
-
try {
|
|
276
|
-
var s = window.amisScoped || (document.querySelector('[data-amisScoped]') && document.querySelector('[data-amisScoped]').__amisScoped);
|
|
277
|
-
if (s) {
|
|
278
|
-
var svc = s.getComponentById('u:instanceNav');
|
|
279
|
-
var tr = s.getComponentById('u:instanceNavTree');
|
|
280
|
-
origConsoleLog.call(console, ' Service组件:', svc ? '存在' : '不存在');
|
|
281
|
-
origConsoleLog.call(console, ' Tree组件:', tr ? '存在' : '不存在');
|
|
282
|
-
if (svc && svc.props && svc.props.data) {
|
|
283
|
-
var svcOpts = svc.props.data.options;
|
|
284
|
-
origConsoleLog.call(console, ' Service.data.options[0].tag:', svcOpts && svcOpts[0] ? svcOpts[0].tag : 'N/A');
|
|
285
|
-
}
|
|
286
|
-
if (tr && tr.props && tr.props.formItem) {
|
|
287
|
-
var treeOpts = tr.props.formItem.getOptions ? tr.props.formItem.getOptions() : (tr.props.options || []);
|
|
288
|
-
origConsoleLog.call(console, ' Tree.options[0].tag:', treeOpts && treeOpts[0] ? treeOpts[0].tag : 'N/A');
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
} catch(e) { origConsoleLog.call(console, ' 诊断出错:', e); }
|
|
292
249
|
stopped = true;
|
|
293
250
|
break;
|
|
294
251
|
}
|
|
@@ -302,7 +259,6 @@
|
|
|
302
259
|
window.fetch = originalFetch;
|
|
303
260
|
XHR.open = origXHROpen;
|
|
304
261
|
XHR.send = origXHRSend;
|
|
305
|
-
console.log = origConsoleLog;
|
|
306
262
|
|
|
307
263
|
// 报告
|
|
308
264
|
const passed = results.filter(r => r.pass).length;
|