vue2-client 1.16.31 → 1.16.33
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/.env.message +19 -19
- package/package.json +112 -112
- package/src/base-client/components/common/XFormTable/demo.vue +52 -90
- package/src/base-client/components/common/XReport/print.js +186 -186
- package/src/base-client/components/common/XTable/README.md +243 -0
- package/src/base-client/components/common/XTable/XTable.vue +1608 -1607
- package/src/base-client/components/common/XTable/XTableWrapper.vue +35 -2
- package/src/base-client/components/common/XWebSocketProgress/README.md +14 -0
- package/src/base-client/components/common/XWebSocketProgress/index.vue +252 -0
- package/src/base-client/components/his/XHisEditor/XHisEditor.vue +12 -1
- package/src/base-client/components/his/threeTestOrders/editor.vue +2 -0
- package/src/utils/map-utils.js +47 -47
- package/src/utils/websocket/README.md +224 -0
- package/src/utils/websocket/websocket.js +241 -0
- package/vue.config.js +6 -0
@@ -211,7 +211,16 @@
|
|
211
211
|
<ellipsis :length="item.slotValue" tooltip>{{ text === '' ? '--' : text }}</ellipsis>
|
212
212
|
</span>
|
213
213
|
<span v-else-if="item.slotType === 'progress'" :key="'progress-' + c_index">
|
214
|
-
|
214
|
+
<!-- websocket-id (配置名称-字段名称-用户id-页码-数据行id) -->
|
215
|
+
<x-web-socket-progress
|
216
|
+
v-if="item.webSocket"
|
217
|
+
:key="`${tableContext.requestParameters?.pageNo || 1}-${item.dataIndex}-${record[tableContext.rowKey] || index}`"
|
218
|
+
:websocket-id="`${queryParamsName}-${item.dataIndex}-${currUser.id}-${tableContext.requestParameters?.pageNo || 1}-${record[tableContext.rowKey] || index}`"
|
219
|
+
:initial-value="text || 0"
|
220
|
+
@progress-updated="(data) => handleProgressUpdated(data, record, item.dataIndex)"
|
221
|
+
/>
|
222
|
+
<!-- 表格进度组件 -->
|
223
|
+
<a-progress v-else :percent="text" status="active" style="padding-right: 20px;" />
|
215
224
|
</span>
|
216
225
|
<span v-else-if="item.slotType === 'badge'" :key="'badge-' + c_index">
|
217
226
|
<x-badge
|
@@ -277,7 +286,9 @@ import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormIte
|
|
277
286
|
import CustomFuncCel from '@vue2-client/base-client/components/common/XTable/CustomFuncCel.vue'
|
278
287
|
import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
|
279
288
|
import XRate from '@vue2-client/base-client/components/common/XRate/index.vue'
|
289
|
+
import XWebSocketProgress from '@vue2-client/base-client/components/common/XWebSocketProgress'
|
280
290
|
import VueDraggableResizable from 'vue-draggable-resizable'
|
291
|
+
import { mapState } from 'vuex'
|
281
292
|
|
282
293
|
export default {
|
283
294
|
name: 'XTableWrapper',
|
@@ -288,6 +299,7 @@ export default {
|
|
288
299
|
XFormItem,
|
289
300
|
XRate,
|
290
301
|
CustomFuncCel,
|
302
|
+
XWebSocketProgress,
|
291
303
|
VueDraggableResizable
|
292
304
|
},
|
293
305
|
data () {
|
@@ -298,6 +310,7 @@ export default {
|
|
298
310
|
}
|
299
311
|
},
|
300
312
|
computed: {
|
313
|
+
...mapState('account', { currUser: 'user' }),
|
301
314
|
localDataSource () {
|
302
315
|
return this.activeTable?.localDataSource
|
303
316
|
},
|
@@ -426,6 +439,13 @@ export default {
|
|
426
439
|
}
|
427
440
|
},
|
428
441
|
props: {
|
442
|
+
// 查询配置文件名
|
443
|
+
queryParamsName: {
|
444
|
+
type: String,
|
445
|
+
default: () => {
|
446
|
+
return ''
|
447
|
+
}
|
448
|
+
},
|
429
449
|
loadSelectedData: {
|
430
450
|
type: Boolean,
|
431
451
|
required: false,
|
@@ -547,7 +567,20 @@ export default {
|
|
547
567
|
},
|
548
568
|
handleResizeColumn (w, col) {
|
549
569
|
col.width = w
|
550
|
-
}
|
570
|
+
},
|
571
|
+
|
572
|
+
/**
|
573
|
+
* 处理进度更新事件
|
574
|
+
* @param {Object} data 进度数据
|
575
|
+
* @param {Object} record 行数据
|
576
|
+
* @param {String} dataIndex 列字段名
|
577
|
+
*/
|
578
|
+
handleProgressUpdated (data, record, dataIndex) {
|
579
|
+
// 更新行数据中的进度值
|
580
|
+
if (record && dataIndex) {
|
581
|
+
this.$set(record, dataIndex, data.value)
|
582
|
+
}
|
583
|
+
},
|
551
584
|
}
|
552
585
|
}
|
553
586
|
</script>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
发生sendMessage请求
|
2
|
+
```json
|
3
|
+
{
|
4
|
+
"event": "16", // 进度数据, 取值 0~100
|
5
|
+
"userList": [
|
6
|
+
"ceshiCRUD-t_f_operator_id-419879409793761282-1-18",// 数据webSocket 唯一标识 (配置名称-字段名称-用户id-页码-数据行id)
|
7
|
+
"ceshiCRUD-t_f_type-419879409793761282-1-18",
|
8
|
+
"ceshiCRUD-t_f_type-419879409793761282-1-19",
|
9
|
+
"ceshiCRUD-t_f_type-419879409793761282-1-20",
|
10
|
+
"ceshiCRUD-t_f_operator_id-419879409793761282-1-21",
|
11
|
+
"ceshiCRUD-t_f_operator_id-419879409793761282-1-22"
|
12
|
+
]
|
13
|
+
}
|
14
|
+
```
|
@@ -0,0 +1,252 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="websocket-progress">
|
3
|
+
<a-progress
|
4
|
+
:percent="progressValue"
|
5
|
+
status="active"
|
6
|
+
style="padding-right: 20px;" />
|
7
|
+
|
8
|
+
<!-- 连接状态指示 -->
|
9
|
+
<div class="connection-status">
|
10
|
+
<a-tooltip :title="connectionStatusText">
|
11
|
+
<a-badge
|
12
|
+
:status="connectionBadgeStatus"
|
13
|
+
:text="connectionStatusText"
|
14
|
+
/>
|
15
|
+
</a-tooltip>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</template>
|
19
|
+
|
20
|
+
<script>
|
21
|
+
import { useWebSocket } from '@vue2-client/utils/websocket/websocket'
|
22
|
+
|
23
|
+
export default {
|
24
|
+
name: 'XWebSocketProgress',
|
25
|
+
components: {
|
26
|
+
},
|
27
|
+
props: {
|
28
|
+
// WebSocket 唯一标识
|
29
|
+
websocketId: {
|
30
|
+
type: String,
|
31
|
+
required: true,
|
32
|
+
},
|
33
|
+
// 初始进度值
|
34
|
+
initialValue: {
|
35
|
+
type: Number,
|
36
|
+
default: 0
|
37
|
+
},
|
38
|
+
// 自动重连
|
39
|
+
autoReconnect: {
|
40
|
+
type: Boolean,
|
41
|
+
default: true
|
42
|
+
},
|
43
|
+
// 重连间隔(毫秒)
|
44
|
+
reconnectInterval: {
|
45
|
+
type: Number,
|
46
|
+
default: 3000
|
47
|
+
},
|
48
|
+
// 最大重连次数
|
49
|
+
maxReconnectAttempts: {
|
50
|
+
type: Number,
|
51
|
+
default: 1
|
52
|
+
},
|
53
|
+
},
|
54
|
+
data () {
|
55
|
+
return {
|
56
|
+
progressValue: this.initialValue,
|
57
|
+
connectionState: {
|
58
|
+
isConnected: false,
|
59
|
+
reconnectAttempts: 0
|
60
|
+
},
|
61
|
+
websocketUrl: '',
|
62
|
+
}
|
63
|
+
},
|
64
|
+
computed: {
|
65
|
+
// 连接状态文本
|
66
|
+
connectionStatusText () {
|
67
|
+
if (this.connectionState.isConnected) {
|
68
|
+
return '已连接'
|
69
|
+
} else if (this.connectionState.reconnectAttempts > 0) {
|
70
|
+
return `重连中 (${this.connectionState.reconnectAttempts})`
|
71
|
+
} else {
|
72
|
+
return '未连接'
|
73
|
+
}
|
74
|
+
},
|
75
|
+
|
76
|
+
// 连接状态徽章状态
|
77
|
+
connectionBadgeStatus () {
|
78
|
+
if (this.connectionState.isConnected) {
|
79
|
+
return 'success'
|
80
|
+
} else if (this.connectionState.reconnectAttempts > 0) {
|
81
|
+
return 'processing'
|
82
|
+
} else {
|
83
|
+
return 'default'
|
84
|
+
}
|
85
|
+
}
|
86
|
+
},
|
87
|
+
mounted () {
|
88
|
+
this.initWebSocket()
|
89
|
+
},
|
90
|
+
beforeDestroy () {
|
91
|
+
this.cleanup()
|
92
|
+
},
|
93
|
+
watch: {
|
94
|
+
// 初始值变更时重置当前进度显示
|
95
|
+
initialValue (val) {
|
96
|
+
const num = parseFloat(val)
|
97
|
+
this.progressValue = isNaN(num) ? 0 : Math.max(0, Math.min(100, num))
|
98
|
+
},
|
99
|
+
// 标识变更时,断开旧连接并按新标识重连
|
100
|
+
websocketId (newId, oldId) {
|
101
|
+
if (newId === oldId) return
|
102
|
+
this.cleanup()
|
103
|
+
// 重置进度为新的初始值,确保界面先渲染初始值
|
104
|
+
const num = parseFloat(this.initialValue)
|
105
|
+
this.progressValue = isNaN(num) ? 0 : Math.max(0, Math.min(100, num))
|
106
|
+
// 重新建立连接
|
107
|
+
this.$nextTick(() => {
|
108
|
+
this.initWebSocket()
|
109
|
+
})
|
110
|
+
}
|
111
|
+
},
|
112
|
+
methods: {
|
113
|
+
/**
|
114
|
+
* 初始化 WebSocket
|
115
|
+
*/
|
116
|
+
initWebSocket () {
|
117
|
+
if (!this.websocketId) {
|
118
|
+
return
|
119
|
+
}
|
120
|
+
|
121
|
+
this.websocketUrl = `ws:${window.location.host}/socket/af-system/sendMessage?userId=${this.websocketId}`
|
122
|
+
|
123
|
+
const wsOptions = {
|
124
|
+
autoReconnect: this.autoReconnect,
|
125
|
+
reconnectInterval: this.reconnectInterval,
|
126
|
+
maxReconnectAttempts: this.maxReconnectAttempts
|
127
|
+
}
|
128
|
+
|
129
|
+
// 使用 WebSocket 工具
|
130
|
+
const wsManager = useWebSocket(wsOptions)
|
131
|
+
|
132
|
+
// 保存方法引用
|
133
|
+
this.wsConnect = wsManager.connect
|
134
|
+
this.wsDisconnect = wsManager.disconnect
|
135
|
+
this.wsOn = wsManager.on
|
136
|
+
// 绑定事件监听器
|
137
|
+
this.setupEventListeners()
|
138
|
+
|
139
|
+
// 开始连接
|
140
|
+
this.wsConnect(this.websocketUrl, wsOptions)
|
141
|
+
},
|
142
|
+
/**
|
143
|
+
* 手动重置为初始值(供父组件可选调用)
|
144
|
+
*/
|
145
|
+
resetToInitial () {
|
146
|
+
const num = parseFloat(this.initialValue)
|
147
|
+
this.progressValue = isNaN(num) ? 0 : Math.max(0, Math.min(100, num))
|
148
|
+
},
|
149
|
+
|
150
|
+
/**
|
151
|
+
* 设置事件监听器
|
152
|
+
*/
|
153
|
+
setupEventListeners () {
|
154
|
+
// 连接成功
|
155
|
+
this.wsOn('connected', (data) => {
|
156
|
+
this.connectionState.isConnected = true
|
157
|
+
this.connectionState.reconnectAttempts = 0
|
158
|
+
this.$emit('websocket-connected', data)
|
159
|
+
})
|
160
|
+
|
161
|
+
// 连接中
|
162
|
+
this.wsOn('connecting', (data) => {
|
163
|
+
this.$emit('websocket-connecting', data)
|
164
|
+
})
|
165
|
+
|
166
|
+
// 消息接收
|
167
|
+
this.wsOn('message', (data) => {
|
168
|
+
this.handleWebSocketMessage(data)
|
169
|
+
this.$emit('websocket-message', data)
|
170
|
+
})
|
171
|
+
|
172
|
+
// 连接关闭
|
173
|
+
this.wsOn('closed', (data) => {
|
174
|
+
this.connectionState.isConnected = false
|
175
|
+
this.$emit('websocket-closed', data)
|
176
|
+
})
|
177
|
+
|
178
|
+
// 连接错误
|
179
|
+
this.wsOn('error', (data) => {
|
180
|
+
this.connectionState.isConnected = false
|
181
|
+
this.$emit('websocket-error', data)
|
182
|
+
})
|
183
|
+
|
184
|
+
// 重连中
|
185
|
+
this.wsOn('reconnecting', (data) => {
|
186
|
+
this.connectionState.reconnectAttempts = data.attempts
|
187
|
+
this.$emit('websocket-reconnecting', data)
|
188
|
+
})
|
189
|
+
|
190
|
+
// 重连失败
|
191
|
+
this.wsOn('reconnect-failed', (data) => {
|
192
|
+
this.connectionState.reconnectAttempts = data.attempts
|
193
|
+
this.$emit('websocket-reconnect-failed', data)
|
194
|
+
})
|
195
|
+
|
196
|
+
// 断开连接
|
197
|
+
this.wsOn('disconnected', (data) => {
|
198
|
+
this.connectionState.isConnected = false
|
199
|
+
this.connectionState.reconnectAttempts = 0
|
200
|
+
this.$emit('websocket-disconnected', data)
|
201
|
+
})
|
202
|
+
},
|
203
|
+
|
204
|
+
/**
|
205
|
+
* 处理 WebSocket 消息
|
206
|
+
* @param {Object} data 消息数据
|
207
|
+
*/
|
208
|
+
handleWebSocketMessage (data) {
|
209
|
+
const messageData = data.data
|
210
|
+
|
211
|
+
// 更新进度值
|
212
|
+
this.updateProgress(parseFloat(messageData))
|
213
|
+
},
|
214
|
+
|
215
|
+
/**
|
216
|
+
* 更新进度值
|
217
|
+
* @param {number} value 进度值
|
218
|
+
*/
|
219
|
+
updateProgress (value) {
|
220
|
+
const numValue = parseFloat(value)
|
221
|
+
if (!isNaN(numValue)) {
|
222
|
+
this.progressValue = Math.max(0, Math.min(100, numValue))
|
223
|
+
this.$emit('progress-updated', {
|
224
|
+
value: this.progressValue,
|
225
|
+
originalValue: value
|
226
|
+
})
|
227
|
+
}
|
228
|
+
},
|
229
|
+
|
230
|
+
/**
|
231
|
+
* 清理资源
|
232
|
+
*/
|
233
|
+
cleanup () {
|
234
|
+
if (this.wsDisconnect) {
|
235
|
+
this.wsDisconnect()
|
236
|
+
}
|
237
|
+
}
|
238
|
+
}
|
239
|
+
}
|
240
|
+
</script>
|
241
|
+
|
242
|
+
<style scoped lang="less">
|
243
|
+
.websocket-progress {
|
244
|
+
display: flex;
|
245
|
+
align-items: center;
|
246
|
+
gap: 8px;
|
247
|
+
|
248
|
+
.connection-status {
|
249
|
+
flex-shrink: 0;
|
250
|
+
}
|
251
|
+
}
|
252
|
+
</style>
|
@@ -19,6 +19,7 @@
|
|
19
19
|
<!-- </template>-->
|
20
20
|
</template>
|
21
21
|
<a-radio-group
|
22
|
+
class="custom-radio-group"
|
22
23
|
v-show="showModeChoose"
|
23
24
|
button-style="solid"
|
24
25
|
@change="changeMode"
|
@@ -29,7 +30,7 @@
|
|
29
30
|
</a-radio-group>
|
30
31
|
</a-space>
|
31
32
|
</a-col>
|
32
|
-
<a-col class="editor-action">
|
33
|
+
<a-col class="editor-action-button">
|
33
34
|
<a-space>
|
34
35
|
<template v-if="this.modeType !== 'readonly'">
|
35
36
|
<!-- <a-button-->
|
@@ -649,6 +650,11 @@ export default {
|
|
649
650
|
.editor-action-container {
|
650
651
|
height: 40px;
|
651
652
|
}
|
653
|
+
.editor-action-button {
|
654
|
+
.ant-btn-primary {
|
655
|
+
background-color: rgb(0, 87, 254) !important;
|
656
|
+
}
|
657
|
+
}
|
652
658
|
:deep(.ant-divider-horizontal) {
|
653
659
|
margin: 4px 0;
|
654
660
|
}
|
@@ -691,4 +697,9 @@ export default {
|
|
691
697
|
font-size: 12px;
|
692
698
|
margin: 0 !important;
|
693
699
|
}
|
700
|
+
.custom-radio-group {
|
701
|
+
.ant-radio-button-wrapper-checked {
|
702
|
+
background-color: rgb(0, 87, 254) !important;
|
703
|
+
}
|
704
|
+
}
|
694
705
|
</style>
|
package/src/utils/map-utils.js
CHANGED
@@ -1,47 +1,47 @@
|
|
1
|
-
import AMapLoader from '@amap/amap-jsapi-loader'
|
2
|
-
let Amap
|
3
|
-
async function GetGDMap (secretKey, key) {
|
4
|
-
if (!Amap) {
|
5
|
-
window._AMapSecurityConfig = {
|
6
|
-
securityJsCode: secretKey
|
7
|
-
}
|
8
|
-
// 解决高德地图加载报错 ---> 禁止多种API加载方式混用
|
9
|
-
AMapLoader.reset()
|
10
|
-
Amap = await AMapLoader.load({
|
11
|
-
key: key, // 申请好的Web端开发者Key,首次调用 load 时必填
|
12
|
-
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
13
|
-
plugins: ['AMap.IndexCluster', 'AMP.MarkerCluster', 'AMap.InfoWindow', 'AMap.HeatMap', 'AMap.HawkEye', 'AMap.DistrictSearch',
|
14
|
-
'AMap.ToolBar', 'AMap.Geolocation', 'AMap.MouseTool',
|
15
|
-
'AMap.Geocoder', 'AMap.MarkerClusterer', 'AMap.AutoComplete', 'AMap.Scale'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
16
|
-
AMapUI: {
|
17
|
-
version: '1.1', // AMapUI 缺省 1.1
|
18
|
-
plugins: ['misc/PositionPicker'] // 需要加载的 AMapUI ui插件
|
19
|
-
}
|
20
|
-
})
|
21
|
-
}
|
22
|
-
return Amap
|
23
|
-
}
|
24
|
-
|
25
|
-
async function getGDMap (address) {
|
26
|
-
new (await GetGDMap()).Geocoder({
|
27
|
-
radius: 500 // 范围,默认:500
|
28
|
-
}).getLocation(address, function (status, result) {
|
29
|
-
if (status === 'complete' && result.geocodes.length) {
|
30
|
-
return ({ lng: result.geocodes[0].location.lng, lat: result.geocodes[0].location.lat })
|
31
|
-
} else {
|
32
|
-
// eslint-disable-next-line prefer-promise-reject-errors
|
33
|
-
throw new Error('根据经纬度查询地址失败')
|
34
|
-
}
|
35
|
-
})
|
36
|
-
}
|
37
|
-
|
38
|
-
async function GetLocation (address) {
|
39
|
-
return new Promise((resolve, reject) => {
|
40
|
-
try {
|
41
|
-
resolve(getGDMap(address))
|
42
|
-
} catch (e) {
|
43
|
-
reject(e)
|
44
|
-
}
|
45
|
-
})
|
46
|
-
}
|
47
|
-
export { GetGDMap, GetLocation }
|
1
|
+
import AMapLoader from '@amap/amap-jsapi-loader'
|
2
|
+
let Amap
|
3
|
+
async function GetGDMap (secretKey, key) {
|
4
|
+
if (!Amap) {
|
5
|
+
window._AMapSecurityConfig = {
|
6
|
+
securityJsCode: secretKey
|
7
|
+
}
|
8
|
+
// 解决高德地图加载报错 ---> 禁止多种API加载方式混用
|
9
|
+
AMapLoader.reset()
|
10
|
+
Amap = await AMapLoader.load({
|
11
|
+
key: key, // 申请好的Web端开发者Key,首次调用 load 时必填
|
12
|
+
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
13
|
+
plugins: ['AMap.IndexCluster', 'AMP.MarkerCluster', 'AMap.InfoWindow', 'AMap.HeatMap', 'AMap.HawkEye', 'AMap.DistrictSearch',
|
14
|
+
'AMap.ToolBar', 'AMap.Geolocation', 'AMap.MouseTool',
|
15
|
+
'AMap.Geocoder', 'AMap.MarkerClusterer', 'AMap.AutoComplete', 'AMap.Scale'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
16
|
+
AMapUI: {
|
17
|
+
version: '1.1', // AMapUI 缺省 1.1
|
18
|
+
plugins: ['misc/PositionPicker'] // 需要加载的 AMapUI ui插件
|
19
|
+
}
|
20
|
+
})
|
21
|
+
}
|
22
|
+
return Amap
|
23
|
+
}
|
24
|
+
|
25
|
+
async function getGDMap (address) {
|
26
|
+
new (await GetGDMap()).Geocoder({
|
27
|
+
radius: 500 // 范围,默认:500
|
28
|
+
}).getLocation(address, function (status, result) {
|
29
|
+
if (status === 'complete' && result.geocodes.length) {
|
30
|
+
return ({ lng: result.geocodes[0].location.lng, lat: result.geocodes[0].location.lat })
|
31
|
+
} else {
|
32
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
33
|
+
throw new Error('根据经纬度查询地址失败')
|
34
|
+
}
|
35
|
+
})
|
36
|
+
}
|
37
|
+
|
38
|
+
async function GetLocation (address) {
|
39
|
+
return new Promise((resolve, reject) => {
|
40
|
+
try {
|
41
|
+
resolve(getGDMap(address))
|
42
|
+
} catch (e) {
|
43
|
+
reject(e)
|
44
|
+
}
|
45
|
+
})
|
46
|
+
}
|
47
|
+
export { GetGDMap, GetLocation }
|