Your Name 3425adbc20 flow
2025-10-29 10:00:07 +08:00

1332 lines
63 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[
{
"id": "0ac020c7380665e7",
"type": "tab",
"label": "测试流程",
"disabled": false,
"info": "",
"env": []
},
{
"id": "78d15f59dee4b6d8",
"type": "tab",
"label": "流程 2",
"disabled": false,
"info": "",
"env": []
},
{
"id": "8aaa24cf39b5742a",
"type": "http proxy",
"name": "https",
"url": "https://10.22.98.21:8080",
"noproxy": []
},
{
"id": "97353ed49f690c0b",
"type": "http proxy",
"name": "http",
"url": "http://10.22.98.21:8080",
"noproxy": []
},
{
"id": "be9c605d4cdaa297",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "创建井",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1030,
"y": 560,
"wires": [
[
"6f07c9e60472a814",
"2220f90bcc99b3a4",
"df389955c2ae3156"
]
]
},
{
"id": "96fbb1fa63a1cb8b",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "创建",
"props": [
{
"p": "payload"
},
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"version\":\"1.0.0\",\"act\":-1,\"data\":[{\"dsid\":\"testid2\",\"wellId\":\"WELL-zzlhTEST-002\",\"wellCommonName\":\"zzlh测试用井名\",\"wellLegalName\":\"zzlh-test-01\",\"wellPurpose\":\"开发井\",\"wellType\":\"直井\",\"dataRegion\":\"ZZLH\",\"projectId\":\"PROJ-ZZLH-001\",\"projectName\":\"zzlh测试地质单元\",\"orgId\":\"ORG-ZZLH-01\",\"orgName\":\"zzlh采油厂\",\"bsflag\":1,\"wellState\":\"生产中\",\"spudDate\":\"2024-01-15\",\"completionDate\":\"2024-05-20\",\"prodDate\":\"2024-06-01\",\"egl\":145.5,\"kbd\":5.2,\"kb\":150.7,\"actualXAxis\":550123.45,\"actualYAxis\":4998765.32,\"coordinateSystemName\":\"zzlh测试坐标系\",\"geoDescription\":\"位于zzlh测试区域\",\"remarks\":\"这是一口用于系统测试的生产井。\",\"createUserId\":\"testuser001\",\"createDate\":\"2025-09-12T10:00:00Z\",\"updateUserId\":\"testuser001\",\"updateDate\":\"2025-09-12T10:00:00Z\"}]}",
"payloadType": "json",
"x": 850,
"y": 400,
"wires": [
[
"013f3a0718a44e18"
]
]
},
{
"id": "6f07c9e60472a814",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "创建结果",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1180,
"y": 440,
"wires": []
},
{
"id": "1b18d7419c63f2b5",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "查询详情",
"props": [
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
},
{
"p": "url",
"v": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0/testid2",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 160,
"y": 220,
"wires": [
[
"70a49687f823bf4e"
]
]
},
{
"id": "88cf35d496381288",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "查询",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 470,
"y": 220,
"wires": []
},
{
"id": "70a49687f823bf4e",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "查询井详情",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "basic",
"senderr": false,
"headers": [],
"x": 330,
"y": 240,
"wires": [
[
"88cf35d496381288"
]
]
},
{
"id": "ae5c8d27d69b77ed",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "更新井",
"method": "PUT",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 270,
"y": 340,
"wires": [
[
"2b37a50f557b48ff"
]
]
},
{
"id": "7f1ff1fda219baaa",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "更新",
"props": [
{
"p": "payload"
},
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"version\":\"1.0.0\",\"act\":-1,\"data\":[{\"dsid\":\"testid2\",\"wellId\":\"WELL-zzlhTEST-002\",\"wellCommonName\":\"zzlh测试用井名\",\"wellLegalName\":\"zzlh-test-01\",\"wellPurpose\":\"开发井---更新16\",\"wellType\":\"直井\",\"dataRegion\":\"ZZLH\",\"projectId\":\"PROJ-ZZLH-001\",\"projectName\":\"zzlh测试地质单元\",\"orgId\":\"ORG-ZZLH-01\",\"orgName\":\"zzlh采油厂\",\"bsflag\":1,\"wellState\":\"生产中\",\"spudDate\":\"2024-01-15\",\"completionDate\":\"2024-05-20\",\"prodDate\":\"2024-06-01\",\"egl\":145.5,\"kbd\":5.2,\"kb\":150.7,\"actualXAxis\":550123.45,\"actualYAxis\":4998765.32,\"coordinateSystemName\":\"zzlh测试坐标系\",\"geoDescription\":\"位于zzlh测试区域\",\"remarks\":\"这是一口用于系统测试的生产井。\",\"createUserId\":\"testuser001\",\"createDate\":\"2025-09-12T10:00:00Z\",\"updateUserId\":\"testuser001\",\"updateDate\":\"2025-09-12T10:00:00Z\"}]}",
"payloadType": "json",
"x": 110,
"y": 280,
"wires": [
[
"ae5c8d27d69b77ed"
]
]
},
{
"id": "2b37a50f557b48ff",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "更新结果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 460,
"y": 340,
"wires": []
},
{
"id": "c3514fbf44147aed",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "删除",
"props": [
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
},
{
"p": "url",
"v": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"vt": "str"
},
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"version\":\"1.0.0\",\"data\":[\"testid2\"]}",
"payloadType": "json",
"x": 90,
"y": 380,
"wires": [
[
"0d437a2a77570c57"
]
]
},
{
"id": "647fd9a7f8fc214c",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "删除结果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 500,
"y": 420,
"wires": []
},
{
"id": "0d437a2a77570c57",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "删除井",
"method": "DELETE",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 230,
"y": 420,
"wires": [
[
"647fd9a7f8fc214c"
]
]
},
{
"id": "044945e983586ce5",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "查询列表",
"props": [
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
},
{
"p": "url",
"v": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0",
"vt": "str"
},
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{}",
"payloadType": "json",
"x": 120,
"y": 480,
"wires": [
[
"5921574867140eb3"
]
]
},
{
"id": "286d3b129ca1b756",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "查询",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 490,
"y": 480,
"wires": []
},
{
"id": "5921574867140eb3",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "查询井列表",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 290,
"y": 500,
"wires": [
[
"286d3b129ca1b756",
"819906f13bb83e88"
]
]
},
{
"id": "819906f13bb83e88",
"type": "function",
"z": "0ac020c7380665e7",
"name": "function 1",
"func": "try {\n \n const payload = JSON.parse(msg.payload);\n if (payload && payload.data && Array.isArray(payload.data.list)) {\n msg.isEmpty = payload.data.list.length === 0;\n } else {\n msg.isEmpty = false; \n }\n} catch (e) {\n \n \n msg.isEmpty = false\n}\n\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 300,
"y": 600,
"wires": [
[
"7b828761c4ae4f35"
]
]
},
{
"id": "7b828761c4ae4f35",
"type": "switch",
"z": "0ac020c7380665e7",
"name": "",
"property": "isEmpty",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "true",
"vt": "jsonata"
},
{
"t": "neq",
"v": "true",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 470,
"y": 580,
"wires": [
[
"e308201b5e361b2e",
"013f3a0718a44e18"
],
[
"5712828285fd7a38"
]
]
},
{
"id": "5712828285fd7a38",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "\"初始不为空,错误\"",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 490,
"y": 680,
"wires": []
},
{
"id": "e308201b5e361b2e",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 2",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "\"初始为空,正确\"",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 690,
"y": 640,
"wires": []
},
{
"id": "013f3a0718a44e18",
"type": "change",
"z": "0ac020c7380665e7",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"version\":\"1.0.0\",\"act\":-1,\"data\":[{\"dsid\":\"testid2\",\"wellId\":\"WELL-zzlhTEST-002\",\"wellCommonName\":\"zzlh测试用井名\",\"wellLegalName\":\"zzlh-test-01\",\"wellPurpose\":\"开发井\",\"wellType\":\"直井\",\"dataRegion\":\"ZZLH\",\"projectId\":\"PROJ-ZZLH-001\",\"projectName\":\"zzlh测试地质单元\",\"orgId\":\"ORG-ZZLH-01\",\"orgName\":\"zzlh采油厂\",\"bsflag\":1,\"wellState\":\"生产中\",\"spudDate\":\"2024-01-15\",\"completionDate\":\"2024-05-20\",\"prodDate\":\"2024-06-01\",\"egl\":145.5,\"kbd\":5.2,\"kb\":150.7,\"actualXAxis\":550123.45,\"actualYAxis\":4998765.32,\"coordinateSystemName\":\"zzlh测试坐标系\",\"geoDescription\":\"位于zzlh测试区域\",\"remarks\":\"这是一口用于系统测试的生产井。\",\"createUserId\":\"testuser001\",\"createDate\":\"2025-09-12T10:00:00Z\",\"updateUserId\":\"testuser001\",\"updateDate\":\"2025-09-12T10:00:00Z\"}]}",
"tot": "json"
},
{
"t": "set",
"p": "headers",
"pt": "msg",
"to": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"tot": "json"
},
{
"t": "set",
"p": "rejectUnauthorized",
"pt": "msg",
"to": "false",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 560,
"wires": [
[
"be9c605d4cdaa297"
]
]
},
{
"id": "8f574d489345a331",
"type": "switch",
"z": "0ac020c7380665e7",
"name": "",
"property": "isCreated",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "true",
"vt": "jsonata"
},
{
"t": "eq",
"v": "false",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 1330,
"y": 620,
"wires": [
[
"23f668f265c1db5c",
"8f280fa3aac33505"
],
[
"4fd140a8f2df7e53"
]
]
},
{
"id": "2220f90bcc99b3a4",
"type": "function",
"z": "0ac020c7380665e7",
"name": "function 2",
"func": "try {\n const payloadObject = JSON.parse(msg.payload);\n msg.isCreated = (payloadObject.code === 0);\n\n} catch (e) {\n msg.isCreated = false;\n}\n\n// 返回更新后的 msg 对象\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1160,
"y": 620,
"wires": [
[
"8f574d489345a331"
]
]
},
{
"id": "23f668f265c1db5c",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 3",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "\"创建成功\"",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 1390,
"y": 460,
"wires": []
},
{
"id": "4fd140a8f2df7e53",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 4",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "创建失败",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 1410,
"y": 740,
"wires": []
},
{
"id": "df389955c2ae3156",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 6",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "msg",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 1000,
"y": 680,
"wires": []
},
{
"id": "39c28a10430cce71",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 5",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 800,
"y": 740,
"wires": []
},
{
"id": "551a78c76ae2bccf",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "删除井",
"method": "DELETE",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1770,
"y": 660,
"wires": [
[
"99f3d98419231d12",
"e3cc68ad6021510f"
]
]
},
{
"id": "99f3d98419231d12",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "删除结果",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1960,
"y": 540,
"wires": []
},
{
"id": "7d94b96bcc85d684",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "删除",
"props": [
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
},
{
"p": "url",
"v": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"vt": "str"
},
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"version\":\"1.0.0\",\"data\":[\"testid2\"]}",
"payloadType": "json",
"x": 1710,
"y": 480,
"wires": [
[
"551a78c76ae2bccf"
]
]
},
{
"id": "8f280fa3aac33505",
"type": "change",
"z": "0ac020c7380665e7",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"version\":\"1.0.0\",\"data\":[\"testid2\"]}",
"tot": "json"
},
{
"t": "set",
"p": "headers",
"pt": "msg",
"to": "{\"Content-Type\":\"application/json\",\"Authorization\":\"1\",\"Dataregion\":\"ZZLH\"}",
"tot": "json"
},
{
"t": "set",
"p": "rejectUnauthorized",
"pt": "msg",
"to": "false",
"tot": "str"
},
{
"t": "set",
"p": "url",
"pt": "msg",
"to": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1580,
"y": 620,
"wires": [
[
"551a78c76ae2bccf"
]
]
},
{
"id": "6585c529e8732137",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 7",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "\"删除成功\"",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 2170,
"y": 540,
"wires": []
},
{
"id": "3b9a9af3fb68645f",
"type": "switch",
"z": "0ac020c7380665e7",
"name": "",
"property": "isDeleted",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "true",
"vt": "jsonata"
},
{
"t": "eq",
"v": "false",
"vt": "jsonata"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 2110,
"y": 700,
"wires": [
[
"6585c529e8732137",
"cfbf5ff4275a974e"
],
[
"f80987279214f312"
]
]
},
{
"id": "f80987279214f312",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 8",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "删除失败",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 2190,
"y": 820,
"wires": []
},
{
"id": "e3cc68ad6021510f",
"type": "function",
"z": "0ac020c7380665e7",
"name": "function 3",
"func": "try {\n const payloadObject = JSON.parse(msg.payload);\n msg.isDeleted = (payloadObject.code === 0);\n\n} catch (e) {\n msg.isDeleted = false;\n}\n\n// 返回更新后的 msg 对象\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1920,
"y": 700,
"wires": [
[
"3b9a9af3fb68645f",
"f92150ebdd4ca3ff"
]
]
},
{
"id": "f92150ebdd4ca3ff",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "debug 9",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "msg",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 2000,
"y": 760,
"wires": []
},
{
"id": "c281f9583e262827",
"type": "function",
"z": "0ac020c7380665e7",
"name": "function 4",
"func": "msg.headers = { \"Content-Type\": \"application/json\", \"Authorization\": \"1\", \"Dataregion\": \"ZZLH\" }\nmsg.body={}\nmsg.rejectUnauthorized=false\nmsg.url = \"https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0\"\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 100,
"y": 580,
"wires": [
[
"5921574867140eb3"
]
]
},
{
"id": "ea8a01974cede86a",
"type": "http in",
"z": "0ac020c7380665e7",
"name": "",
"url": "/test",
"method": "get",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 80,
"y": 660,
"wires": [
[
"c281f9583e262827"
]
]
},
{
"id": "fdf4a7a6166cf05c",
"type": "http response",
"z": "0ac020c7380665e7",
"name": "",
"statusCode": "",
"headers": {},
"x": 2370,
"y": 700,
"wires": []
},
{
"id": "cfbf5ff4275a974e",
"type": "function",
"z": "0ac020c7380665e7",
"name": "function 5",
"func": "msg.payload = { \"code\": 0, \"message\": \"井创建删除流程测试成功\",}\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 2260,
"y": 640,
"wires": [
[
"fdf4a7a6166cf05c"
]
]
},
{
"id": "ac556871dae3b9ea",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "查询列表",
"props": [
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
},
{
"p": "url",
"v": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0",
"vt": "str"
},
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{}",
"payloadType": "json",
"x": 280,
"y": 100,
"wires": [
[
"ee3b0307d3ddb476"
]
]
},
{
"id": "c69cfc2d862f1fe4",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "查询",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 650,
"y": 100,
"wires": []
},
{
"id": "ee3b0307d3ddb476",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "查询井列表",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 450,
"y": 120,
"wires": [
[
"c69cfc2d862f1fe4"
]
]
},
{
"id": "d50ee4d6f62682dd",
"type": "inject",
"z": "0ac020c7380665e7",
"name": "创建",
"props": [
{
"p": "payload"
},
{
"p": "headers",
"v": "{\"Content-Type\":\"application/json\",\"Dataregion\":\"ZZLH\"}",
"vt": "json"
},
{
"p": "rejectUnauthorized",
"v": "false",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"version\":\"1.0.0\",\"act\":-1,\"data\":[{\"dsid\":\"testid2\",\"wellId\":\"WELL-zzlhTEST-002\",\"wellCommonName\":\"zzlh测试用井名\",\"wellLegalName\":\"zzlh-test-01\",\"wellPurpose\":\"开发井\",\"wellType\":\"直井\",\"dataRegion\":\"ZZLH\",\"projectId\":\"PROJ-ZZLH-001\",\"projectName\":\"zzlh测试地质单元\",\"orgId\":\"ORG-ZZLH-01\",\"orgName\":\"zzlh采油厂\",\"bsflag\":1,\"wellState\":\"生产中\",\"spudDate\":\"2024-01-15\",\"completionDate\":\"2024-05-20\",\"prodDate\":\"2024-06-01\",\"egl\":145.5,\"kbd\":5.2,\"kb\":150.7,\"actualXAxis\":550123.45,\"actualYAxis\":4998765.32,\"coordinateSystemName\":\"zzlh测试坐标系\",\"geoDescription\":\"位于zzlh测试区域\",\"remarks\":\"这是一口用于系统测试的生产井。\",\"createUserId\":\"testuser001\",\"createDate\":\"2025-09-12T10:00:00Z\",\"updateUserId\":\"testuser001\",\"updateDate\":\"2025-09-12T10:00:00Z\"}]}",
"payloadType": "json",
"x": 850,
"y": 160,
"wires": [
[
"61b9d6e67e3f48f6"
]
]
},
{
"id": "61b9d6e67e3f48f6",
"type": "http request",
"z": "0ac020c7380665e7",
"name": "创建井",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 990,
"y": 100,
"wires": [
[
"9821ae3eea5804dc"
]
]
},
{
"id": "9821ae3eea5804dc",
"type": "debug",
"z": "0ac020c7380665e7",
"name": "创建结果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1080,
"y": 220,
"wires": []
},
{
"id": "fd3672b8ebb314ee",
"type": "http in",
"z": "78d15f59dee4b6d8",
"name": "单接口测试",
"url": "/single_test",
"method": "post",
"upload": false,
"skipBodyParsing": false,
"swaggerDoc": "",
"x": 120,
"y": 140,
"wires": [
[
"f414ed448fcf544b"
]
]
},
{
"id": "d666851b16cf6482",
"type": "http response",
"z": "78d15f59dee4b6d8",
"name": "",
"statusCode": "msg.testcase.results",
"headers": {},
"x": 700,
"y": 260,
"wires": []
},
{
"id": "f414ed448fcf544b",
"type": "function",
"z": "78d15f59dee4b6d8",
"name": "dms转化为oas",
"func": "'use strict';\n\nconst DEFAULT_OPENAPI_VERSION = '3.0.1';\nconst DEFAULT_API_VERSION = '1.0.0';\n\nlet schema;\ntry {\n // 优先使用 HTTP In 提供的 req.body.schema缺省时回退到 msg.payload。\n const schemaInput = extractSchemaInput(msg);\n schema = parseSchema(schemaInput);\n} catch (error) {\n node.error(`DMS -> Swagger 解析失败:${error.message}`, msg);\n msg.error = error.message;\n return msg;\n}\n\nconst resourceTitle = typeof schema.title === 'string' && schema.title.trim()\n ? schema.title.trim()\n : 'DMS Resource';\n\nconst resourceName = pascalCase(resourceTitle);\nconst collectionName = pluralize(kebabCase(resourceTitle));\nconst identityField = Array.isArray(schema.identityId) && schema.identityId.length > 0\n ? String(schema.identityId[0])\n : 'id';\n\nconst schemaComponent = buildComponentSchema(resourceName, schema);\nconst identitySchema = schemaComponent.properties && schemaComponent.properties[identityField]\n ? clone(schemaComponent.properties[identityField])\n : { type: 'string' };\n\nconst openApiDocument = {\n openapi: DEFAULT_OPENAPI_VERSION,\n info: {\n title: `${resourceTitle} API`,\n version: DEFAULT_API_VERSION,\n description: schema.description || `${schema.$id || ''}`.trim(),\n 'x-dms-sourceId': schema.$id || undefined,\n },\n paths: buildCrudPaths({\n collectionName,\n resourceName,\n identityField,\n identitySchema,\n }),\n components: {\n schemas: {\n [resourceName]: schemaComponent,\n },\n },\n};\n\nmsg.oas_def = openApiDocument;\nmsg.payload = openApiDocument;\nreturn msg;\n\nfunction extractSchemaInput(message) {\n if (message && message.req && message.req.body && typeof message.req.body === 'object') {\n if (message.req.body.schema !== undefined) {\n return message.req.body.schema;\n }\n }\n\n if (message && message.payload !== undefined) {\n return message.payload;\n }\n\n throw new Error('未找到schema请在请求体的schema字段或msg.payload中提供');\n}\n\nfunction parseSchema(source) {\n if (typeof source === 'string') {\n try {\n return JSON.parse(source);\n } catch (error) {\n throw new Error(`JSON 解析失败:${error.message}`);\n }\n }\n\n if (!source || typeof source !== 'object') {\n throw new Error('schema 必须是 DMS 定义对象或 JSON 字符串');\n }\n\n return source;\n}\n\nfunction buildComponentSchema(resourceName, dmsSchema) {\n const { properties = {}, required = [], groupView, identityId, naturalKey, defaultShow } = dmsSchema;\n const openApiProps = {};\n\n for (const [propName, propSchema] of Object.entries(properties)) {\n openApiProps[propName] = mapProperty(propSchema);\n }\n\n return {\n type: 'object',\n required: Array.isArray(required) ? required.slice() : [],\n properties: openApiProps,\n description: dmsSchema.description || dmsSchema.title || resourceName,\n 'x-dms-groupView': groupView || undefined,\n 'x-dms-identityId': identityId || undefined,\n 'x-dms-naturalKey': naturalKey || undefined,\n 'x-dms-defaultShow': defaultShow || undefined,\n };\n}\n\nfunction mapProperty(propSchema) {\n if (!propSchema || typeof propSchema !== 'object') {\n return { type: 'string' };\n }\n\n const result = {};\n\n const type = normalizeType(propSchema.type);\n result.type = type.type;\n if (type.format) {\n result.format = type.format;\n }\n if (type.items) {\n result.items = type.items;\n }\n\n if (propSchema.description) {\n result.description = propSchema.description;\n } else if (propSchema.title) {\n result.description = propSchema.title;\n }\n\n if (propSchema.enum) {\n result.enum = propSchema.enum.slice();\n }\n\n if (propSchema.default !== undefined) {\n result.default = propSchema.default;\n }\n\n if (propSchema.mask) {\n result['x-dms-mask'] = propSchema.mask;\n }\n if (propSchema.geom) {\n result['x-dms-geom'] = propSchema.geom;\n }\n if (propSchema.title) {\n result['x-dms-title'] = propSchema.title;\n }\n if (propSchema.type) {\n result['x-dms-originalType'] = propSchema.type;\n }\n\n return result;\n}\n\nfunction normalizeType(typeValue) {\n const normalized = typeof typeValue === 'string' ? typeValue.toLowerCase() : undefined;\n\n switch (normalized) {\n case 'number':\n case 'integer':\n case 'long':\n case 'float':\n case 'double':\n return { type: 'number' };\n case 'boolean':\n return { type: 'boolean' };\n case 'array':\n return { type: 'array', items: { type: 'string' } };\n case 'date':\n return { type: 'string', format: 'date' };\n case 'date-time':\n return { type: 'string', format: 'date-time' };\n case 'object':\n return { type: 'object' };\n case 'string':\n default:\n return { type: 'string' };\n }\n}\n\nfunction buildCrudPaths({ collectionName, resourceName, identityField, identitySchema }) {\n const ref = `#/components/schemas/${resourceName}`;\n const collectionPath = `/${collectionName}`;\n const itemPath = `/${collectionName}/{${identityField}}`;\n\n return {\n [collectionPath]: {\n get: {\n operationId: `list${resourceName}s`,\n summary: `List ${resourceName} resources`,\n responses: {\n 200: {\n description: 'Successful response',\n content: {\n 'application/json': {\n schema: {\n type: 'array',\n items: { $ref: ref },\n },\n },\n },\n },\n },\n },\n /*\n post: {\n operationId: `create${resourceName}`,\n summary: `Create a ${resourceName}`,\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: ref },\n },\n },\n },\n responses: {\n 201: {\n description: 'Created',\n content: {\n 'application/json': {\n schema: { $ref: ref },\n },\n },\n },\n },\n },\n */\n },\n [itemPath]: {\n parameters: [\n {\n name: identityField,\n in: 'path',\n required: true,\n schema: identitySchema,\n },\n ],\n get: {\n operationId: `get${resourceName}`,\n summary: `Get a single ${resourceName}`,\n responses: {\n 200: {\n description: 'Successful response',\n content: {\n 'application/json': {\n schema: { $ref: ref },\n },\n },\n },\n 404: { description: `${resourceName} not found` },\n },\n },\n /*\n put: {\n operationId: `update${resourceName}`,\n summary: `Update a ${resourceName}`,\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: ref },\n },\n },\n },\n responses: {\n 200: {\n description: 'Successful update',\n content: {\n 'application/json': {\n schema: { $ref: ref },\n },\n },\n },\n },\n },\n delete: {\n operationId: `delete${resourceName}`,\n summary: `Delete a ${resourceName}`,\n responses: {\n 204: { description: 'Deleted' },\n },\n },\n */\n },\n };\n}\n\nfunction pascalCase(input) {\n return input\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('') || 'Resource';\n}\n\nfunction kebabCase(input) {\n return input\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toLowerCase() || 'resource';\n}\n\nfunction pluralize(word) {\n if (word.endsWith('s')) {\n return word;\n }\n if (word.endsWith('y')) {\n return word.slice(0, -1) + 'ies';\n }\n return `${word}s`;\n}\n\nfunction clone(value) {\n return JSON.parse(JSON.stringify(value));\n}\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 320,
"y": 220,
"wires": [
[
"dfe6ed572461c4a5",
"5231ed8a796d6f17"
]
]
},
{
"id": "ab16f5ccd9266e28",
"type": "inject",
"z": "78d15f59dee4b6d8",
"name": "",
"props": [
{
"p": "req.body.schema",
"v": "{\"$id\":\"https://schema.ideas.cnpc/json/core-data/cd_well.1.0.0.json\",\"type\":\"Object\",\"title\":\"井\",\"schema\":\"http://json-schema.org/draft-07/schema#\",\"required\":[\"bsflag\",\"dataRegion\",\"createUserId\",\"orgId\",\"wellPurpose\",\"createDate\",\"wellLegalName\",\"dsid\",\"wellType\",\"updateUserId\",\"updateDate\",\"wellId\",\"wellCommonName\",\"projectId\"],\"groupView\":[{\"name\":\"groupByWellCommonName\",\"group\":[\"dataRegion\",\"wellCommonName\",\"wellId\"]},{\"name\":\"groupByPlatformName\",\"group\":[\"dataRegion\",\"platformName\"]}],\"identityId\":[\"dsid\"],\"naturalKey\":[\"dataRegion\",\"wellCommonName\"],\"properties\":{\"kb\":{\"type\":\"number\",\"title\":\"补心海拔\",\"description\":\"海拔(高程),补心海拔=地面海拔+补心高\"},\"egl\":{\"type\":\"number\",\"title\":\"地面海拔\",\"description\":\"地面海拔\"},\"kbd\":{\"type\":\"number\",\"title\":\"补心高度\",\"description\":\"补心高度\"},\"dsid\":{\"type\":\"string\",\"title\":\"DSID\",\"description\":\"主键ID\"},\"orgId\":{\"type\":\"string\",\"title\":\"机构ID\",\"description\":\"单位唯一标识符关联CD_ORGANIZATION的主键\"},\"bsflag\":{\"type\":\"number\",\"title\":\"删除标识\",\"description\":\"填写数据逻辑删除标识1=在用,-5=废弃\"},\"canton\":{\"type\":\"string\",\"title\":\"行政区名称\",\"description\":\"填写行政区代码对应的行政区名称\"},\"siteId\":{\"type\":\"string\",\"title\":\"物探工区ID\",\"description\":\"物探工区ID\"},\"wellId\":{\"type\":\"string\",\"title\":\"井ID\",\"description\":\"井标识符非限定唯一。由EPDM系统自动产生维护无需人工干预是用于唯一标识EPDM系统的每一口井的内部机器码\"},\"orgName\":{\"type\":\"string\",\"title\":\"机构名称\",\"description\":\"单位名称,必填\"},\"remarks\":{\"type\":\"string\",\"title\":\"备注\",\"description\":\"备注\"},\"prodDate\":{\"type\":\"date\",\"title\":\"投产日期\",\"description\":\"投产日期\"},\"siteName\":{\"type\":\"string\",\"title\":\"物探工区名称\",\"description\":\"物探工区名称\"},\"spudDate\":{\"type\":\"date\",\"title\":\"开钻日期\",\"description\":\"主井筒的开钻日期\"},\"wellDesc\":{\"type\":\"string\",\"title\":\"曾用名\",\"description\":\"填写这口井的曾用名\"},\"wellType\":{\"type\":\"string\",\"title\":\"井型\",\"description\":\"属性规范值字段引用属性代码WELL_TYPE下的属性值\"},\"checkDate\":{\"type\":\"date\",\"title\":\"审核日期\",\"description\":\"记录数据在本系统的审核时间,需精确到时分秒\"},\"dataGroup\":{\"type\":\"string\",\"title\":\"数据分组\",\"description\":\"数据分组\"},\"projectId\":{\"type\":\"string\",\"title\":\"地质单元ID\",\"description\":\"地质单元唯一标识符根据井别不同选择关联构造单元探井还是油气田单元开发井关联CD_GEO_UNIT表的主键\"},\"stationId\":{\"type\":\"string\",\"title\":\"站库ID\",\"description\":\"站库ID\"},\"wellState\":{\"type\":\"string\",\"title\":\"井状态\",\"description\":\"井状态\"},\"activityId\":{\"type\":\"string\",\"title\":\"项目ID\",\"description\":\"项目唯一标示符关联CD_ACTIVITY表的主键\"},\"cantonCode\":{\"type\":\"string\",\"title\":\"行政区代码\",\"description\":\"属性规范值字段引用属性代码CANTON下的属性值\"},\"createDate\":{\"type\":\"date\",\"title\":\"创建日期\",\"description\":\"记录数据在本系统的创建时间,需精确到时分秒\"},\"dataRegion\":{\"type\":\"string\",\"title\":\"油田标识\",\"description\":\"油田标识\"},\"dataSource\":{\"type\":\"string\",\"title\":\"数据来源\",\"description\":\"填写数据来源的表CODE\"},\"desgWellId\":{\"type\":\"string\",\"title\":\"设计井ID\",\"description\":\"设计井的唯一标识\"},\"energyType\":{\"type\":\"string\",\"title\":\"能源类型\",\"description\":\"描述本井生产的油气资源类型,如煤层气、致密气、页岩气等\"},\"platformId\":{\"type\":\"string\",\"title\":\"平台ID\",\"description\":\"平台ID\"},\"updateDate\":{\"type\":\"date\",\"title\":\"更新日期\",\"description\":\"记录数据在本系统最新的更新时间,需精确到时分秒,默认=创建时间\"},\"wellTypeId\":{\"type\":\"string\",\"title\":\"井型ID\",\"description\":\"属性规范值字段引用属性代码WELL_TYPE下的属性值\"},\"abandonDate\":{\"type\":\"date\",\"title\":\"报废日期\",\"description\":\"报废日期\"},\"abondonType\":{\"type\":\"string\",\"title\":\"报废类型\",\"description\":\"报废类型\"},\"actualXAxis\":{\"geom\":\"Point.x.actual\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"实际X坐标,实际X坐标\"},\"actualYAxis\":{\"geom\":\"Point.y.actual\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"实际Y坐标,实际Y坐标\"},\"checkUserId\":{\"type\":\"string\",\"title\":\"审核用户\",\"description\":\"记录数据在本系统的审核用户\"},\"createAppId\":{\"type\":\"string\",\"title\":\"创建应用\",\"description\":\"填写数据来源的系统名\"},\"designXAxis\":{\"geom\":\"Point.x.design\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"设计X坐标,设计X坐标\"},\"designYAxis\":{\"geom\":\"Point.y.design\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"设计Y坐标,设计Y坐标\"},\"projectName\":{\"type\":\"string\",\"title\":\"地质单元名称\",\"description\":\"地质单元名称,填写地质单元的中文名称,该名称在整个油田公司内不能重名,必填\"},\"stationName\":{\"type\":\"string\",\"title\":\"站库名称\",\"description\":\"站库名称,必填\"},\"wellPurpose\":{\"type\":\"string\",\"title\":\"井别\",\"description\":\"属性规范值字段引用属性代码WELL_PURPOSE下的属性值\"},\"activityName\":{\"type\":\"string\",\"title\":\"项目名称\",\"description\":\"项目名称,必填\"},\"completionMd\":{\"type\":\"number\",\"title\":\"完钻井深\",\"description\":\"完钻井深\"},\"createUserId\":{\"type\":\"string\",\"title\":\"创建用户\",\"description\":\"记录数据在本系统的创建用户\"},\"keyWellLevel\":{\"type\":\"string\",\"title\":\"重点井级别\",\"description\":\"重点井级别\"},\"platformName\":{\"type\":\"string\",\"title\":\"平台名称\",\"description\":\"平台名称\"},\"sourceDataId\":{\"type\":\"string\",\"title\":\"源库ID标识\",\"description\":\"存储数据来源的主键信息\"},\"structurePos\":{\"type\":\"string\",\"title\":\"构造位置\",\"description\":\"构造位置的描述\"},\"updateUserId\":{\"type\":\"string\",\"title\":\"更新用户\",\"description\":\"记录数据在本系统最新的更新用户,默认=创建用户\"},\"geoOffsetEast\":{\"geom\":\"Point.x.wellhead\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"井口横坐标\"},\"seismicLineNo\":{\"type\":\"string\",\"title\":\"井旁地震测线号\",\"description\":\"井旁地震测线号(勘探井)\"},\"wellLegalName\":{\"type\":\"string\",\"title\":\"拼音井号\",\"description\":\"规范的井号名称,井号名称命名规范请参考《主数据库技术标准》\"},\"wellPurposeId\":{\"type\":\"string\",\"title\":\"井别ID\",\"description\":\"属性规范值字段引用属性代码WELL_PURPOSE下的属性值\"},\"completionDate\":{\"type\":\"date\",\"title\":\"完井日期\",\"description\":\"完井日期\"},\"geoDescription\":{\"type\":\"string\",\"title\":\"地理位置\",\"description\":\"地理位置的描述\"},\"geoOffsetNorth\":{\"geom\":\"Point.y.wellhead\",\"mask\":\"coordinate\",\"type\":\"number\",\"title\":\"井口纵坐标\"},\"wellCommonName\":{\"type\":\"string\",\"title\":\"井名\",\"description\":\"通用井名,来源于钻井公报的汉字井名,必填\"},\"endDrillingDate\":{\"type\":\"date\",\"title\":\"完钻日期\",\"description\":\"最后一个井筒的完钻日期\"},\"targetFormation\":{\"type\":\"string\",\"title\":\"目的层\",\"description\":\"目的层\"},\"completionMethod\":{\"type\":\"string\",\"title\":\"完井方法\",\"description\":\"完井方法\"},\"registrationDate\":{\"type\":\"date\",\"title\":\"注册日期\",\"description\":\"井位通知单下达日期\"},\"sourceCreateDate\":{\"type\":\"date\",\"title\":\"源头数据采集时间\",\"description\":\"记录源头系统采集数据的时间\"},\"coordinateSystemId\":{\"geom\":\"Point.srid.wellhead,Point.srid.design,Point.srid.actual\",\"type\":\"string\",\"title\":\"坐标系统ID\",\"description\":\"坐标系统的唯一标示符\"},\"completionFormation\":{\"type\":\"string\",\"title\":\"钻井完钻层位\",\"description\":\"钻井完钻层位\"},\"coordinateSystemName\":{\"type\":\"string\",\"title\":\"坐标系名称\",\"description\":\"坐标系名称\"},\"wellbaseGeoOffsetEast\":{\"type\":\"number\",\"title\":\"井底横坐标\",\"description\":\"井底横坐标\"},\"wellbaseGeoOffsetNorth\":{\"type\":\"number\",\"title\":\"井底纵坐标\",\"description\":\"井底纵坐标\"}},\"defaultShow\":[\"wellCommonName\"]}",
"vt": "json"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 170,
"y": 280,
"wires": [
[
"f414ed448fcf544b"
]
]
},
{
"id": "dfe6ed572461c4a5",
"type": "debug",
"z": "78d15f59dee4b6d8",
"name": "debug 10",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "msg",
"targetType": "jsonata",
"statusVal": "",
"statusType": "auto",
"x": 600,
"y": 140,
"wires": []
},
{
"id": "a252afceaa16c14c",
"type": "catch",
"z": "78d15f59dee4b6d8",
"name": "",
"scope": null,
"uncaught": false,
"x": 160,
"y": 460,
"wires": [
[
"1496f4d2a070111c"
]
]
},
{
"id": "1496f4d2a070111c",
"type": "debug",
"z": "78d15f59dee4b6d8",
"name": "debug 11",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 440,
"y": 460,
"wires": []
},
{
"id": "5231ed8a796d6f17",
"type": "function",
"z": "78d15f59dee4b6d8",
"name": "分页参数检查",
"func": "'use strict';\n\nconst TEST_METADATA = {\n id: 'TC-DMS-PAGINATION-001',\n name: '分页参数检查',\n description: \"检查API请求参数中是否包含标准分页参数pageNo、pageSize和isSearchCount。只有名称含有'查询'、'列表'等并且不含有'详情'一类的API才应用此验证。\",\n severity: 'MEDIUM',\n tags: ['pagination', 'params', 'backend-guide'],\n skip_execution: true,\n};\n\nconst globalApiSpec = msg && msg.oas_def ? msg.oas_def : null;\n\nif (!globalApiSpec || typeof globalApiSpec !== 'object' || !globalApiSpec.paths) {\n const errorMessage = '分页参数检查无法运行msg.oas_def 缺失、不是对象或不包含 paths';\n node.error(errorMessage, msg);\n msg.error = errorMessage;\n msg.testcase = {\n metadata: TEST_METADATA,\n applies: false,\n skipped: true,\n results: [],\n };\n return msg;\n}\n\nconst allResults = [];\nlet testApplied = false;\n\n// 遍历所有路径和方法\nfor (const path in globalApiSpec.paths) {\n if (Object.prototype.hasOwnProperty.call(globalApiSpec.paths, path)) {\n const pathItem = globalApiSpec.paths[path];\n for (const method in pathItem) {\n if (Object.prototype.hasOwnProperty.call(pathItem, method) && ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'].includes(method.toLowerCase())) {\n\n const operation = pathItem[method];\n if (!operation || typeof operation !== 'object') continue;\n\n // 构建 endpointSpec\n const endpointSpec = buildEndpointSpec(path, method, pathItem, operation);\n\n // 检查测试是否适用\n if (shouldApplyTest(endpointSpec)) {\n testApplied = true;\n const evaluation = runPaginationCheck(endpointSpec, globalApiSpec);\n allResults.push(...evaluation.results);\n }\n }\n }\n }\n}\n\nmsg.testcase = {\n metadata: TEST_METADATA,\n applies: testApplied,\n skipped: !testApplied,\n results: allResults,\n};\nmsg.payload = msg.testcase;\nreturn msg;\n\nfunction buildEndpointSpec(path, method, pathItem, operation) {\n const combinedParameters = [];\n if (Array.isArray(pathItem.parameters)) {\n combinedParameters.push(...pathItem.parameters);\n }\n if (Array.isArray(operation.parameters)) {\n combinedParameters.push(...operation.parameters);\n }\n\n const spec = deepClone(operation);\n spec.method = method;\n spec.path = path;\n if (combinedParameters.length > 0) {\n spec.parameters = mergeParameters(combinedParameters);\n }\n return spec;\n}\n\nfunction shouldApplyTest(spec) {\n const method = (spec.method || '').toLowerCase();\n if (method !== 'get' && method !== 'post') {\n return false;\n }\n\n const path = spec.path || '';\n const summary = spec.summary || '';\n const description = spec.description || '';\n const operationId = spec.operationId || '';\n\n const includeKeywords = ['查询', '列表', '分页', 'page', 'list', 'query', 'search', 'find'];\n const excludeKeywords = ['详情', '明细', 'detail', 'info', 'get by id', 'getbyid', '查看'];\n\n const apiDescriptionText = `${summary} ${description} ${operationId} ${path}`.toLowerCase();\n\n const containsInclude = includeKeywords.some(keyword => apiDescriptionText.includes(keyword.toLowerCase()));\n if (!containsInclude) {\n return false;\n }\n\n // 检查是否是获取单个资源的 'get'\n if (method === 'get' && path.includes('{') && path.includes('}')) {\n const getByIdHints = ['get', 'detail', 'info', '查看'];\n const isGetById = getByIdHints.some(hint => apiDescriptionText.includes(hint));\n if (isGetById) return false;\n }\n\n const containsExclude = excludeKeywords.some(keyword => apiDescriptionText.includes(keyword.toLowerCase()));\n return !containsExclude;\n}\n\nfunction extractEndpointSpec(message, apiSpec) {\n // This function is no longer needed as we iterate through all paths and methods.\n // Kept for potential future use if a single endpoint needs to be targeted.\n return null;\n}\n\nfunction resolveEndpointInfo(message) {\n // This function is no longer needed as we iterate through all paths and methods.\n return null;\n}\n\nfunction mergeParameters(parameters) {\n const merged = new Map();\n for (const param of parameters) {\n if (!param || typeof param !== 'object') {\n continue;\n }\n const name = param.name || '';\n const location = param.in || '';\n const key = `${location}:${name}`;\n if (!merged.has(key)) {\n merged.set(key, deepClone(param));\n }\n }\n return Array.from(merged.values());\n}\n\nfunction runPaginationCheck(spec, apiSpec) {\n const results = [];\n const path = spec.path || '';\n const method = (spec.method || '').toLowerCase();\n\n let foundPageNo = false;\n let foundPageSize = false;\n let foundIsSearchCount = false;\n\n if (Array.isArray(spec.parameters)) {\n for (const param of spec.parameters) {\n if (!param || typeof param !== 'object') {\n continue;\n }\n const location = (param.in || '').toLowerCase();\n if (location !== 'query') {\n continue;\n }\n\n if (param.name === 'pageNo') {\n foundPageNo = true;\n } else if (param.name === 'pageSize') {\n foundPageSize = true;\n } else if (param.name === 'isSearchCount') {\n foundIsSearchCount = true;\n }\n }\n }\n\n if (method === 'post' && spec.requestBody && typeof spec.requestBody === 'object') {\n const { content } = spec.requestBody;\n if (content && typeof content === 'object') {\n for (const mediaType of Object.keys(content)) {\n const mediaDefinition = content[mediaType];\n if (!mediaDefinition || typeof mediaDefinition !== 'object') {\n continue;\n }\n const resolvedSchema = resolveSchema(mediaDefinition.schema, apiSpec);\n const properties = resolvedSchema && resolvedSchema.properties;\n if (!properties || typeof properties !== 'object') {\n continue;\n }\n\n if (Object.prototype.hasOwnProperty.call(properties, 'pageNo')) {\n foundPageNo = true;\n }\n if (Object.prototype.hasOwnProperty.call(properties, 'pageSize')) {\n foundPageSize = true;\n }\n if (Object.prototype.hasOwnProperty.call(properties, 'isSearchCount')) {\n foundIsSearchCount = true;\n }\n }\n }\n }\n\n if (foundPageNo && foundPageSize && foundIsSearchCount) {\n results.push(makePassedResult('API请求包含所有标准分页参数pageNo、pageSize和isSearchCount', {\n path,\n method: method.toUpperCase(),\n }));\n } else {\n const missingParams = [];\n if (!foundPageNo) missingParams.push('pageNo');\n if (!foundPageSize) missingParams.push('pageSize');\n if (!foundIsSearchCount) missingParams.push('isSearchCount');\n\n results.push(makeFailedResult(`API请求缺少标准分页参数${missingParams.join(', ')}`, {\n path,\n method: method.toUpperCase(),\n missing_params: missingParams,\n found_params: {\n pageNo: foundPageNo,\n pageSize: foundPageSize,\n isSearchCount: foundIsSearchCount,\n },\n }));\n }\n\n return { results };\n}\n\nfunction deepClone(value) {\n return value == null ? value : JSON.parse(JSON.stringify(value));\n}\n\nfunction makePassedResult(message, details) {\n return {\n passed: true,\n message,\n details: details || {},\n };\n}\n\nfunction makeFailedResult(message, details) {\n return {\n passed: false,\n message,\n details: details || {},\n };\n}\n\nfunction resolveSchema(schemaOrRef, apiSpec) {\n if (!schemaOrRef || typeof schemaOrRef !== 'object') {\n return {};\n }\n\n if (!schemaOrRef.$ref) {\n return schemaOrRef;\n }\n\n if (!apiSpec || typeof apiSpec !== 'object') {\n return schemaOrRef;\n }\n\n const refPath = schemaOrRef.$ref;\n if (typeof refPath !== 'string' || !refPath.startsWith('#/')) {\n return schemaOrRef;\n }\n\n const tokens = refPath.slice(2).split('/').map(unescapeRefToken);\n let current = apiSpec;\n for (const token of tokens) {\n if (current && Object.prototype.hasOwnProperty.call(current, token)) {\n current = current[token];\n } else {\n return schemaOrRef;\n }\n }\n\n return current && typeof current === 'object' ? current : schemaOrRef;\n}\n\nfunction unescapeRefToken(token) {\n return token.replace(/~1/g, '/').replace(/~0/g, '~');\n}\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 460,
"y": 320,
"wires": [
[
"dfe6ed572461c4a5",
"d666851b16cf6482"
]
]
},
{
"id": "9a020a2d438e0d5e",
"type": "file",
"z": "78d15f59dee4b6d8",
"name": "",
"filename": "C:\\workspace\\test2.txt",
"filenameType": "str",
"appendNewline": true,
"createDir": false,
"overwriteFile": "false",
"encoding": "none",
"x": 760,
"y": 200,
"wires": [
[]
]
},
{
"id": "ad6438b1a6e76365",
"type": "inject",
"z": "78d15f59dee4b6d8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 210,
"y": 320,
"wires": [
[
"f414ed448fcf544b"
]
]
}
]