vue2-client 1.22.2 → 1.22.3
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/.claude/settings.local.json +30 -30
- package/.env.his +19 -19
- package/.eslintrc.js +74 -74
- package/.history/.eslintrc_20260521171150.js +74 -0
- package/.history/.eslintrc_20260521171213.js +74 -0
- package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +726 -0
- package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +478 -0
- package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +706 -0
- package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +694 -0
- package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +755 -0
- package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +524 -0
- package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +731 -0
- package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +525 -0
- package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +1046 -0
- package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +512 -0
- package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +511 -0
- package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +696 -0
- package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +693 -0
- package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +677 -0
- package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164645.vue +758 -0
- package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164714.vue +693 -0
- package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508171651.vue +716 -0
- package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509133717.vue +695 -0
- package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509171115.vue +664 -0
- package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +1455 -0
- package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +1441 -0
- package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +1441 -0
- package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +1442 -0
- package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +1486 -0
- package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +1607 -0
- package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +643 -0
- package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +628 -0
- package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +104 -0
- package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +102 -0
- package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +1241 -0
- package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +1223 -0
- package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +472 -0
- package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +538 -0
- package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +650 -0
- package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +1469 -0
- package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +788 -0
- package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +780 -0
- package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +585 -0
- package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +787 -0
- package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +739 -0
- package/.history/src/components/STable/index_20260409155138.js +806 -0
- package/.history/src/components/STable/index_20260409155218.js +814 -0
- package/.history/src/expression/core/Expression_20260305164427.js +1371 -0
- package/.history/src/expression/core/Expression_20260305170258.js +1358 -0
- package/.history/src/expression/core/Program_20260305111830.js +944 -0
- package/.history/src/expression/core/Program_20260305112041.js +931 -0
- package/.history/src/logic/LogicRunner_20260304154306.js +170 -0
- package/.history/src/logic/LogicRunner_20260304155553.js +112 -0
- package/.history/src/logic/LogicRunner_20260305105834.js +112 -0
- package/.history/src/logic/LogicRunner_20260305112718.js +129 -0
- package/.history/src/logic/LogicRunner_20260305182436.js +133 -0
- package/.history/src/logic/LogicRunner_20260306151301.js +213 -0
- package/.history/src/logic/LogicRunner_20260306152419.js +213 -0
- package/.history/src/logic/plugins/common/DateTools_20260305154159.js +61 -0
- package/.history/src/logic/plugins/common/DateTools_20260305154217.js +44 -0
- package/.history/src/logic/plugins/common/DateTools_20260305161014.js +44 -0
- package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +80 -0
- package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +75 -0
- package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +75 -0
- package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +72 -0
- package/.history/src/services/api/restTools_20260427142149.js +245 -0
- package/.history/src/services/api/restTools_20260427142853.js +230 -0
- package/.history/src/services/api/restTools_20260519135558.js +230 -0
- package/.history/src/services/api/restTools_20260519140825.js +230 -0
- package/.history/src/services/api/restTools_20260519151223.js +230 -0
- package/.history/src/utils/indexedDB_20260306150918.js +593 -0
- package/.history/src/utils/indexedDB_20260306151301.js +586 -0
- package/.idea/af-vue2-client.iml +9 -0
- package/.idea/codeStyles/Project.xml +62 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +1 -1
- package/Components.md +60 -60
- package/index.js +31 -31
- package/jest-transform-stub.js +8 -8
- package/jest.setup.js +7 -7
- package/package.json +1 -1
- package/preview-input-box.html +180 -0
- package/src/assets/img/querySlotDemo.svg +15 -15
- package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
- package/src/base-client/components/common/CitySelect/index.js +3 -3
- package/src/base-client/components/common/CitySelect/index.md +109 -109
- package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
- package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
- package/src/base-client/components/common/HIS/HButtons/HButtons.vue +55 -1
- package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
- package/src/base-client/components/common/HIS/HTab/HTab.vue +88 -1
- package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
- package/src/base-client/components/common/PersonSetting/index.js +3 -3
- package/src/base-client/components/common/Tree/index.js +2 -2
- package/src/base-client/components/common/Upload/index.js +3 -3
- package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
- package/src/base-client/components/common/XAddReport/XAddReport.vue +16 -1
- package/src/base-client/components/common/XCard/XCard.vue +64 -64
- package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
- package/src/base-client/components/common/XDataDrawer/index.js +3 -3
- package/src/base-client/components/common/XDataDrawer/index.md +41 -41
- package/src/base-client/components/common/XDescriptions/index.js +3 -3
- package/src/base-client/components/common/XDescriptions/index.md +382 -382
- package/src/base-client/components/common/XForm/index.md +178 -178
- package/src/base-client/components/common/XInput/XInput.vue +32 -1
- package/src/base-client/components/common/XInspectionDetailDrawer/index.vue +1 -1
- package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
- package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
- package/src/base-client/components/common/XStepView/index.js +3 -3
- package/src/base-client/components/common/XStepView/index.md +31 -31
- package/src/base-client/components/common/XTable/index.md +255 -255
- package/src/base-client/components/his/HAi/HAi.vue +1177 -436
- package/src/base-client/components/his/XList/XList.vue +337 -58
- package/src/base-client/components/his/XSidebar/XSidebar.vue +36 -12
- package/src/base-client/components/his/XTransfer/index.md +327 -327
- package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
- package/src/base-client/plugins/Config.js +19 -19
- package/src/base-client/plugins/tabs-page-plugin.js +39 -39
- package/src/components/Charts/Bar.vue +62 -62
- package/src/components/Charts/ChartCard.vue +134 -134
- package/src/components/Charts/Liquid.vue +67 -67
- package/src/components/Charts/MiniArea.vue +39 -39
- package/src/components/Charts/MiniBar.vue +39 -39
- package/src/components/Charts/MiniProgress.vue +75 -75
- package/src/components/Charts/MiniSmoothArea.vue +40 -40
- package/src/components/Charts/Radar.vue +68 -68
- package/src/components/Charts/RankList.vue +77 -77
- package/src/components/Charts/TagCloud.vue +113 -113
- package/src/components/Charts/TransferBar.vue +64 -64
- package/src/components/Charts/Trend.vue +82 -82
- package/src/components/Charts/chart.less +12 -12
- package/src/components/Charts/smooth.area.less +13 -13
- package/src/components/NumberInfo/NumberInfo.vue +54 -54
- package/src/components/NumberInfo/index.js +3 -3
- package/src/components/NumberInfo/index.less +54 -54
- package/src/components/NumberInfo/index.md +43 -43
- package/src/components/STable/index.js +953 -953
- package/src/components/card/ChartCard.vue +79 -79
- package/src/components/chart/Bar.vue +60 -60
- package/src/components/chart/MiniArea.vue +67 -67
- package/src/components/chart/MiniBar.vue +59 -59
- package/src/components/chart/MiniProgress.vue +57 -57
- package/src/components/chart/Radar.vue +80 -80
- package/src/components/chart/RankingList.vue +60 -60
- package/src/components/chart/Trend.vue +79 -79
- package/src/components/chart/index.less +9 -9
- package/src/components/checkbox/ColorCheckbox.vue +157 -157
- package/src/components/input/IInput.vue +66 -66
- package/src/components/menu/SideMenu.vue +75 -75
- package/src/components/menu/menu.js +273 -273
- package/src/components/tool/AStepItem.vue +60 -60
- package/src/layouts/CommonLayout.vue +56 -56
- package/src/lib.js +1 -1
- package/src/mock/extend/index.js +84 -84
- package/src/mock/goods/index.js +108 -108
- package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
- package/src/pages/system/dictionary/index.vue +44 -44
- package/src/pages/system/monitor/loginInfor/index.vue +37 -37
- package/src/pages/system/monitor/operLog/index.vue +37 -37
- package/src/services/api/cas.js +79 -79
- package/src/store/modules/setting.js +119 -119
- package/src/utils/errorCode.js +6 -6
- package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
- package/.idea/MarsCodeWorkspaceAppSettings.xml +0 -7
- package/.idea/google-java-format.xml +0 -6
- package/.idea/inspectionProfiles/Project_Default.xml +0 -24
- package/.idea/jsLinters/eslint.xml +0 -6
- package/.idea/vue2-client.iml +0 -12
- package/.vscode/settings.json +0 -28
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import ServiceException from '../expression/exception/ServiceException'
|
|
2
|
+
import LogicConsole from '../expression/instances/LogicConsole'
|
|
3
|
+
import ExpressionRunner from '../expression/ExpressionRunner'
|
|
4
|
+
import { getLogicConfigByNameAsync } from '@vue2-client/services/api/common'
|
|
5
|
+
import * as Plugins from './plugins/index'
|
|
6
|
+
import Expression from '../expression/core/Expression'
|
|
7
|
+
|
|
8
|
+
export default class LogicRunner {
|
|
9
|
+
static logicConsoleInstance = new LogicConsole()
|
|
10
|
+
|
|
11
|
+
// 存储正在运行的 Logic 任务,key 为 logicName,value 为 { promise, abortController, status }
|
|
12
|
+
// status: 'running' - 运行中, 'completed' - 已完成(用于ignore模式判断)
|
|
13
|
+
static runningTasks = new Map()
|
|
14
|
+
|
|
15
|
+
// 当前正在执行的请求 ID(用于区分同一 logic 的多次调用)
|
|
16
|
+
static currentRequestId = null
|
|
17
|
+
|
|
18
|
+
// 存储请求 ID 到 abortController 的映射(用于 cancel 模式)
|
|
19
|
+
static requestIdToAbortController = new Map()
|
|
20
|
+
|
|
21
|
+
// 获取当前正在运行的任务的 abortSignal(供 HttpTools 使用)
|
|
22
|
+
static getCurrentAbortSignal () {
|
|
23
|
+
// 优先使用 currentRequestId 获取对应请求实例的 abortController
|
|
24
|
+
// 这样可以确保每次请求使用自己的 abortController
|
|
25
|
+
console.log('[LogicRunner.getCurrentAbortSignal] currentRequestId:', LogicRunner.currentRequestId)
|
|
26
|
+
if (LogicRunner.currentRequestId) {
|
|
27
|
+
const controller = LogicRunner.requestIdToAbortController.get(LogicRunner.currentRequestId)
|
|
28
|
+
if (controller) {
|
|
29
|
+
const signal = controller.signal
|
|
30
|
+
console.log('[LogicRunner.getCurrentAbortSignal] 从 requestIdToAbortController 获取,aborted:', signal.aborted, 'requestId:', LogicRunner.currentRequestId)
|
|
31
|
+
return signal
|
|
32
|
+
}
|
|
33
|
+
console.log('[LogicRunner.getCurrentAbortSignal] requestIdToAbortController 中未找到 controller')
|
|
34
|
+
}
|
|
35
|
+
// 降级:从 runningTasks 获取
|
|
36
|
+
const logicName = LogicRunner.currentExecutingLogicName
|
|
37
|
+
console.log('[LogicRunner.getCurrentAbortSignal] logicName:', logicName)
|
|
38
|
+
if (!logicName) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
const task = LogicRunner.runningTasks.get(logicName)
|
|
42
|
+
console.log('[LogicRunner.getCurrentAbortSignal] task:', task)
|
|
43
|
+
if (task && task.status === 'running' && task.abortController) {
|
|
44
|
+
const signal = task.abortController.signal
|
|
45
|
+
console.log('[LogicRunner.getCurrentAbortSignal] 从 runningTasks 获取,aborted:', signal.aborted, 'logicName:', logicName)
|
|
46
|
+
return signal
|
|
47
|
+
}
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 清理请求 ID 映射
|
|
52
|
+
static clearRequestId (requestId) {
|
|
53
|
+
if (requestId) {
|
|
54
|
+
LogicRunner.requestIdToAbortController.delete(requestId)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 任务完成后保持"已完成"状态的时间(毫秒),之后自动清理
|
|
59
|
+
static COMPLETED_STATUS_TTL = 3000
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 是否存在指定名称的Logic资源
|
|
63
|
+
*
|
|
64
|
+
* @param logicName Logic名称
|
|
65
|
+
* @return 是否存在
|
|
66
|
+
*/
|
|
67
|
+
static async has (logicName) {
|
|
68
|
+
const result = await LogicRunner.getLogic(logicName, false)
|
|
69
|
+
return result != null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 执行Logic
|
|
74
|
+
*
|
|
75
|
+
* @param logicName Logic名称
|
|
76
|
+
* @param param 参数
|
|
77
|
+
* @param mode 运行模式:undefined-普通模式,'ignore'-忽略重复,'cancel'-取消前一个
|
|
78
|
+
* @return 执行结果
|
|
79
|
+
*/
|
|
80
|
+
static async run (logicName, param, mode) {
|
|
81
|
+
const taskKey = logicName
|
|
82
|
+
console.log('mode', mode)
|
|
83
|
+
// 检查已存在的任务
|
|
84
|
+
const existingTask = LogicRunner.runningTasks.get(taskKey)
|
|
85
|
+
|
|
86
|
+
// 模式1: ignore - 如果已存在运行中的任务,直接忽略当前调用
|
|
87
|
+
if (mode === 'ignore') {
|
|
88
|
+
// 如果任务正在运行中,忽略本次调用
|
|
89
|
+
if (existingTask && existingTask.status === 'running') {
|
|
90
|
+
console.log(`[LogicRunner] ${logicName} 已在运行中,忽略本次调用`)
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 模式2: cancel - 如果已存在运行中的任务,中止之前的任务
|
|
96
|
+
let oldAbortController = null
|
|
97
|
+
if (mode === 'cancel') {
|
|
98
|
+
if (existingTask && existingTask.status === 'running') {
|
|
99
|
+
console.log(`[LogicRunner] 取消 ${logicName} 的前一次运行,requestId: ${existingTask.requestId}`)
|
|
100
|
+
oldAbortController = existingTask.abortController
|
|
101
|
+
if (oldAbortController) {
|
|
102
|
+
console.log(`[LogicRunner] 执行 abort,aborted:`, oldAbortController.signal.aborted, 'old requestId:', existingTask.requestId)
|
|
103
|
+
oldAbortController.abort()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 创建唯一请求 ID,用于区分同一 logic 的多次调用
|
|
109
|
+
const requestId = `${logicName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
110
|
+
|
|
111
|
+
// 每次都创建新的 AbortController
|
|
112
|
+
// cancel 模式下:旧的 abortController 已被 abort,用于取消前一次请求
|
|
113
|
+
// 新的 abortController 用于当前请求
|
|
114
|
+
const abortController = new AbortController()
|
|
115
|
+
|
|
116
|
+
// 存储请求 ID 到 abortController 的映射
|
|
117
|
+
LogicRunner.requestIdToAbortController.set(requestId, abortController)
|
|
118
|
+
|
|
119
|
+
// 关键:先设置当前请求 ID 和 abortController,在调用 getLogic 之前就设置
|
|
120
|
+
// 这样 getLogic 发起的 HTTP 请求也能使用正确的 abortSignal
|
|
121
|
+
LogicRunner.currentExecutingLogicName = logicName
|
|
122
|
+
LogicRunner.currentRequestId = requestId
|
|
123
|
+
|
|
124
|
+
// 存储任务信息,设置状态为运行中
|
|
125
|
+
LogicRunner.runningTasks.set(taskKey, { promise: null, abortController, status: 'running', requestId })
|
|
126
|
+
|
|
127
|
+
const taskPromise = LogicRunner.executeLogic(logicName, param, abortController, requestId)
|
|
128
|
+
|
|
129
|
+
// 更新 promise 引用
|
|
130
|
+
const currentTask = LogicRunner.runningTasks.get(taskKey)
|
|
131
|
+
if (currentTask) {
|
|
132
|
+
currentTask.promise = taskPromise
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const result = await taskPromise
|
|
137
|
+
return result
|
|
138
|
+
} finally {
|
|
139
|
+
// 清理请求 ID 映射
|
|
140
|
+
LogicRunner.clearRequestId(requestId)
|
|
141
|
+
|
|
142
|
+
// 任务完成后更新状态为已完成,而不是直接删除
|
|
143
|
+
const currentTask = LogicRunner.runningTasks.get(taskKey)
|
|
144
|
+
if (currentTask && currentTask.promise === taskPromise) {
|
|
145
|
+
currentTask.status = 'completed'
|
|
146
|
+
|
|
147
|
+
// 延迟删除任务,让 ignore 模式可以检测到"刚完成"的状态
|
|
148
|
+
setTimeout(() => {
|
|
149
|
+
const task = LogicRunner.runningTasks.get(taskKey)
|
|
150
|
+
if (task && task.status === 'completed') {
|
|
151
|
+
LogicRunner.runningTasks.delete(taskKey)
|
|
152
|
+
}
|
|
153
|
+
}, LogicRunner.COMPLETED_STATUS_TTL)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 实际执行 Logic 的内部方法
|
|
160
|
+
*/
|
|
161
|
+
static async executeLogic (logicName, param, abortController, requestId) {
|
|
162
|
+
// 设置当前正在执行的 logicName 和请求 ID
|
|
163
|
+
// 注意:不设置 currentTaskAbortController,让 getCurrentAbortSignal 从 requestIdToAbortController 获取
|
|
164
|
+
LogicRunner.currentExecutingLogicName = logicName
|
|
165
|
+
LogicRunner.currentRequestId = requestId
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
// 获取Logic资源(传 shouldParseConfig: false,不触发服务端解析)
|
|
169
|
+
const result = await LogicRunner.getLogic(logicName, false)
|
|
170
|
+
if (!result || !result.source) {
|
|
171
|
+
throw new ServiceException('Logic资源' + logicName + '未找到', 400)
|
|
172
|
+
}
|
|
173
|
+
// 预处理 source:移除换行符,将换行替换为分号,避免解析器报错
|
|
174
|
+
const source = result.source.replace(/[\r\n]+/g, '')
|
|
175
|
+
const paramStr = Expression.toJSONString(param)
|
|
176
|
+
const logicLog = LogicConsole.createLogger('logic.' + logicName)
|
|
177
|
+
logicLog.info(`执行Logic[${logicName}],params: ${paramStr}`)
|
|
178
|
+
// 附加用户注册的对象到业务逻辑中
|
|
179
|
+
const plugins = {}
|
|
180
|
+
plugins.data = param
|
|
181
|
+
plugins.log = logicLog
|
|
182
|
+
plugins.ENV = result.$globalProp
|
|
183
|
+
plugins.logic = this
|
|
184
|
+
|
|
185
|
+
// 注入 abortSignal 到 plugins,用于支持取消操作
|
|
186
|
+
console.log('[LogicRunner.executeLogic] 设置 abortSignal:', abortController.signal)
|
|
187
|
+
plugins.abortSignal = abortController.signal
|
|
188
|
+
|
|
189
|
+
Object.assign(plugins, Plugins.default)
|
|
190
|
+
|
|
191
|
+
return await LogicRunner.runExpression(source, plugins)
|
|
192
|
+
} finally {
|
|
193
|
+
// 不在这里清理状态,让 run() 方法的 finally 块统一管理
|
|
194
|
+
// 这样可以确保在 cancel 模式下,第二次请求能够获取到正确的 abortSignal
|
|
195
|
+
// 状态会在 run() 方法的 finally 中统一清理
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 执行原生表达式
|
|
201
|
+
*
|
|
202
|
+
* @param source 表达式内容
|
|
203
|
+
* @param params 参数
|
|
204
|
+
* @return 执行结果
|
|
205
|
+
*/
|
|
206
|
+
static async runExpression (source, params) {
|
|
207
|
+
return await ExpressionRunner.run(source, params)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
static async getLogic (logicName, isDev) {
|
|
211
|
+
return await getLogicConfigByNameAsync(logicName, undefined, isDev)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import ServiceException from '../expression/exception/ServiceException'
|
|
2
|
+
import LogicConsole from '../expression/instances/LogicConsole'
|
|
3
|
+
import ExpressionRunner from '../expression/ExpressionRunner'
|
|
4
|
+
import { getLogicConfigByNameAsync } from '@vue2-client/services/api/common'
|
|
5
|
+
import * as Plugins from './plugins/index'
|
|
6
|
+
import Expression from '../expression/core/Expression'
|
|
7
|
+
|
|
8
|
+
export default class LogicRunner {
|
|
9
|
+
static logicConsoleInstance = new LogicConsole()
|
|
10
|
+
|
|
11
|
+
// 存储正在运行的 Logic 任务,key 为 logicName,value 为 { promise, abortController, status }
|
|
12
|
+
// status: 'running' - 运行中, 'completed' - 已完成(用于ignore模式判断)
|
|
13
|
+
static runningTasks = new Map()
|
|
14
|
+
|
|
15
|
+
// 当前正在执行的请求 ID(用于区分同一 logic 的多次调用)
|
|
16
|
+
static currentRequestId = null
|
|
17
|
+
|
|
18
|
+
// 存储请求 ID 到 abortController 的映射(用于 cancel 模式)
|
|
19
|
+
static requestIdToAbortController = new Map()
|
|
20
|
+
|
|
21
|
+
// 获取当前正在运行的任务的 abortSignal(供 HttpTools 使用)
|
|
22
|
+
static getCurrentAbortSignal () {
|
|
23
|
+
// 优先使用 currentRequestId 获取对应请求实例的 abortController
|
|
24
|
+
// 这样可以确保每次请求使用自己的 abortController
|
|
25
|
+
console.log('[LogicRunner.getCurrentAbortSignal] currentRequestId:', LogicRunner.currentRequestId)
|
|
26
|
+
if (LogicRunner.currentRequestId) {
|
|
27
|
+
const controller = LogicRunner.requestIdToAbortController.get(LogicRunner.currentRequestId)
|
|
28
|
+
if (controller) {
|
|
29
|
+
const signal = controller.signal
|
|
30
|
+
console.log('[LogicRunner.getCurrentAbortSignal] 从 requestIdToAbortController 获取,aborted:', signal.aborted, 'requestId:', LogicRunner.currentRequestId)
|
|
31
|
+
return signal
|
|
32
|
+
}
|
|
33
|
+
console.log('[LogicRunner.getCurrentAbortSignal] requestIdToAbortController 中未找到 controller')
|
|
34
|
+
}
|
|
35
|
+
// 降级:从 runningTasks 获取
|
|
36
|
+
const logicName = LogicRunner.currentExecutingLogicName
|
|
37
|
+
console.log('[LogicRunner.getCurrentAbortSignal] logicName:', logicName)
|
|
38
|
+
if (!logicName) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
const task = LogicRunner.runningTasks.get(logicName)
|
|
42
|
+
console.log('[LogicRunner.getCurrentAbortSignal] task:', task)
|
|
43
|
+
if (task && task.status === 'running' && task.abortController) {
|
|
44
|
+
const signal = task.abortController.signal
|
|
45
|
+
console.log('[LogicRunner.getCurrentAbortSignal] 从 runningTasks 获取,aborted:', signal.aborted, 'logicName:', logicName)
|
|
46
|
+
return signal
|
|
47
|
+
}
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 清理请求 ID 映射
|
|
52
|
+
static clearRequestId (requestId) {
|
|
53
|
+
if (requestId) {
|
|
54
|
+
LogicRunner.requestIdToAbortController.delete(requestId)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 任务完成后保持"已完成"状态的时间(毫秒),之后自动清理
|
|
59
|
+
static COMPLETED_STATUS_TTL = 3000
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 是否存在指定名称的Logic资源
|
|
63
|
+
*
|
|
64
|
+
* @param logicName Logic名称
|
|
65
|
+
* @return 是否存在
|
|
66
|
+
*/
|
|
67
|
+
static async has (logicName) {
|
|
68
|
+
const result = await LogicRunner.getLogic(logicName, false)
|
|
69
|
+
return result != null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 执行Logic
|
|
74
|
+
*
|
|
75
|
+
* @param logicName Logic名称
|
|
76
|
+
* @param param 参数
|
|
77
|
+
* @param mode 运行模式:undefined-普通模式,'ignore'-忽略重复,'cancel'-取消前一个
|
|
78
|
+
* @return 执行结果
|
|
79
|
+
*/
|
|
80
|
+
static async run (logicName, param, mode) {
|
|
81
|
+
const taskKey = logicName
|
|
82
|
+
console.log('mode', mode)
|
|
83
|
+
// 检查已存在的任务
|
|
84
|
+
const existingTask = LogicRunner.runningTasks.get(taskKey)
|
|
85
|
+
|
|
86
|
+
// 模式1: ignore - 如果已存在运行中的任务,直接忽略当前调用
|
|
87
|
+
if (mode === 'ignore') {
|
|
88
|
+
// 如果任务正在运行中,忽略本次调用
|
|
89
|
+
if (existingTask && existingTask.status === 'running') {
|
|
90
|
+
console.log(`[LogicRunner] ${logicName} 已在运行中,忽略本次调用`)
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 模式2: cancel - 如果已存在运行中的任务,中止之前的任务
|
|
96
|
+
let oldAbortController = null
|
|
97
|
+
if (mode === 'cancel') {
|
|
98
|
+
if (existingTask && existingTask.status === 'running') {
|
|
99
|
+
console.log(`[LogicRunner] 取消 ${logicName} 的前一次运行,requestId: ${existingTask.requestId}`)
|
|
100
|
+
oldAbortController = existingTask.abortController
|
|
101
|
+
if (oldAbortController) {
|
|
102
|
+
console.log(`[LogicRunner] 执行 abort,aborted:`, oldAbortController.signal.aborted, 'old requestId:', existingTask.requestId)
|
|
103
|
+
oldAbortController.abort()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 创建唯一请求 ID,用于区分同一 logic 的多次调用
|
|
109
|
+
const requestId = `${logicName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
|
|
110
|
+
|
|
111
|
+
// 每次都创建新的 AbortController
|
|
112
|
+
// cancel 模式下:旧的 abortController 已被 abort,用于取消前一次请求
|
|
113
|
+
// 新的 abortController 用于当前请求
|
|
114
|
+
const abortController = new AbortController()
|
|
115
|
+
|
|
116
|
+
// 存储请求 ID 到 abortController 的映射
|
|
117
|
+
LogicRunner.requestIdToAbortController.set(requestId, abortController)
|
|
118
|
+
|
|
119
|
+
// 关键:先设置当前请求 ID 和 abortController,在调用 getLogic 之前就设置
|
|
120
|
+
// 这样 getLogic 发起的 HTTP 请求也能使用正确的 abortSignal
|
|
121
|
+
LogicRunner.currentExecutingLogicName = logicName
|
|
122
|
+
LogicRunner.currentRequestId = requestId
|
|
123
|
+
|
|
124
|
+
// 存储任务信息,设置状态为运行中
|
|
125
|
+
LogicRunner.runningTasks.set(taskKey, { promise: null, abortController, status: 'running', requestId })
|
|
126
|
+
|
|
127
|
+
const taskPromise = LogicRunner.executeLogic(logicName, param, abortController, requestId)
|
|
128
|
+
|
|
129
|
+
// 更新 promise 引用
|
|
130
|
+
const currentTask = LogicRunner.runningTasks.get(taskKey)
|
|
131
|
+
if (currentTask) {
|
|
132
|
+
currentTask.promise = taskPromise
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const result = await taskPromise
|
|
137
|
+
return result
|
|
138
|
+
} finally {
|
|
139
|
+
// 清理请求 ID 映射
|
|
140
|
+
LogicRunner.clearRequestId(requestId)
|
|
141
|
+
|
|
142
|
+
// 任务完成后更新状态为已完成,而不是直接删除
|
|
143
|
+
const currentTask = LogicRunner.runningTasks.get(taskKey)
|
|
144
|
+
if (currentTask && currentTask.promise === taskPromise) {
|
|
145
|
+
currentTask.status = 'completed'
|
|
146
|
+
|
|
147
|
+
// 延迟删除任务,让 ignore 模式可以检测到"刚完成"的状态
|
|
148
|
+
setTimeout(() => {
|
|
149
|
+
const task = LogicRunner.runningTasks.get(taskKey)
|
|
150
|
+
if (task && task.status === 'completed') {
|
|
151
|
+
LogicRunner.runningTasks.delete(taskKey)
|
|
152
|
+
}
|
|
153
|
+
}, LogicRunner.COMPLETED_STATUS_TTL)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 实际执行 Logic 的内部方法
|
|
160
|
+
*/
|
|
161
|
+
static async executeLogic (logicName, param, abortController, requestId) {
|
|
162
|
+
// 设置当前正在执行的 logicName 和请求 ID
|
|
163
|
+
// 注意:不设置 currentTaskAbortController,让 getCurrentAbortSignal 从 requestIdToAbortController 获取
|
|
164
|
+
LogicRunner.currentExecutingLogicName = logicName
|
|
165
|
+
LogicRunner.currentRequestId = requestId
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
// 获取Logic资源(传 shouldParseConfig: false,不触发服务端解析)
|
|
169
|
+
const result = await LogicRunner.getLogic(logicName, false)
|
|
170
|
+
if (!result || !result.source) {
|
|
171
|
+
throw new ServiceException('Logic资源' + logicName + '未找到', 400)
|
|
172
|
+
}
|
|
173
|
+
// 预处理 source:移除换行符,将换行替换为分号,避免解析器报错
|
|
174
|
+
const source = result.source.replace(/[\r\n]+/g, '')
|
|
175
|
+
const paramStr = Expression.toJSONString(param)
|
|
176
|
+
const logicLog = LogicConsole.createLogger('logic.' + logicName)
|
|
177
|
+
logicLog.info(`执行Logic[${logicName}],params: ${paramStr}`)
|
|
178
|
+
// 附加用户注册的对象到业务逻辑中
|
|
179
|
+
const plugins = {}
|
|
180
|
+
plugins.data = param
|
|
181
|
+
plugins.log = logicLog
|
|
182
|
+
plugins.ENV = result.$globalProp
|
|
183
|
+
plugins.logic = this
|
|
184
|
+
|
|
185
|
+
// 注入 abortSignal 到 plugins,用于支持取消操作
|
|
186
|
+
console.log('[LogicRunner.executeLogic] 设置 abortSignal:', abortController.signal)
|
|
187
|
+
plugins.abortSignal = abortController.signal
|
|
188
|
+
|
|
189
|
+
Object.assign(plugins, Plugins.default)
|
|
190
|
+
|
|
191
|
+
return await LogicRunner.runExpression(source, plugins)
|
|
192
|
+
} finally {
|
|
193
|
+
// 不在这里清理状态,让 run() 方法的 finally 块统一管理
|
|
194
|
+
// 这样可以确保在 cancel 模式下,第二次请求能够获取到正确的 abortSignal
|
|
195
|
+
// 状态会在 run() 方法的 finally 中统一清理
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 执行原生表达式
|
|
201
|
+
*
|
|
202
|
+
* @param source 表达式内容
|
|
203
|
+
* @param params 参数
|
|
204
|
+
* @return 执行结果
|
|
205
|
+
*/
|
|
206
|
+
static async runExpression (source, params) {
|
|
207
|
+
return await ExpressionRunner.run(source, params)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
static async getLogic (logicName, isDev) {
|
|
211
|
+
return await getLogicConfigByNameAsync(logicName, undefined, isDev)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日期工具类
|
|
3
|
+
*/
|
|
4
|
+
export default class DateTools {
|
|
5
|
+
static instance = new DateTools()
|
|
6
|
+
static currentAbortSignal = null
|
|
7
|
+
|
|
8
|
+
constructor () {
|
|
9
|
+
if (DateTools.instance) {
|
|
10
|
+
return DateTools.instance
|
|
11
|
+
}
|
|
12
|
+
DateTools.instance = this
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static getInstance () {
|
|
16
|
+
if (!DateTools.instance) {
|
|
17
|
+
DateTools.instance = new DateTools()
|
|
18
|
+
}
|
|
19
|
+
return DateTools.instance
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 设置当前执行的 abortSignal
|
|
24
|
+
*/
|
|
25
|
+
static setAbortSignal (signal) {
|
|
26
|
+
DateTools.currentAbortSignal = signal
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 获取当前时间
|
|
31
|
+
* @returns {string} yyyy-MM-dd HH:mm:ss
|
|
32
|
+
*/
|
|
33
|
+
getNow2 () {
|
|
34
|
+
const now = new Date()
|
|
35
|
+
const year = now.getFullYear()
|
|
36
|
+
const month = String(now.getMonth() + 1).padStart(2, '0') // 月份从 0 开始,所以要 +1
|
|
37
|
+
const day = String(now.getDate()).padStart(2, '0')
|
|
38
|
+
const hours = String(now.getHours()).padStart(2, '0')
|
|
39
|
+
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|
40
|
+
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|
41
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 延迟指定毫秒(支持自动取消)
|
|
46
|
+
* @param {number} ms 延迟毫秒数
|
|
47
|
+
* @returns {Promise}
|
|
48
|
+
*/
|
|
49
|
+
delay (ms) {
|
|
50
|
+
const abortSignal = DateTools.currentAbortSignal
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const timer = setTimeout(resolve, ms)
|
|
53
|
+
if (abortSignal) {
|
|
54
|
+
abortSignal.addEventListener('abort', () => {
|
|
55
|
+
clearTimeout(timer)
|
|
56
|
+
reject(new Error('Delay aborted'))
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日期工具类
|
|
3
|
+
*/
|
|
4
|
+
export default class DateTools {
|
|
5
|
+
static instance = new DateTools()
|
|
6
|
+
|
|
7
|
+
constructor () {
|
|
8
|
+
if (DateTools.instance) {
|
|
9
|
+
return DateTools.instance
|
|
10
|
+
}
|
|
11
|
+
DateTools.instance = this
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getInstance () {
|
|
15
|
+
if (!DateTools.instance) {
|
|
16
|
+
DateTools.instance = new DateTools()
|
|
17
|
+
}
|
|
18
|
+
return DateTools.instance
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 获取当前时间
|
|
23
|
+
* @returns {string} yyyy-MM-dd HH:mm:ss
|
|
24
|
+
*/
|
|
25
|
+
getNow2 () {
|
|
26
|
+
const now = new Date()
|
|
27
|
+
const year = now.getFullYear()
|
|
28
|
+
const month = String(now.getMonth() + 1).padStart(2, '0') // 月份从 0 开始,所以要 +1
|
|
29
|
+
const day = String(now.getDate()).padStart(2, '0')
|
|
30
|
+
const hours = String(now.getHours()).padStart(2, '0')
|
|
31
|
+
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|
32
|
+
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|
33
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 延迟指定毫秒
|
|
38
|
+
* @param {number} ms 延迟毫秒数
|
|
39
|
+
* @returns {Promise}
|
|
40
|
+
*/
|
|
41
|
+
delay (ms) {
|
|
42
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日期工具类
|
|
3
|
+
*/
|
|
4
|
+
export default class DateTools {
|
|
5
|
+
static instance = new DateTools()
|
|
6
|
+
|
|
7
|
+
constructor () {
|
|
8
|
+
if (DateTools.instance) {
|
|
9
|
+
return DateTools.instance
|
|
10
|
+
}
|
|
11
|
+
DateTools.instance = this
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getInstance () {
|
|
15
|
+
if (!DateTools.instance) {
|
|
16
|
+
DateTools.instance = new DateTools()
|
|
17
|
+
}
|
|
18
|
+
return DateTools.instance
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 获取当前时间
|
|
23
|
+
* @returns {string} yyyy-MM-dd HH:mm:ss
|
|
24
|
+
*/
|
|
25
|
+
getNow2 () {
|
|
26
|
+
const now = new Date()
|
|
27
|
+
const year = now.getFullYear()
|
|
28
|
+
const month = String(now.getMonth() + 1).padStart(2, '0') // 月份从 0 开始,所以要 +1
|
|
29
|
+
const day = String(now.getDate()).padStart(2, '0')
|
|
30
|
+
const hours = String(now.getHours()).padStart(2, '0')
|
|
31
|
+
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|
32
|
+
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|
33
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 延迟指定毫秒
|
|
38
|
+
* @param {number} ms 延迟毫秒数
|
|
39
|
+
* @returns {Promise}
|
|
40
|
+
*/
|
|
41
|
+
delay (ms) {
|
|
42
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前端 Logic 用 HTTP 请求插件。
|
|
3
|
+
* 提供 post、get 方法,均返回 Promise,供表达式执行器在调用处自动等待。
|
|
4
|
+
* 使用项目统一的 request/restTools,走 axios 拦截器与认证。
|
|
5
|
+
*/
|
|
6
|
+
import { post as postRequest, get as getRequest } from '@vue2-client/services/api/restTools'
|
|
7
|
+
|
|
8
|
+
export default class HttpTools {
|
|
9
|
+
static instance
|
|
10
|
+
static currentDelegate = null
|
|
11
|
+
|
|
12
|
+
constructor () {
|
|
13
|
+
if (HttpTools.instance) {
|
|
14
|
+
return HttpTools.instance
|
|
15
|
+
}
|
|
16
|
+
HttpTools.instance = this
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static getInstance () {
|
|
20
|
+
if (!HttpTools.instance) {
|
|
21
|
+
HttpTools.instance = new HttpTools()
|
|
22
|
+
}
|
|
23
|
+
return HttpTools.instance
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* POST 请求,返回 Promise<响应体>(即 response.data)
|
|
28
|
+
* @param {string} url 请求地址,如 '/hai-api/suggest-by-complaint' 或 '/api/af-his/logic/xxx'
|
|
29
|
+
* @param {Object} body 请求体(JSON),会作为 request body 发送
|
|
30
|
+
* @param {Object} [config] 可选,axios 配置,如 { dedupe: false }
|
|
31
|
+
* @param {AbortSignal} [config.abortSignal] 可选的 abortSignal(从 plugins 传入)
|
|
32
|
+
* @returns {Promise<*>} 解析为响应体(通常为 JSON 对象)
|
|
33
|
+
*/
|
|
34
|
+
post (url, body, config) {
|
|
35
|
+
// 从 delegate 获取 abortSignal
|
|
36
|
+
let abortSignal = config?.abortSignal
|
|
37
|
+
if (!abortSignal && HttpTools.currentDelegate) {
|
|
38
|
+
abortSignal = HttpTools.currentDelegate.get('abortSignal')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log('[HttpTools.post] abortSignal:', abortSignal, 'aborted:', abortSignal?.aborted)
|
|
42
|
+
|
|
43
|
+
// 如果已经 abort 了,直接抛出错误
|
|
44
|
+
if (abortSignal?.aborted) {
|
|
45
|
+
const error = new Error('请求已被取消')
|
|
46
|
+
error.name = 'AbortError'
|
|
47
|
+
return Promise.reject(error)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const options = { ...config }
|
|
51
|
+
delete options.abortSignal
|
|
52
|
+
|
|
53
|
+
if (abortSignal) {
|
|
54
|
+
options.signal = abortSignal
|
|
55
|
+
}
|
|
56
|
+
return postRequest(url, body || {}, options)
|
|
57
|
+
.then(res => res && res.data !== undefined ? res.data : res)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* GET 请求,返回 Promise<响应体>(即 response.data)
|
|
62
|
+
* @param {string} url 请求地址
|
|
63
|
+
* @param {Object} [params] 查询参数
|
|
64
|
+
* @param {Object} [config] 可选,axios 配置
|
|
65
|
+
* @param {AbortSignal} [config.abortSignal] 可选的 abortSignal(从 plugins 传入)
|
|
66
|
+
* @returns {Promise<*>} 解析为响应体
|
|
67
|
+
*/
|
|
68
|
+
get (url, params, config) {
|
|
69
|
+
const options = { ...config }
|
|
70
|
+
const abortSignal = options.abortSignal
|
|
71
|
+
|
|
72
|
+
delete options.abortSignal
|
|
73
|
+
|
|
74
|
+
if (abortSignal) {
|
|
75
|
+
options.signal = abortSignal
|
|
76
|
+
}
|
|
77
|
+
return getRequest(url, params, options)
|
|
78
|
+
.then(res => res && res.data !== undefined ? res.data : res)
|
|
79
|
+
}
|
|
80
|
+
}
|