diff --git a/README.md b/README.md index f801f3f..1cbfc03 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ ## TODO -pre 环境屏蔽外部配置后启动,主要用于检查和配置采集器 - -支付回调需要判断可能重复调用的情况 - -实现订单状态查询的 SSE 接口 - - - ### 长期 更新支付状态后,缓存结果以便查询 diff --git a/docs/支付接口处理流程.excalidraw b/docs/支付接口处理流程.excalidraw new file mode 100644 index 0000000..6b8ef9d --- /dev/null +++ b/docs/支付接口处理流程.excalidraw @@ -0,0 +1,1289 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "bmIRiNhorAfnANXQRYZOo", + "type": "rectangle", + "x": 667, + "y": -13, + "width": 178, + "height": 105, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0u", + "roundness": { + "type": 3 + }, + "seed": 341025248, + "version": 134, + "versionNonce": 1546883552, + "isDeleted": false, + "boundElements": [ + { + "id": "KDZTqivC63YtCM2AFDBi7", + "type": "arrow" + }, + { + "type": "text", + "id": "MliWfNwLLhLc_W6KdWK5P" + }, + { + "id": "8Jgd2T5r4qgB5CgO8EsjS", + "type": "arrow" + }, + { + "id": "mDPOBLlv5XfmCD_99LGfZ", + "type": "arrow" + } + ], + "updated": 1755159656267, + "link": null, + "locked": false + }, + { + "id": "MliWfNwLLhLc_W6KdWK5P", + "type": "text", + "x": 716, + "y": 27, + "width": 80, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0uV", + "roundness": null, + "seed": 209706016, + "version": 112, + "versionNonce": 116474238, + "isDeleted": false, + "boundElements": [], + "updated": 1755252409701, + "link": null, + "locked": false, + "text": "创建订单", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bmIRiNhorAfnANXQRYZOo", + "originalText": "创建订单", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "UBH-70S9aMSAfGgxMQAZX", + "type": "rectangle", + "x": 842.1111111111111, + "y": -320.88888888888886, + "width": 170, + "height": 107, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0v", + "roundness": { + "type": 3 + }, + "seed": 459578400, + "version": 261, + "versionNonce": 845247422, + "isDeleted": false, + "boundElements": [ + { + "id": "KDZTqivC63YtCM2AFDBi7", + "type": "arrow" + }, + { + "type": "text", + "id": "5nW8wcQ95L-zgTwDAnVmg" + }, + { + "id": "JFOC2TYHOLQvi2t2ONgMY", + "type": "arrow" + }, + { + "id": "yU6K7vXNFM30nWzXfGuVQ", + "type": "arrow" + }, + { + "id": "V3yIpZahue6n-m-LtUe5-", + "type": "arrow" + }, + { + "id": "RJwvxqhHwed70yglXjKEr", + "type": "arrow" + } + ], + "updated": 1755252492458, + "link": null, + "locked": false + }, + { + "id": "5nW8wcQ95L-zgTwDAnVmg", + "type": "text", + "x": 907.1111111111111, + "y": -279.88888888888886, + "width": 40, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0vV", + "roundness": null, + "seed": 920482848, + "version": 228, + "versionNonce": 2142784510, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "text": "支付", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "UBH-70S9aMSAfGgxMQAZX", + "originalText": "支付", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "KDZTqivC63YtCM2AFDBi7", + "type": "arrow", + "x": 791.8559117000124, + "y": -19.891051832961452, + "width": 88.40322697971362, + "height": 184.61317442588927, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0w", + "roundness": { + "type": 2 + }, + "seed": 1162625504, + "version": 339, + "versionNonce": 1695161406, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 88.40322697971362, + -184.61317442588927 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "bmIRiNhorAfnANXQRYZOo", + "focus": 0.07111407605069947, + "gap": 12.764809769148098 + }, + "endBinding": { + "elementId": "UBH-70S9aMSAfGgxMQAZX", + "focus": 0.1505507955936347, + "gap": 16.528643016121972 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "DqDvJptMBnEF0YqpbEaWd", + "type": "rectangle", + "x": 1093.111111111111, + "y": -321.88888888888886, + "width": 186.99999999999997, + "height": 110.00000000000001, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0x", + "roundness": { + "type": 3 + }, + "seed": 798681120, + "version": 404, + "versionNonce": 1220195710, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "PbzfH_HJevLU-2mfY3qqC" + }, + { + "id": "8Jgd2T5r4qgB5CgO8EsjS", + "type": "arrow" + }, + { + "id": "kGUtBIm0ECfKY-SwXrmKv", + "type": "arrow" + } + ], + "updated": 1755252492458, + "link": null, + "locked": false + }, + { + "id": "PbzfH_HJevLU-2mfY3qqC", + "type": "text", + "x": 1166.611111111111, + "y": -279.38888888888886, + "width": 40, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0y", + "roundness": null, + "seed": 86563872, + "version": 252, + "versionNonce": 84104638, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "text": "队列", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "DqDvJptMBnEF0YqpbEaWd", + "originalText": "队列", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "8Jgd2T5r4qgB5CgO8EsjS", + "type": "arrow", + "x": 852.1968184892847, + "y": -10.223179419881205, + "width": 234.4073315078332, + "height": 210.67786239132147, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0z", + "roundness": { + "type": 2 + }, + "seed": 1799263712, + "version": 340, + "versionNonce": 667807230, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492459, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 234.4073315078332, + -210.67786239132147 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "bmIRiNhorAfnANXQRYZOo", + "focus": 0.282889499082003, + "gap": 13.193797344136419 + }, + "endBinding": { + "elementId": "DqDvJptMBnEF0YqpbEaWd", + "focus": 0.31529516994633344, + "gap": 10.158482631827605 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "IQxetlMy6WVL5JICpM_N2", + "type": "rectangle", + "x": 925, + "y": -19, + "width": 196, + "height": 110, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b11", + "roundness": { + "type": 3 + }, + "seed": 1722890272, + "version": 87, + "versionNonce": 250057760, + "isDeleted": false, + "boundElements": [ + { + "id": "JFOC2TYHOLQvi2t2ONgMY", + "type": "arrow" + }, + { + "id": "D25neZf2irSwGzbHerF1g", + "type": "arrow" + } + ], + "updated": 1755159725479, + "link": null, + "locked": false + }, + { + "id": "i7OeKAUvEOli6UxrU3EKU", + "type": "rectangle", + "x": 1182, + "y": -18, + "width": 192, + "height": 104, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b13", + "roundness": { + "type": 3 + }, + "seed": 1175120352, + "version": 40, + "versionNonce": 636790240, + "isDeleted": false, + "boundElements": [ + { + "id": "kGUtBIm0ECfKY-SwXrmKv", + "type": "arrow" + }, + { + "id": "G79dsogvNeSIx6Q1a8ul_", + "type": "arrow" + } + ], + "updated": 1755159778660, + "link": null, + "locked": false + }, + { + "id": "kGUtBIm0ECfKY-SwXrmKv", + "type": "arrow", + "x": 1220.926227772824, + "y": -207.61033407141724, + "width": 19.591643116347996, + "height": 214.04082805799155, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b15", + "roundness": { + "type": 2 + }, + "seed": 1248671776, + "version": 296, + "versionNonce": 2115731006, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492459, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 19.591643116347996, + 214.04082805799155 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "DqDvJptMBnEF0YqpbEaWd", + "focus": -0.29353840791250757, + "gap": 8.109267607121028 + }, + "endBinding": { + "elementId": "jokH0eEg6fASYkwOxGFm1", + "focus": 0.32267451623440035, + "gap": 11.572080803627642 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "JFOC2TYHOLQvi2t2ONgMY", + "type": "arrow", + "x": 970.4260672708022, + "y": -201.54141088391037, + "width": 103.97686072899228, + "height": 210.61596455191264, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b16", + "roundness": { + "type": 2 + }, + "seed": 1134034400, + "version": 270, + "versionNonce": 406316158, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 103.97686072899228, + 210.61596455191264 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "UBH-70S9aMSAfGgxMQAZX", + "focus": -0.097288501118154, + "gap": 21.44778971557787 + }, + "endBinding": { + "elementId": "L9g4Xw7OlQgK5rewdLHrU", + "focus": 0.36183613932324554, + "gap": 10.86064190781903 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "XOLtIg1T970qyV6cOyGiZ", + "type": "ellipse", + "x": 1025.4444444444443, + "y": 310.7777777777777, + "width": 107, + "height": 107, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1B", + "roundness": { + "type": 2 + }, + "seed": 6423584, + "version": 103, + "versionNonce": 910684478, + "isDeleted": false, + "boundElements": [ + { + "id": "mDPOBLlv5XfmCD_99LGfZ", + "type": "arrow" + }, + { + "id": "D25neZf2irSwGzbHerF1g", + "type": "arrow" + }, + { + "id": "G79dsogvNeSIx6Q1a8ul_", + "type": "arrow" + }, + { + "type": "text", + "id": "0JAK537hc9rx7Mcf6iven" + } + ], + "updated": 1755252495889, + "link": null, + "locked": false + }, + { + "id": "0JAK537hc9rx7Mcf6iven", + "type": "text", + "x": 1059.114231650964, + "y": 351.9475649842974, + "width": 40, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1BV", + "roundness": null, + "seed": 1738167778, + "version": 11, + "versionNonce": 711783422, + "isDeleted": false, + "boundElements": null, + "updated": 1755252497938, + "link": null, + "locked": false, + "text": "用户", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "XOLtIg1T970qyV6cOyGiZ", + "originalText": "用户", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "mDPOBLlv5XfmCD_99LGfZ", + "type": "arrow", + "x": 1021.5098343920322, + "y": 321.5977290473379, + "width": 248.1841941987219, + "height": 222.5733014562, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1C", + "roundness": { + "type": 2 + }, + "seed": 1482740768, + "version": 156, + "versionNonce": 1758179326, + "isDeleted": false, + "boundElements": [], + "updated": 1755252495439, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -248.1841941987219, + -222.5733014562 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "XOLtIg1T970qyV6cOyGiZ", + "focus": -0.0866633248620954, + "gap": 18.056418241171176 + }, + "endBinding": { + "elementId": "bmIRiNhorAfnANXQRYZOo", + "focus": 0.33122737742678615, + "gap": 13 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "D25neZf2irSwGzbHerF1g", + "type": "arrow", + "x": 1063.269501706512, + "y": 300.2715580006144, + "width": 86.56161478403055, + "height": 218.2703822722455, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1D", + "roundness": { + "type": 2 + }, + "seed": 1612749280, + "version": 146, + "versionNonce": 504430654, + "isDeleted": false, + "boundElements": [], + "updated": 1755252495440, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -86.56161478403055, + -218.2703822722455 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "XOLtIg1T970qyV6cOyGiZ", + "focus": 0.1300864921344435, + "gap": 12.397647909466382 + }, + "endBinding": { + "elementId": "LLbexMYaSebBUVV3Kc2ca", + "focus": 0.28477179356439575, + "gap": 8.156192149487026 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "G79dsogvNeSIx6Q1a8ul_", + "type": "arrow", + "x": 1122.4851267718925, + "y": 307.4666237154634, + "width": 100.717262018351, + "height": 226.14365561401877, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1E", + "roundness": { + "type": 2 + }, + "seed": 1628185056, + "version": 220, + "versionNonce": 1455573118, + "isDeleted": false, + "boundElements": [], + "updated": 1755252495440, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 100.717262018351, + -226.14365561401877 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "XOLtIg1T970qyV6cOyGiZ", + "focus": 0.235695009661068, + "gap": 18.077218746132967 + }, + "endBinding": { + "elementId": "jokH0eEg6fASYkwOxGFm1", + "focus": -0.16946173729766398, + "gap": 11.202940575985338 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "LLbexMYaSebBUVV3Kc2ca", + "type": "rectangle", + "x": 937, + "y": 17, + "width": 81.99999999999997, + "height": 60, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1F", + "roundness": { + "type": 3 + }, + "seed": 787024928, + "version": 67, + "versionNonce": 1996867966, + "isDeleted": false, + "boundElements": [ + { + "id": "yU6K7vXNFM30nWzXfGuVQ", + "type": "arrow" + }, + { + "id": "D25neZf2irSwGzbHerF1g", + "type": "arrow" + }, + { + "type": "text", + "id": "w0zk_HxYW231vshrUQSO-" + } + ], + "updated": 1755252443387, + "link": null, + "locked": false + }, + { + "id": "w0zk_HxYW231vshrUQSO-", + "type": "text", + "x": 958, + "y": 22, + "width": 40, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1FV", + "roundness": null, + "seed": 1987813856, + "version": 35, + "versionNonce": 622638626, + "isDeleted": false, + "boundElements": [], + "updated": 1755252447869, + "link": null, + "locked": false, + "text": "完成\n检查", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LLbexMYaSebBUVV3Kc2ca", + "originalText": "完成\n检查", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "L9g4Xw7OlQgK5rewdLHrU", + "type": "rectangle", + "x": 1035, + "y": 16, + "width": 77, + "height": 60, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1G", + "roundness": { + "type": 3 + }, + "seed": 805416992, + "version": 66, + "versionNonce": 1461512190, + "isDeleted": false, + "boundElements": [ + { + "id": "JFOC2TYHOLQvi2t2ONgMY", + "type": "arrow" + }, + { + "type": "text", + "id": "KLR_kJMA8lFX4MmoLrW9P" + } + ], + "updated": 1755252454203, + "link": null, + "locked": false + }, + { + "id": "KLR_kJMA8lFX4MmoLrW9P", + "type": "text", + "x": 1053.5, + "y": 21, + "width": 40, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1GV", + "roundness": null, + "seed": 1230225888, + "version": 27, + "versionNonce": 860761086, + "isDeleted": false, + "boundElements": [], + "updated": 1755252472855, + "link": null, + "locked": false, + "text": "完成\n处理", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "L9g4Xw7OlQgK5rewdLHrU", + "originalText": "完成\n处理", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "yU6K7vXNFM30nWzXfGuVQ", + "type": "arrow", + "x": 963.7513921741125, + "y": 10.828600648188981, + "width": 3.7297224502452764, + "height": 216.83077399209668, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1H", + "roundness": { + "type": 2 + }, + "seed": 1219467744, + "version": 151, + "versionNonce": 1795335358, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -3.7297224502452764, + -216.83077399209668 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "LLbexMYaSebBUVV3Kc2ca", + "focus": -0.3198823034888613, + "gap": 10 + }, + "endBinding": { + "elementId": "UBH-70S9aMSAfGgxMQAZX", + "focus": -0.37139374238114536, + "gap": 14 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "jokH0eEg6fASYkwOxGFm1", + "type": "rectangle", + "x": 1195, + "y": 14, + "width": 73, + "height": 60, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1I", + "roundness": { + "type": 3 + }, + "seed": 330083808, + "version": 61, + "versionNonce": 1679280930, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "HDn739ht_L1aKxn0dTPIU" + }, + { + "id": "G79dsogvNeSIx6Q1a8ul_", + "type": "arrow" + }, + { + "id": "V3yIpZahue6n-m-LtUe5-", + "type": "arrow" + }, + { + "id": "kGUtBIm0ECfKY-SwXrmKv", + "type": "arrow" + } + ], + "updated": 1755252479874, + "link": null, + "locked": false + }, + { + "id": "HDn739ht_L1aKxn0dTPIU", + "type": "text", + "x": 1211.5, + "y": 19, + "width": 40, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1IV", + "roundness": null, + "seed": 1962265056, + "version": 15, + "versionNonce": 922097378, + "isDeleted": false, + "boundElements": [], + "updated": 1755252480988, + "link": null, + "locked": false, + "text": "取消\n检查", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jokH0eEg6fASYkwOxGFm1", + "originalText": "取消\n检查", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "ZI0PGR_uD1y6hxmc7QRgr", + "type": "rectangle", + "x": 1290, + "y": 15, + "width": 70, + "height": 60, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1J", + "roundness": { + "type": 3 + }, + "seed": 787827168, + "version": 38, + "versionNonce": 1646761186, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "P1iVF_zjJLfRdCZwQ3MlC" + }, + { + "id": "RJwvxqhHwed70yglXjKEr", + "type": "arrow" + } + ], + "updated": 1755252484951, + "link": null, + "locked": false + }, + { + "id": "P1iVF_zjJLfRdCZwQ3MlC", + "type": "text", + "x": 1305, + "y": 20, + "width": 40, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1K", + "roundness": null, + "seed": 1326818784, + "version": 14, + "versionNonce": 1201948578, + "isDeleted": false, + "boundElements": [], + "updated": 1755252486827, + "link": null, + "locked": false, + "text": "取消\n处理", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ZI0PGR_uD1y6hxmc7QRgr", + "originalText": "取消\n处理", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "V3yIpZahue6n-m-LtUe5-", + "type": "arrow", + "x": 1224.4186360461333, + "y": 7.478670173411203, + "width": 227.24545127667022, + "height": 213.87330919461755, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1L", + "roundness": { + "type": 2 + }, + "seed": 1343107552, + "version": 158, + "versionNonce": 1326144766, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -227.24545127667022, + -213.87330919461755 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "jokH0eEg6fASYkwOxGFm1", + "focus": 0.4652241112828428, + "gap": 10 + }, + "endBinding": { + "elementId": "UBH-70S9aMSAfGgxMQAZX", + "focus": -0.03721556230242014, + "gap": 13.341982604298487 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "RJwvxqhHwed70yglXjKEr", + "type": "arrow", + "x": 1019.8628279223053, + "y": -211.05782957192724, + "width": 308.2196067674481, + "height": 221.43061577044426, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b1M", + "roundness": { + "type": 2 + }, + "seed": 333378016, + "version": 157, + "versionNonce": 1507003710, + "isDeleted": false, + "boundElements": [], + "updated": 1755252492458, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 308.2196067674481, + 221.43061577044426 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "UBH-70S9aMSAfGgxMQAZX", + "focus": -0.09002922082215117, + "gap": 17.223560031999124 + }, + "endBinding": { + "elementId": "ZI0PGR_uD1y6hxmc7QRgr", + "focus": 0.6685541946205441, + "gap": 7 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} \ No newline at end of file diff --git a/web/error.go b/web/error.go index d35b455..98e7268 100644 --- a/web/error.go +++ b/web/error.go @@ -18,6 +18,7 @@ func ErrorHandler(c *fiber.Ctx, err error) error { var fiberErr *fiber.Error var authErr auth.AuthenticationErr var bizErr *core.BizErr + var servErr *core.ServErr switch { @@ -38,11 +39,14 @@ func ErrorHandler(c *fiber.Ctx, err error) error { } message = err.Error() - // 服务错误 + // 已处理的业务错误 case errors.As(err, &bizErr): code = fiber.StatusBadRequest message = err.Error() - slog.Debug("服务错误", slog.Any(slog.SourceKey, bizErr.Source())) + + case errors.As(err, &servErr): + code = fiber.StatusInternalServerError + message = err.Error() // 所有未手动声明的错误类型 default: diff --git a/web/handlers/trade.go b/web/handlers/trade.go index e1b9ff8..ae95879 100644 --- a/web/handlers/trade.go +++ b/web/handlers/trade.go @@ -65,8 +65,7 @@ func TradeCreate(c *fiber.Ctx) error { } type TradeCompleteReq struct { - TradeNo string `json:"trade_no" validate:"required"` - Method trade2.Method `json:"method" validate:"required"` + s.ModifyTradeData } func TradeComplete(c *fiber.Ctx) error { @@ -83,13 +82,39 @@ func TradeComplete(c *fiber.Ctx) error { } // 检查订单状态 - err = s.Trade.CompleteTrade(&s.CheckTradeData{ + err = s.Trade.CompleteTrade(&s.ModifyTradeData{ TradeNo: req.TradeNo, Method: req.Method, }) if err != nil { - slog.Error("完成交易失败", "trade_no", req.TradeNo, "method", req.Method, "error", err) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "完成交易失败"}) + return err + } + + return c.SendStatus(fiber.StatusNoContent) +} + +type TradeCancelReq struct { + s.ModifyTradeData +} + +func TradeCancel(c *fiber.Ctx) error { + // 检查权限 + _, err := auth.Protect(c, []auth.PayloadType{auth.PayloadUser}, []string{}) + if err != nil { + return err + } + + // 解析请求参数 + req := new(TradeCancelReq) + if err := g.Validator.Validate(c, req); err != nil { + return err + } + + // 取消交易 + err = s.Trade.CancelTrade(req.TradeNo, req.Method, time.Now()) + if err != nil { + slog.Error("取消交易失败", "trade_no", req.TradeNo, "error", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "取消交易失败"}) } return c.SendStatus(fiber.StatusNoContent) @@ -99,16 +124,6 @@ type TradeCheckReq struct { tasks.CancelTradeData } -func TradeCheckSSE(c *fiber.Ctx) error { - - // 设置响应头 - c.Set("Content-Type", "text/event-stream") - c.Set("Cache-Control", "no-cache") - c.Set("Connection", "keep-alive") - - return nil -} - func TradeCancelByTask(c *fiber.Ctx) error { // 检查权限 _, err := auth.Protect(c, []auth.PayloadType{auth.PayloadInternalServer}, []string{}) diff --git a/web/router.go b/web/router.go index a58afe1..2aea85a 100644 --- a/web/router.go +++ b/web/router.go @@ -53,7 +53,7 @@ func ApplyRouters(app *fiber.App) { trade := api.Group("/trade") trade.Post("/create", handlers.TradeCreate) trade.Post("/complete", handlers.TradeComplete) - trade.Post("/check", handlers.TradeCheckSSE) + trade.Post("/cancel", handlers.TradeCancel) // 账单 bill := api.Group("/bill") diff --git a/web/services/trade.go b/web/services/trade.go index bc363d2..c3ab058 100644 --- a/web/services/trade.go +++ b/web/services/trade.go @@ -254,7 +254,7 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, data *CreateTradeDa }, nil } -func (s *tradeService) CompleteTrade(data *CheckTradeData) error { +func (s *tradeService) CompleteTrade(data *ModifyTradeData) error { return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error { // 检查订单状态 @@ -306,7 +306,8 @@ func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) { var paidAt = data.Time // 获取交易信息 - trade, err := q.Trade. + var err error + trade, err = q.Trade. Where(q.Trade.InnerNo.Eq(tradeNo)). Take() if err != nil { @@ -318,7 +319,7 @@ func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) { case trade2.StatusCanceled: return core.NewBizErr("交易已取消") case trade2.StatusSuccess: - return core.NewBizErr("交易已完成") + return nil // 跳过更新交易信息 case trade2.StatusPending: } @@ -337,7 +338,11 @@ func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) { return nil }) - return trade, err + if err != nil { + return nil, err + } else { + return trade, err + } } func afterTradeComplete(trade *m.Trade) error { @@ -479,7 +484,7 @@ func (s *tradeService) OnTradeRefunded(q *q.Query, tradeNo string, now time.Time panic("todo") } -func (s *tradeService) CheckTrade(data *CheckTradeData) (*CheckTradeResult, error) { +func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, error) { var tradeNo = data.TradeNo var method = data.Method @@ -619,8 +624,8 @@ func (s *tradeService) CheckTrade(data *CheckTradeData) (*CheckTradeResult, erro return result, nil } -func (s *tradeService) ConfirmTradeCompleted(data *CheckTradeData) (*TradeSuccessResult, error) { - rs, err := Trade.CheckTrade(&CheckTradeData{ +func (s *tradeService) ConfirmTradeCompleted(data *ModifyTradeData) (*TradeSuccessResult, error) { + rs, err := Trade.CheckTrade(&ModifyTradeData{ TradeNo: data.TradeNo, Method: data.Method, }) @@ -638,8 +643,8 @@ func (s *tradeService) ConfirmTradeCompleted(data *CheckTradeData) (*TradeSucces return rs.Success, nil } -func (s *tradeService) ConfirmTradeCanceled(data *CheckTradeData) error { - rs, err := Trade.CheckTrade(&CheckTradeData{ +func (s *tradeService) ConfirmTradeCanceled(data *ModifyTradeData) error { + rs, err := Trade.CheckTrade(&ModifyTradeData{ TradeNo: data.TradeNo, Method: data.Method, }) @@ -657,8 +662,8 @@ func (s *tradeService) ConfirmTradeCanceled(data *CheckTradeData) error { return nil } -func (s *tradeService) ConfirmTradeRefunded(data *CheckTradeData) error { - rs, err := Trade.CheckTrade(&CheckTradeData{ +func (s *tradeService) ConfirmTradeRefunded(data *ModifyTradeData) error { + rs, err := Trade.CheckTrade(&ModifyTradeData{ TradeNo: data.TradeNo, Method: data.Method, }) @@ -697,9 +702,9 @@ type CreateTradeResult struct { PaymentUrl string } -type CheckTradeData struct { - TradeNo string - Method trade2.Method +type ModifyTradeData struct { + TradeNo string `json:"trade_no" validate:"required"` + Method trade2.Method `json:"method" validate:"required"` } type CheckTradeResult struct {