vue2-client 1.2.37 → 1.2.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +103 -90
  2. package/docs/notice.md +22 -22
  3. package/package.json +1 -1
  4. package/src/base-client/all.js +2 -0
  5. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +104 -0
  6. package/src/base-client/components/common/AmapMarker/index.js +3 -0
  7. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +149 -149
  8. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +315 -315
  9. package/src/base-client/components/common/XForm/XForm.vue +275 -275
  10. package/src/base-client/components/iot/CustomerDetailsView/CustomerDetailsView.vue +225 -225
  11. package/src/base-client/components/iot/DataAnalysisView/DataAnalysisView.vue +244 -244
  12. package/src/base-client/components/iot/DeviceBrandDetailsView/DeviceBrandDetailsView.vue +452 -452
  13. package/src/base-client/components/iot/DeviceDetailsView/DeviceDetailsView.vue +8 -2
  14. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsCount.vue +330 -330
  15. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsException.vue +57 -57
  16. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsInstructOperate.vue +121 -121
  17. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsRead.vue +131 -131
  18. package/src/base-client/components/iot/DeviceTypeDetailsView/DeviceTypeDetailsView.vue +276 -276
  19. package/src/base-client/components/iot/InstructDetailsView/InstructDetailsView.vue +469 -469
  20. package/src/base-client/components/iot/LogDetailsView/LogDetailsView.vue +379 -379
  21. package/src/base-client/components/iot/MeterDetailsView/MeterDetailsView.vue +359 -359
  22. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsCount.vue +335 -335
  23. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsException.vue +184 -184
  24. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsHandPlan.vue +291 -291
  25. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsInstruct.vue +236 -236
  26. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsMain.vue +256 -256
  27. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsSellGas.vue +189 -189
  28. package/src/base-client/components/iot/WebmeterAnalysisView/WebmeterAnalysisView.vue +722 -722
  29. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +231 -231
  30. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +247 -247
  31. package/src/base-client/components/ticket/EmployeeDetailsView/EmployeeDetailsView.vue +370 -370
  32. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +3 -3
  33. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +260 -260
  34. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +532 -532
  35. package/src/base-client/plugins/AppData.js +67 -67
  36. package/src/base-client/plugins/GetLoginInfoService.js +252 -252
  37. package/src/components/exception/ExceptionPage.vue +70 -70
  38. package/src/components/setting/Setting.vue +235 -237
  39. package/src/config/default/setting.config.js +6 -5
  40. package/src/config/index.js +3 -6
  41. package/src/layouts/SinglePageView.vue +13 -17
  42. package/src/layouts/header/HeaderNotice.vue +97 -97
  43. package/src/layouts/tabs/TabsView.vue +3 -5
  44. package/src/pages/login/Login.vue +4 -1
  45. package/src/pages/report/ReportTableHome.vue +28 -28
  46. package/src/pages/resourceManage/depListManage.vue +23 -23
  47. package/src/pages/resourceManage/funListManage.vue +23 -23
  48. package/src/pages/resourceManage/index.js +15 -15
  49. package/src/pages/resourceManage/orgListManage.vue +98 -98
  50. package/src/pages/resourceManage/roleListManage.vue +23 -23
  51. package/src/pages/resourceManage/staffListManage.vue +23 -23
  52. package/src/pages/system/ticket/index.vue +456 -440
  53. package/src/pages/system/ticket/submitTicketSuccess.vue +248 -248
  54. package/src/router/async/config.async.js +26 -26
  55. package/src/router/async/router.map.js +58 -59
  56. package/src/router/index.js +27 -27
  57. package/src/services/api/common.js +47 -47
  58. package/src/services/api/index.js +39 -39
  59. package/src/services/user.js +34 -34
  60. package/src/utils/indexedDB.js +146 -146
  61. package/src/utils/routerUtil.js +359 -360
  62. package/vue.config.js +2 -2
  63. package/src/config/config.js +0 -15
@@ -1,469 +1,469 @@
1
- <template>
2
- <a-drawer
3
- title="指令详情"
4
- placement="right"
5
- :width="isMobile ? screenWidth : screenWidth * 0.85"
6
- :visible="visible"
7
- @close="onClose"
8
- >
9
- <a-spin :spinning="loadInstructDetails">
10
- <meter-details-view
11
- :visible.sync="detailVisible"
12
- :select-org-name="selectOrgName"
13
- :userid="selectUserId"
14
- v-if="selectUserId && isShowUserFiles"
15
- />
16
- <a-page-header
17
- :title="'指令:' + details.f_instruct_type"
18
- >
19
- <div class="row">
20
- <div class="content">
21
- <a-descriptions size="small" :column="isMobile ? 1 : 2">
22
- <a-descriptions-item label="指令编号" :span="isMobile ? 1 : 2">{{ details.id }}</a-descriptions-item>
23
- <a-descriptions-item label="表编号">
24
- <a v-if="isShowUserFiles" @click="openUserFilesDetails">{{ details.userid }}</a>
25
- <span v-else>{{ details.userid }}</span>
26
- </a-descriptions-item>
27
- <a-descriptions-item label="表号">{{ details.f_meternumber }}</a-descriptions-item>
28
- <a-descriptions-item label="操作人员">{{ details.f_inputtor }}</a-descriptions-item>
29
- <a-descriptions-item label="指令说明">{{ details.f_instruct_title }}</a-descriptions-item>
30
- <a-descriptions-item label="生成时间">{{ format(details.f_instruct_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
31
- <a-descriptions-item label="表厂别名">{{ details.f_alias }}</a-descriptions-item>
32
- <a-descriptions-item label="最后发送时间">{{ format(details.f_send_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
33
- <a-descriptions-item label="最后响应时间">{{ format(details.f_callback_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
34
- </a-descriptions>
35
- </div>
36
- <div class="extra">
37
- <a-row class="status-list">
38
- <a-col :xs="12" :sm="24">
39
- <div class="text">指令状态</div>
40
- <div class="heading">
41
- <x-badge :value="details.f_instruct_state" badge-key="instructStateMap" :is-external-text="true"/>
42
- </div>
43
- </a-col>
44
- </a-row>
45
- <p></p>
46
- <a-row class="status-list">
47
- <a-col :xs="12" :sm="24">
48
- <div class="text">响应结果</div>
49
- <div class="heading">{{ details.f_receive_state }}</div>
50
- </a-col>
51
- </a-row>
52
- </div>
53
- </div>
54
-
55
- <!-- actions -->
56
- <template v-slot:extra>
57
- <a-button-group style="margin-right: 4px;">
58
- <a-button type="dashed" @click="initView" :loading="loadInstructDetails">刷新</a-button>
59
- </a-button-group>
60
- <a-button-group style="margin-right: 4px;">
61
- <a-popover title="重新发送" placement="bottomLeft">
62
- <template slot="content">
63
- <p>将指令标记为待发送状态</p>
64
- <p>指令将在 定时器轮询/表具上报 后重新发送</p>
65
- <p style="color: red">此操作不可撤销</p>
66
- </template>
67
- <a-button type="primary" @click="againSend(details.id)" :disabled="againSendBtnHide()">重新发送</a-button>
68
- </a-popover>
69
- <a-popover title="取消发送" placement="bottomLeft">
70
- <template slot="content">
71
- <p>该指令将被<span style="color: red;font-weight: bold">取消</span>,请谨慎操作</p>
72
- <p>只有待发送或已发送的指令可以取消发送</p>
73
- <p style="color: red">此操作不可撤销</p>
74
- </template>
75
- <a-button type="danger" @click="cancelSend(details.id)" :disabled="cancelSendBtnHide()">取消发送</a-button>
76
- </a-popover>
77
- </a-button-group>
78
- </template>
79
-
80
- <!-- 操作 -->
81
- <a-card :bordered="false" title="指令状态">
82
- <a-steps :direction="'horizontal'" :current="step" :status="status">
83
- <a-step>
84
- <template v-slot:title><span>待发送</span></template>
85
- <template v-slot:description>
86
- <div>指令已经就绪,待发送<div>{{ format(details.f_instruct_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
87
- </template>
88
- </a-step>
89
- <a-step>
90
- <template v-slot:title><span>已发送</span></template>
91
- <template v-slot:description>
92
- <div>{{ getIntroduction() }}<div>{{ format(details.f_send_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
93
- </template>
94
- </a-step>
95
- <a-step>
96
- <template v-slot:title><span>{{ instructResult }}</span></template>
97
- <template v-slot:description>
98
- <div>{{ getResultText(instructResult) }}<div>{{ format(details.f_callback_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
99
- </template>
100
- </a-step>
101
- </a-steps>
102
- </a-card>
103
- <a-card
104
- style="margin-top: 24px"
105
- :bordered="false"
106
- :tabList="operationTabList"
107
- :activeTabKey="operationActiveTabKey"
108
- @tabChange="(key) => {this.operationActiveTabKey = key}"
109
- >
110
- <div v-if="operationActiveTabKey === '1'">
111
- <a-card type="inner" title="指令内容">
112
- <json-viewer :copyable="{copyText: '复制', copiedText: '已复制'}" :value="details.f_instruct_content === undefined ? {} : toJSON(details.f_instruct_content)"></json-viewer>
113
- </a-card>
114
- <a-card type="inner" title="指令元数据">
115
- <json-viewer :copyable="{copyText: '复制', copiedText: '已复制'}" :value="details.f_instruct_meta_data === undefined ? {} : toJSON(details.f_instruct_meta_data)"></json-viewer>
116
- </a-card>
117
- </div>
118
-
119
- <x-table
120
- v-if="loaded && operationActiveTabKey === '2'"
121
- :json-data="showColumns"
122
- :queryParamsName="queryParamsName"
123
- @loadData="loadData"
124
- :fixedQueryForm="form"
125
- />
126
- <div v-else-if="operationActiveTabKey === '3'" class="no-data"><a-icon type="frown-o"/>暂无数据</div>
127
- </a-card>
128
- </a-page-header>
129
- </a-spin>
130
- </a-drawer>
131
- </template>
132
-
133
- <script>
134
- import JsonViewer from 'vue-json-viewer'
135
- import { formatDate } from '@vue2-client/utils/util'
136
- import { InstructDetailsViewApi, post, query, commonApi } from '@vue2-client/services/api'
137
- import XTable from '@vue2-client/base-client/components/common/XTable/XTable'
138
- import { mapState } from 'vuex'
139
-
140
- export default {
141
- name: 'InstructDetailsView',
142
- components: {
143
- JsonViewer,
144
- XTable
145
- },
146
- data () {
147
- return {
148
- // 页面宽度
149
- screenWidth: document.documentElement.clientWidth,
150
- // 指令详情
151
- details: {
152
- id: 0,
153
- userid: 0,
154
- f_meternumber: '',
155
- f_instruct_type: '',
156
- f_instruct_title: '',
157
- f_instruct_state: '待发送',
158
- f_receive_state: '',
159
- f_inputtor: '',
160
- f_alias: '',
161
- f_instruct_date: '',
162
- f_send_date: '',
163
- f_callback_date: '',
164
- f_instruct_meta_data: {},
165
- f_instruct_content: {}
166
- },
167
- // 当前步骤
168
- step: 0,
169
- // 当前状态,
170
- status: 'process',
171
- // 指令状态结果
172
- instructResult: '执行成功',
173
- // 档案详情组件显示
174
- detailVisible: false,
175
- // 查询的档案id
176
- selectUserId: undefined,
177
- // 档案id
178
- userId: undefined,
179
- // 指令详情加载
180
- loadInstructDetails: true,
181
- // 查询配置文件名
182
- queryParamsName: 'recordQueryParams',
183
- // 查询列集合
184
- showColumns: [],
185
- // queryJson加载是否完成
186
- loaded: false,
187
- // 查询操作日志表单
188
- form: {
189
- r_f_data_id: this.instructid
190
- },
191
- operationTabList: [
192
- {
193
- key: '1',
194
- tab: '开发者信息'
195
- },
196
- {
197
- key: '2',
198
- tab: '操作日志'
199
- },
200
- {
201
- key: '3',
202
- tab: '维护教程'
203
- }
204
- ],
205
- operationActiveTabKey: '1'
206
- }
207
- },
208
- created () {
209
- this.getColumnsJson()
210
- },
211
- mounted () {
212
- this.initView()
213
- },
214
- computed: {
215
- ...mapState('account', { currUser: 'user' }),
216
- ...mapState('setting', ['isMobile'])
217
- },
218
- props: {
219
- instructid: {
220
- type: String,
221
- required: true
222
- },
223
- selectOrgName: {
224
- type: String,
225
- required: true
226
- },
227
- visible: {
228
- type: Boolean,
229
- default: false
230
- },
231
- isShowUserFiles: {
232
- type: Boolean,
233
- default: true
234
- }
235
- },
236
- methods: {
237
- // 初始化组件
238
- initView () {
239
- this.getInstruct(this.instructid, this.selectOrgName)
240
- },
241
- // 获取查询配置JSON
242
- getColumnsJson () {
243
- post(commonApi.getColumnsJson, { str: this.queryParamsName }).then((res) => {
244
- this.showColumns = res.columnJson
245
- this.loaded = true
246
- })
247
- },
248
- // 关闭抽屉时回调
249
- onClose () {
250
- this.$emit('update:visible', false)
251
- },
252
- // 加载xTable数据
253
- loadData (requestParameters, callback) {
254
- callback(query(requestParameters))
255
- },
256
- // 获取指令详情信息
257
- getInstruct (instructId, selectOrgName) {
258
- this.loadInstructDetails = true
259
- return post(InstructDetailsViewApi.getInstructDetails, {
260
- id: instructId,
261
- orgName: selectOrgName
262
- })
263
- .then(res => {
264
- this.details = res
265
- this.userId = res.userid + ''
266
- // 判断当前指令状态是不是最终流程
267
- if (this.details.f_instruct_state === '待发送') {
268
- this.status = 'process'
269
- this.step = 0
270
- this.instructResult = '执行成功'
271
- } else if (this.details.f_instruct_state === '已发送') {
272
- this.status = 'process'
273
- this.step = 1
274
- this.instructResult = '执行成功'
275
- } else {
276
- this.step = 2
277
- this.instructResult = this.details.f_instruct_state
278
- if (this.details.f_instruct_state === '发送失败' || this.details.f_instruct_state === '执行失败' ||
279
- this.details.f_instruct_state === '响应超时') {
280
- this.status = 'error'
281
- } else if (this.details.f_instruct_state === '忽略冗余' || this.details.f_instruct_state === '无响应' || this.details.f_instruct_state === '已延迟') {
282
- this.status = 'wait'
283
- } else {
284
- this.status = 'finish'
285
- }
286
- }
287
- this.loadInstructDetails = false
288
- }, err => {
289
- this.loadInstructDetails = false
290
- console.error(err)
291
- })
292
- },
293
- // 获取指令操作记录
294
- getRecord (requestParameters) {
295
- return post(InstructDetailsViewApi.getInstructRecordList, requestParameters)
296
- .then(res => {
297
- return res
298
- })
299
- },
300
- // 日期格式化
301
- format (date, format) {
302
- return formatDate(date, format)
303
- },
304
- // 重新发送指令
305
- againSend (id) {
306
- const _this = this
307
- this.$confirm({
308
- title: '您确定要重新发送该指令吗?',
309
- content: '指令状态将被标记为待发送',
310
- okText: '确定',
311
- okType: 'danger',
312
- cancelText: '取消',
313
- onOk () {
314
- return post(InstructDetailsViewApi.againSendInstruct, {
315
- id: id,
316
- orgName: _this.selectOrgName,
317
- username: _this.currUser.username
318
- }).then(res => {
319
- _this.getInstruct(id, _this.selectOrgName)
320
- if (res.nums === 1) {
321
- _this.$message.success('操作成功')
322
- } else {
323
- _this.$message.error('操作失败')
324
- }
325
- })
326
- }
327
- })
328
- },
329
- // 取消发送指令
330
- cancelSend (id) {
331
- const _this = this
332
- this.$confirm({
333
- title: '您确定要取消发送该指令吗?',
334
- content: '指令状态将被标记为忽略冗余',
335
- okText: '确定',
336
- okType: 'danger',
337
- cancelText: '取消',
338
- onOk () {
339
- return post(InstructDetailsViewApi.cancelSendInstruct, {
340
- id: id,
341
- orgName: _this.selectOrgName,
342
- username: _this.currUser.username
343
- }).then(res => {
344
- _this.getInstruct(id, _this.selectOrgName)
345
- if (res.nums === 1) {
346
- _this.$message.success('操作成功')
347
- } else {
348
- _this.$message.error('操作失败')
349
- }
350
- })
351
- }
352
- })
353
- },
354
- // 控制重新发送按钮的显示
355
- againSendBtnHide () {
356
- return this.step === 0 || this.loadInstructDetails
357
- },
358
- // 控制取消发送按钮的显示
359
- cancelSendBtnHide () {
360
- return (this.step !== 0 && this.step !== 1 && this.details.f_instruct_state !== '已延迟') || this.loadInstructDetails
361
- },
362
- // 转换JSON
363
- toJSON (value) {
364
- try {
365
- return JSON.parse(value)
366
- } catch (e) {
367
- return value
368
- }
369
- },
370
- // 获取指令过程说明
371
- getIntroduction () {
372
- if (this.step > 0) {
373
- return '已发送,等待响应结果'
374
- } else if (this.step === 0) {
375
- return ''
376
- }
377
- },
378
- // 获取指令结果说明
379
- getResultText (value) {
380
- if (this.step === 2) {
381
- if (value === '执行成功') {
382
- return '指令已发送成功'
383
- } else if (value === '执行失败') {
384
- return '失败,请查看响应结果'
385
- } else if (value === '忽略冗余') {
386
- return '指令已被取消发送'
387
- } else if (value === '无响应') {
388
- return '无法得到指令响应结果'
389
- } else if (value === '响应超时') {
390
- return '未得到指令响应结果'
391
- } else if (value === '已延迟') {
392
- return '由于表具限制,指令已被延迟发送'
393
- }
394
- }
395
- },
396
- // 打开档案详情抽屉
397
- openUserFilesDetails () {
398
- this.selectUserId = this.userId
399
- this.detailVisible = true
400
- }
401
- },
402
- watch: {
403
- 'visible' (val) {
404
- if (val) {
405
- this.initView()
406
- }
407
- }
408
- }
409
- }
410
- </script>
411
-
412
- <style lang="less" scoped>
413
- .detail-layout {
414
- margin-left: 44px;
415
- }
416
- .text {
417
- color: rgba(0, 0, 0, .45);
418
- }
419
-
420
- .heading {
421
- color: rgba(0, 0, 0, .85);
422
- font-size: 20px;
423
- }
424
-
425
- .no-data {
426
- color: rgba(0, 0, 0, .25);
427
- text-align: center;
428
- line-height: 64px;
429
- font-size: 16px;
430
-
431
- i {
432
- font-size: 24px;
433
- margin-right: 16px;
434
- position: relative;
435
- top: 3px;
436
- }
437
- }
438
-
439
- .mobile {
440
- .detail-layout {
441
- margin-left: unset;
442
- }
443
- .text {
444
-
445
- }
446
- .status-list {
447
- text-align: left;
448
- }
449
- }
450
-
451
- .row {
452
- display: flex;
453
-
454
- .content {
455
- -webkit-box-flex: 1;
456
- flex: auto;
457
- -ms-flex: auto;
458
- }
459
-
460
- .extra {
461
- flex: 0 1 auto;
462
- -webkit-box-flex: 0;
463
- -ms-flex: 0 1 auto;
464
- min-width: 242px;
465
- margin-left: 88px;
466
- text-align: right;
467
- }
468
- }
469
- </style>
1
+ <template>
2
+ <a-drawer
3
+ title="指令详情"
4
+ placement="right"
5
+ :width="isMobile ? screenWidth : screenWidth * 0.85"
6
+ :visible="visible"
7
+ @close="onClose"
8
+ >
9
+ <a-spin :spinning="loadInstructDetails">
10
+ <meter-details-view
11
+ :visible.sync="detailVisible"
12
+ :select-org-name="selectOrgName"
13
+ :userid="selectUserId"
14
+ v-if="selectUserId && isShowUserFiles"
15
+ />
16
+ <a-page-header
17
+ :title="'指令:' + details.f_instruct_type"
18
+ >
19
+ <div class="row">
20
+ <div class="content">
21
+ <a-descriptions size="small" :column="isMobile ? 1 : 2">
22
+ <a-descriptions-item label="指令编号" :span="isMobile ? 1 : 2">{{ details.id }}</a-descriptions-item>
23
+ <a-descriptions-item label="表编号">
24
+ <a v-if="isShowUserFiles" @click="openUserFilesDetails">{{ details.userid }}</a>
25
+ <span v-else>{{ details.userid }}</span>
26
+ </a-descriptions-item>
27
+ <a-descriptions-item label="表号">{{ details.f_meternumber }}</a-descriptions-item>
28
+ <a-descriptions-item label="操作人员">{{ details.f_inputtor }}</a-descriptions-item>
29
+ <a-descriptions-item label="指令说明">{{ details.f_instruct_title }}</a-descriptions-item>
30
+ <a-descriptions-item label="生成时间">{{ format(details.f_instruct_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
31
+ <a-descriptions-item label="表厂别名">{{ details.f_alias }}</a-descriptions-item>
32
+ <a-descriptions-item label="最后发送时间">{{ format(details.f_send_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
33
+ <a-descriptions-item label="最后响应时间">{{ format(details.f_callback_date,'yyyy-MM-dd hh:mm:ss') }}</a-descriptions-item>
34
+ </a-descriptions>
35
+ </div>
36
+ <div class="extra">
37
+ <a-row class="status-list">
38
+ <a-col :xs="12" :sm="24">
39
+ <div class="text">指令状态</div>
40
+ <div class="heading">
41
+ <x-badge :value="details.f_instruct_state" badge-key="instructStateMap" :is-external-text="true"/>
42
+ </div>
43
+ </a-col>
44
+ </a-row>
45
+ <p></p>
46
+ <a-row class="status-list">
47
+ <a-col :xs="12" :sm="24">
48
+ <div class="text">响应结果</div>
49
+ <div class="heading">{{ details.f_receive_state }}</div>
50
+ </a-col>
51
+ </a-row>
52
+ </div>
53
+ </div>
54
+
55
+ <!-- actions -->
56
+ <template v-slot:extra>
57
+ <a-button-group style="margin-right: 4px;">
58
+ <a-button type="dashed" @click="initView" :loading="loadInstructDetails">刷新</a-button>
59
+ </a-button-group>
60
+ <a-button-group style="margin-right: 4px;">
61
+ <a-popover title="重新发送" placement="bottomLeft">
62
+ <template slot="content">
63
+ <p>将指令标记为待发送状态</p>
64
+ <p>指令将在 定时器轮询/表具上报 后重新发送</p>
65
+ <p style="color: red">此操作不可撤销</p>
66
+ </template>
67
+ <a-button type="primary" @click="againSend(details.id)" :disabled="againSendBtnHide()">重新发送</a-button>
68
+ </a-popover>
69
+ <a-popover title="取消发送" placement="bottomLeft">
70
+ <template slot="content">
71
+ <p>该指令将被<span style="color: red;font-weight: bold">取消</span>,请谨慎操作</p>
72
+ <p>只有待发送或已发送的指令可以取消发送</p>
73
+ <p style="color: red">此操作不可撤销</p>
74
+ </template>
75
+ <a-button type="danger" @click="cancelSend(details.id)" :disabled="cancelSendBtnHide()">取消发送</a-button>
76
+ </a-popover>
77
+ </a-button-group>
78
+ </template>
79
+
80
+ <!-- 操作 -->
81
+ <a-card :bordered="false" title="指令状态">
82
+ <a-steps :direction="'horizontal'" :current="step" :status="status">
83
+ <a-step>
84
+ <template v-slot:title><span>待发送</span></template>
85
+ <template v-slot:description>
86
+ <div>指令已经就绪,待发送<div>{{ format(details.f_instruct_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
87
+ </template>
88
+ </a-step>
89
+ <a-step>
90
+ <template v-slot:title><span>已发送</span></template>
91
+ <template v-slot:description>
92
+ <div>{{ getIntroduction() }}<div>{{ format(details.f_send_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
93
+ </template>
94
+ </a-step>
95
+ <a-step>
96
+ <template v-slot:title><span>{{ instructResult }}</span></template>
97
+ <template v-slot:description>
98
+ <div>{{ getResultText(instructResult) }}<div>{{ format(details.f_callback_date,'yyyy-MM-dd hh:mm:ss') }}</div></div>
99
+ </template>
100
+ </a-step>
101
+ </a-steps>
102
+ </a-card>
103
+ <a-card
104
+ style="margin-top: 24px"
105
+ :bordered="false"
106
+ :tabList="operationTabList"
107
+ :activeTabKey="operationActiveTabKey"
108
+ @tabChange="(key) => {this.operationActiveTabKey = key}"
109
+ >
110
+ <div v-if="operationActiveTabKey === '1'">
111
+ <a-card type="inner" title="指令内容">
112
+ <json-viewer :copyable="{copyText: '复制', copiedText: '已复制'}" :value="details.f_instruct_content === undefined ? {} : toJSON(details.f_instruct_content)"></json-viewer>
113
+ </a-card>
114
+ <a-card type="inner" title="指令元数据">
115
+ <json-viewer :copyable="{copyText: '复制', copiedText: '已复制'}" :value="details.f_instruct_meta_data === undefined ? {} : toJSON(details.f_instruct_meta_data)"></json-viewer>
116
+ </a-card>
117
+ </div>
118
+
119
+ <x-table
120
+ v-if="loaded && operationActiveTabKey === '2'"
121
+ :json-data="showColumns"
122
+ :queryParamsName="queryParamsName"
123
+ @loadData="loadData"
124
+ :fixedQueryForm="form"
125
+ />
126
+ <div v-else-if="operationActiveTabKey === '3'" class="no-data"><a-icon type="frown-o"/>暂无数据</div>
127
+ </a-card>
128
+ </a-page-header>
129
+ </a-spin>
130
+ </a-drawer>
131
+ </template>
132
+
133
+ <script>
134
+ import JsonViewer from 'vue-json-viewer'
135
+ import { formatDate } from '@vue2-client/utils/util'
136
+ import { InstructDetailsViewApi, post, query, commonApi } from '@vue2-client/services/api'
137
+ import XTable from '@vue2-client/base-client/components/common/XTable/XTable'
138
+ import { mapState } from 'vuex'
139
+
140
+ export default {
141
+ name: 'InstructDetailsView',
142
+ components: {
143
+ JsonViewer,
144
+ XTable
145
+ },
146
+ data () {
147
+ return {
148
+ // 页面宽度
149
+ screenWidth: document.documentElement.clientWidth,
150
+ // 指令详情
151
+ details: {
152
+ id: 0,
153
+ userid: 0,
154
+ f_meternumber: '',
155
+ f_instruct_type: '',
156
+ f_instruct_title: '',
157
+ f_instruct_state: '待发送',
158
+ f_receive_state: '',
159
+ f_inputtor: '',
160
+ f_alias: '',
161
+ f_instruct_date: '',
162
+ f_send_date: '',
163
+ f_callback_date: '',
164
+ f_instruct_meta_data: {},
165
+ f_instruct_content: {}
166
+ },
167
+ // 当前步骤
168
+ step: 0,
169
+ // 当前状态,
170
+ status: 'process',
171
+ // 指令状态结果
172
+ instructResult: '执行成功',
173
+ // 档案详情组件显示
174
+ detailVisible: false,
175
+ // 查询的档案id
176
+ selectUserId: undefined,
177
+ // 档案id
178
+ userId: undefined,
179
+ // 指令详情加载
180
+ loadInstructDetails: true,
181
+ // 查询配置文件名
182
+ queryParamsName: 'recordQueryParams',
183
+ // 查询列集合
184
+ showColumns: [],
185
+ // queryJson加载是否完成
186
+ loaded: false,
187
+ // 查询操作日志表单
188
+ form: {
189
+ r_f_data_id: this.instructid
190
+ },
191
+ operationTabList: [
192
+ {
193
+ key: '1',
194
+ tab: '开发者信息'
195
+ },
196
+ {
197
+ key: '2',
198
+ tab: '操作日志'
199
+ },
200
+ {
201
+ key: '3',
202
+ tab: '维护教程'
203
+ }
204
+ ],
205
+ operationActiveTabKey: '1'
206
+ }
207
+ },
208
+ created () {
209
+ this.getColumnsJson()
210
+ },
211
+ mounted () {
212
+ this.initView()
213
+ },
214
+ computed: {
215
+ ...mapState('account', { currUser: 'user' }),
216
+ ...mapState('setting', ['isMobile'])
217
+ },
218
+ props: {
219
+ instructid: {
220
+ type: String,
221
+ required: true
222
+ },
223
+ selectOrgName: {
224
+ type: String,
225
+ required: true
226
+ },
227
+ visible: {
228
+ type: Boolean,
229
+ default: false
230
+ },
231
+ isShowUserFiles: {
232
+ type: Boolean,
233
+ default: true
234
+ }
235
+ },
236
+ methods: {
237
+ // 初始化组件
238
+ initView () {
239
+ this.getInstruct(this.instructid, this.selectOrgName)
240
+ },
241
+ // 获取查询配置JSON
242
+ getColumnsJson () {
243
+ post(commonApi.getColumnsJson, { str: this.queryParamsName }).then((res) => {
244
+ this.showColumns = res.columnJson
245
+ this.loaded = true
246
+ })
247
+ },
248
+ // 关闭抽屉时回调
249
+ onClose () {
250
+ this.$emit('update:visible', false)
251
+ },
252
+ // 加载xTable数据
253
+ loadData (requestParameters, callback) {
254
+ callback(query(requestParameters))
255
+ },
256
+ // 获取指令详情信息
257
+ getInstruct (instructId, selectOrgName) {
258
+ this.loadInstructDetails = true
259
+ return post(InstructDetailsViewApi.getInstructDetails, {
260
+ id: instructId,
261
+ orgName: selectOrgName
262
+ })
263
+ .then(res => {
264
+ this.details = res
265
+ this.userId = res.userid + ''
266
+ // 判断当前指令状态是不是最终流程
267
+ if (this.details.f_instruct_state === '待发送') {
268
+ this.status = 'process'
269
+ this.step = 0
270
+ this.instructResult = '执行成功'
271
+ } else if (this.details.f_instruct_state === '已发送') {
272
+ this.status = 'process'
273
+ this.step = 1
274
+ this.instructResult = '执行成功'
275
+ } else {
276
+ this.step = 2
277
+ this.instructResult = this.details.f_instruct_state
278
+ if (this.details.f_instruct_state === '发送失败' || this.details.f_instruct_state === '执行失败' ||
279
+ this.details.f_instruct_state === '响应超时') {
280
+ this.status = 'error'
281
+ } else if (this.details.f_instruct_state === '忽略冗余' || this.details.f_instruct_state === '无响应' || this.details.f_instruct_state === '已延迟') {
282
+ this.status = 'wait'
283
+ } else {
284
+ this.status = 'finish'
285
+ }
286
+ }
287
+ this.loadInstructDetails = false
288
+ }, err => {
289
+ this.loadInstructDetails = false
290
+ console.error(err)
291
+ })
292
+ },
293
+ // 获取指令操作记录
294
+ getRecord (requestParameters) {
295
+ return post(InstructDetailsViewApi.getInstructRecordList, requestParameters)
296
+ .then(res => {
297
+ return res
298
+ })
299
+ },
300
+ // 日期格式化
301
+ format (date, format) {
302
+ return formatDate(date, format)
303
+ },
304
+ // 重新发送指令
305
+ againSend (id) {
306
+ const _this = this
307
+ this.$confirm({
308
+ title: '您确定要重新发送该指令吗?',
309
+ content: '指令状态将被标记为待发送',
310
+ okText: '确定',
311
+ okType: 'danger',
312
+ cancelText: '取消',
313
+ onOk () {
314
+ return post(InstructDetailsViewApi.againSendInstruct, {
315
+ id: id,
316
+ orgName: _this.selectOrgName,
317
+ username: _this.currUser.username
318
+ }).then(res => {
319
+ _this.getInstruct(id, _this.selectOrgName)
320
+ if (res.nums === 1) {
321
+ _this.$message.success('操作成功')
322
+ } else {
323
+ _this.$message.error('操作失败')
324
+ }
325
+ })
326
+ }
327
+ })
328
+ },
329
+ // 取消发送指令
330
+ cancelSend (id) {
331
+ const _this = this
332
+ this.$confirm({
333
+ title: '您确定要取消发送该指令吗?',
334
+ content: '指令状态将被标记为忽略冗余',
335
+ okText: '确定',
336
+ okType: 'danger',
337
+ cancelText: '取消',
338
+ onOk () {
339
+ return post(InstructDetailsViewApi.cancelSendInstruct, {
340
+ id: id,
341
+ orgName: _this.selectOrgName,
342
+ username: _this.currUser.username
343
+ }).then(res => {
344
+ _this.getInstruct(id, _this.selectOrgName)
345
+ if (res.nums === 1) {
346
+ _this.$message.success('操作成功')
347
+ } else {
348
+ _this.$message.error('操作失败')
349
+ }
350
+ })
351
+ }
352
+ })
353
+ },
354
+ // 控制重新发送按钮的显示
355
+ againSendBtnHide () {
356
+ return this.step === 0 || this.loadInstructDetails
357
+ },
358
+ // 控制取消发送按钮的显示
359
+ cancelSendBtnHide () {
360
+ return (this.step !== 0 && this.step !== 1 && this.details.f_instruct_state !== '已延迟') || this.loadInstructDetails
361
+ },
362
+ // 转换JSON
363
+ toJSON (value) {
364
+ try {
365
+ return JSON.parse(value)
366
+ } catch (e) {
367
+ return value
368
+ }
369
+ },
370
+ // 获取指令过程说明
371
+ getIntroduction () {
372
+ if (this.step > 0) {
373
+ return '已发送,等待响应结果'
374
+ } else if (this.step === 0) {
375
+ return ''
376
+ }
377
+ },
378
+ // 获取指令结果说明
379
+ getResultText (value) {
380
+ if (this.step === 2) {
381
+ if (value === '执行成功') {
382
+ return '指令已发送成功'
383
+ } else if (value === '执行失败') {
384
+ return '失败,请查看响应结果'
385
+ } else if (value === '忽略冗余') {
386
+ return '指令已被取消发送'
387
+ } else if (value === '无响应') {
388
+ return '无法得到指令响应结果'
389
+ } else if (value === '响应超时') {
390
+ return '未得到指令响应结果'
391
+ } else if (value === '已延迟') {
392
+ return '由于表具限制,指令已被延迟发送'
393
+ }
394
+ }
395
+ },
396
+ // 打开档案详情抽屉
397
+ openUserFilesDetails () {
398
+ this.selectUserId = this.userId
399
+ this.detailVisible = true
400
+ }
401
+ },
402
+ watch: {
403
+ 'visible' (val) {
404
+ if (val) {
405
+ this.initView()
406
+ }
407
+ }
408
+ }
409
+ }
410
+ </script>
411
+
412
+ <style lang="less" scoped>
413
+ .detail-layout {
414
+ margin-left: 44px;
415
+ }
416
+ .text {
417
+ color: rgba(0, 0, 0, .45);
418
+ }
419
+
420
+ .heading {
421
+ color: rgba(0, 0, 0, .85);
422
+ font-size: 20px;
423
+ }
424
+
425
+ .no-data {
426
+ color: rgba(0, 0, 0, .25);
427
+ text-align: center;
428
+ line-height: 64px;
429
+ font-size: 16px;
430
+
431
+ i {
432
+ font-size: 24px;
433
+ margin-right: 16px;
434
+ position: relative;
435
+ top: 3px;
436
+ }
437
+ }
438
+
439
+ .mobile {
440
+ .detail-layout {
441
+ margin-left: unset;
442
+ }
443
+ .text {
444
+
445
+ }
446
+ .status-list {
447
+ text-align: left;
448
+ }
449
+ }
450
+
451
+ .row {
452
+ display: flex;
453
+
454
+ .content {
455
+ -webkit-box-flex: 1;
456
+ flex: auto;
457
+ -ms-flex: auto;
458
+ }
459
+
460
+ .extra {
461
+ flex: 0 1 auto;
462
+ -webkit-box-flex: 0;
463
+ -ms-flex: 0 1 auto;
464
+ min-width: 242px;
465
+ margin-left: 88px;
466
+ text-align: right;
467
+ }
468
+ }
469
+ </style>