vue2-client 1.2.0 → 1.2.1

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 (120) hide show
  1. package/README.md +65 -65
  2. package/babel.config.js +1 -0
  3. package/docs/notice.md +24 -0
  4. package/index.js +28 -28
  5. package/package.json +1 -1
  6. package/src/App.vue +93 -93
  7. package/src/base-client/all.js +57 -57
  8. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +1159 -1159
  9. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  10. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +540 -540
  11. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  12. package/src/base-client/components/common/CustomColumnsDrawer/index.md +46 -46
  13. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +150 -150
  14. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  15. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  16. package/src/base-client/components/common/XAddForm/XAddForm.vue +323 -323
  17. package/src/base-client/components/common/XAddForm/index.md +60 -60
  18. package/src/base-client/components/common/XBadge/index.md +39 -39
  19. package/src/base-client/components/common/XCard/index.md +43 -43
  20. package/src/base-client/components/common/XForm/XForm.vue +275 -275
  21. package/src/base-client/components/common/XForm/XFormItem.vue +217 -217
  22. package/src/base-client/components/common/XForm/index.md +196 -196
  23. package/src/base-client/components/common/XFormCol/index.md +35 -35
  24. package/src/base-client/components/common/XFormTable/XFormTable.vue +405 -405
  25. package/src/base-client/components/common/XFormTable/index.md +89 -89
  26. package/src/base-client/components/common/XTable/XTable.vue +262 -262
  27. package/src/base-client/components/common/XTable/index.md +255 -255
  28. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +105 -105
  29. package/src/base-client/components/iot/CustomerDetailsView/CustomerDetailsView.vue +226 -226
  30. package/src/base-client/components/iot/CustomerDetailsView/index.md +41 -41
  31. package/src/base-client/components/iot/DataAnalysisUser/DataAnalysisUser.vue +127 -127
  32. package/src/base-client/components/iot/DataAnalysisViewGD/DataAnalysisViewGD.vue +548 -548
  33. package/src/base-client/components/iot/DeviceBrandDetailsView/DeviceBrandDetailsView.vue +453 -453
  34. package/src/base-client/components/iot/DeviceDetailsView/DeviceDetailsView.vue +231 -231
  35. package/src/base-client/components/iot/DeviceDetailsView/index.md +43 -43
  36. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsCount.vue +330 -330
  37. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsException.vue +57 -57
  38. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsInstruct.vue +122 -122
  39. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsInstructOperate.vue +122 -122
  40. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsMain.vue +225 -225
  41. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsRead.vue +135 -135
  42. package/src/base-client/components/iot/DeviceTypeDetailsView/DeviceTypeDetailsView.vue +277 -277
  43. package/src/base-client/components/iot/InstructDetailsView/InstructDetailsView.vue +472 -472
  44. package/src/base-client/components/iot/InstructDetailsView/index.md +45 -45
  45. package/src/base-client/components/iot/LogDetailsView/LogDetailsView.vue +380 -380
  46. package/src/base-client/components/iot/LogDetailsView/index.md +43 -43
  47. package/src/base-client/components/iot/MeterDetailsView/MeterDetailsView.vue +360 -360
  48. package/src/base-client/components/iot/MeterDetailsView/index.md +43 -43
  49. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsCount.vue +335 -335
  50. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsException.vue +185 -185
  51. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsHandPlan.vue +292 -292
  52. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsInstruct.vue +237 -237
  53. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsMain.vue +257 -257
  54. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsSellGas.vue +190 -190
  55. package/src/base-client/components/iot/WebmeterAnalysisView/WebmeterAnalysisView.vue +723 -723
  56. package/src/base-client/components/iot/WebmeterAnalysisView/index.md +48 -48
  57. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  58. package/src/base-client/components/system/DictionaryDetailsView/index.md +41 -41
  59. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +248 -248
  60. package/src/base-client/components/ticket/EmployeeDetailsView/EmployeeDetailsView.vue +406 -406
  61. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +486 -486
  62. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +184 -184
  63. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +303 -303
  64. package/src/base-client/plugins/AppData.js +69 -69
  65. package/src/base-client/plugins/GetLoginInfoService.js +221 -221
  66. package/src/base-client/plugins/index.js +21 -21
  67. package/src/bootstrap.js +27 -27
  68. package/src/components/Ellipsis/Ellipsis.vue +64 -64
  69. package/src/components/Ellipsis/index.md +38 -38
  70. package/src/components/NumberInfo/index.md +43 -43
  71. package/src/components/STable/README.md +341 -341
  72. package/src/components/Trend/index.md +45 -45
  73. package/src/components/cache/AKeepAlive.js +172 -172
  74. package/src/components/checkbox/index.js +7 -7
  75. package/src/components/index.js +36 -36
  76. package/src/components/menu/menu.js +273 -273
  77. package/src/components/setting/Setting.vue +237 -237
  78. package/src/components/table/advance/AdvanceTable.vue +275 -275
  79. package/src/components/transition/PageToggleTransition.vue +97 -97
  80. package/src/layouts/CommonLayout.vue +42 -42
  81. package/src/layouts/PageLayout.vue +151 -151
  82. package/src/layouts/SinglePageView.vue +74 -74
  83. package/src/layouts/header/AdminHeader.vue +109 -109
  84. package/src/layouts/header/HeaderAvatar.vue +60 -60
  85. package/src/layouts/header/HeaderNotice.vue +97 -97
  86. package/src/layouts/tabs/TabsHead.vue +190 -190
  87. package/src/layouts/tabs/TabsView.vue +355 -355
  88. package/src/main.js +20 -20
  89. package/src/mock/goods/index.js +108 -108
  90. package/src/mock/index.js +12 -12
  91. package/src/mock/project/index.js +17 -17
  92. package/src/mock/user/current.js +13 -13
  93. package/src/mock/user/login.js +39 -39
  94. package/src/mock/workplace/index.js +15 -15
  95. package/src/pages/exception/403.vue +25 -25
  96. package/src/pages/exception/404.vue +25 -25
  97. package/src/pages/exception/500.vue +25 -25
  98. package/src/pages/login/Login.vue +194 -194
  99. package/src/pages/report/ReportTableHome.vue +28 -28
  100. package/src/pages/resourceManage/resourceManageMain.vue +55 -55
  101. package/src/pages/system/applyInstallView/Core.vue +570 -570
  102. package/src/pages/system/applyInstallView/index.vue +34 -34
  103. package/src/pages/system/dictionary/index.vue +41 -41
  104. package/src/pages/system/queryParams/index.vue +41 -41
  105. package/src/router/async/config.async.js +25 -25
  106. package/src/router/async/router.map.js +59 -59
  107. package/src/router/guards.js +104 -104
  108. package/src/router/index.js +27 -27
  109. package/src/services/api/common.js +39 -39
  110. package/src/services/api/restTools.js +23 -23
  111. package/src/services/dataSource.js +12 -12
  112. package/src/services/user.js +34 -34
  113. package/src/store/modules/setting.js +114 -114
  114. package/src/utils/i18n.js +80 -80
  115. package/src/utils/indexedDB.js +146 -146
  116. package/src/utils/request.js +197 -197
  117. package/src/utils/routerUtil.js +15 -2
  118. package/tests/unit/ReportTable.spec.js +15 -15
  119. package/vue.config.js +153 -153
  120. package/webpack.config.js +12 -12
@@ -1,486 +1,486 @@
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-modal
10
- title="移交工单"
11
- :visible="transVisible"
12
- @ok="handleTransferOk"
13
- @cancel="handleTransferCancel"
14
- :zIndex="1001"
15
- >
16
- <a-input placeholder="请输入要转移工单的员工名" v-model="transferTo" @blur="checkEmp()"/>
17
- <span v-if="!transferCheck" style="color: red">您输入的员工不存在,请检查后再试</span>
18
- <span v-if="transferCheck" style="color: green">您输入的员工已确认,可以进行工单转移</span>
19
- <a-form-model-item label="留言">
20
- <a-input v-model="note" type="textarea" />
21
- </a-form-model-item>
22
- </a-modal>
23
- <a-modal
24
- title="关闭工单"
25
- :visible="closeVisible"
26
- @ok="handleCloseOk"
27
- @cancel="handleCloseCancel"
28
- :zIndex="1002"
29
- >
30
- <p>是否确认手动关闭工单?</p>
31
- <p style="color: red">(该操作不可撤销,请谨慎操作!)</p>
32
- </a-modal>
33
- <a-spin :spinning="loadTicketDetails">
34
- <a-page-header :title="'订单:' + this.details.serial_number">
35
- <div class="row">
36
- <div class="content">
37
- <a-descriptions size="small" :column="isMobile ? 1 : 2">
38
- <a-descriptions-item label="优先级">
39
- <a-alert
40
- :type="showPriorityColorControl()"
41
- :message="showPriority()"
42
- :show-icon="true"/>
43
- </a-descriptions-item>
44
- <a-descriptions-item label="发起人">{{ details.uploader }}</a-descriptions-item>
45
- <a-descriptions-item label="问题类型">{{ details.category }}</a-descriptions-item>
46
- </a-descriptions>
47
- </div>
48
- </div>
49
- <!-- 按钮 -->
50
- <template v-slot:extra>
51
- <a-button-group style="margin-right: 4px;">
52
- <a-popover title="开始处理" placement="bottomLeft">
53
- <template slot="content">
54
- <p>开始处理当前工单</p>
55
- </template>
56
- <a-button type="primary" @click="confirmTicketBtn()" :disabled="handlerBtnDisable()">开始处理</a-button>
57
- </a-popover>
58
- <a-popover title="移交他人" placement="bottomLeft">
59
- <template slot="content">
60
- <p>将工单转交他人处理</p>
61
- </template>
62
- <a-button type="primary" @click="transferBtn()" :disabled="transferBtnDisable()">移交他人</a-button>
63
- </a-popover>
64
- <a-popover title="关闭工单" placement="bottomLeft">
65
- <template slot="content">
66
- <p>强制关闭当前工单</p>
67
- <p style="color: red">此操作不可撤销,请谨慎使用</p>
68
- </template>
69
- <a-button type="danger" @click="closeBtn()" :disabled="closeBtnDisable()">关闭工单</a-button>
70
- </a-popover>
71
- </a-button-group>
72
- </template>
73
-
74
- <br/>
75
- <br/>
76
- <br/>
77
-
78
- <!-- 进度条 -->
79
- <a-card :bordered="false">
80
- <a-steps :direction="'horizontal'" :current="step">
81
- <a-step>
82
- <template v-slot:title><span>待处理</span></template>
83
- <template v-slot:description>
84
- <div>工单已提交,等待处理<div>{{ format(details.created_time,'yyyy-MM-dd hh:mm:ss') }}</div></div>
85
- </template>
86
- </a-step>
87
- <a-step>
88
- <template v-slot:title><span>处理中</span></template>
89
- <template v-slot:description>
90
- <div v-if="step >= 1"><strong>{{ details.name }}</strong> 处理中...<div>{{ format(details.confirm_time,'yyyy-MM-dd hh:mm:ss') }}</div></div>
91
- </template>
92
- </a-step>
93
- <a-step>
94
- <template v-slot:title><span>{{ getStatus() }}</span></template>
95
- <template v-slot:description>
96
- <div v-if="step >= 2">{{ format(details.finished_time,'yyyy-MM-dd hh:mm:ss') }}</div>
97
- </template>
98
- </a-step>
99
- </a-steps>
100
- </a-card>
101
- <br/>
102
- <br/>
103
- <br/>
104
-
105
- <a-card title="问题详细描述" style="width: 100%">
106
- <p>{{ details.description }}</p>
107
- </a-card>
108
-
109
- <ticket-details-flow v-if="details.id" :ticketId="ticketId" :disableCloseBtn="disableCloseBtn" :id="details.id"/>
110
- </a-page-header>
111
- </a-spin>
112
- </a-drawer>
113
- </template>
114
-
115
- <script>
116
- import JsonViewer from 'vue-json-viewer'
117
- import { formatDate } from '@vue2-client/utils/util'
118
- import { TicketDetailsViewApi } from '@vue2-client/services/api/TicketDetailsViewApi'
119
- import { EmployeeDetailsViewApi } from '@vue2-client/services/api/EmployeeDetailsViewApi'
120
- import { post } from '@vue2-client/services/api/restTools'
121
- import XTable from '@vue2-client/base-client/components/common/XTable/XTable'
122
- import { mapState } from 'vuex'
123
- import TicketDetailsFlow from './part/TicketDetailsFlow'
124
-
125
- export default {
126
- name: 'TicketDetailsView',
127
- components: {
128
- TicketDetailsFlow,
129
- JsonViewer,
130
- XTable
131
- },
132
- data () {
133
- return {
134
- // 页面宽度
135
- screenWidth: document.documentElement.clientWidth,
136
- // 工单详情
137
- details: {
138
- // 当前负责人ID
139
- id: undefined,
140
- name: '',
141
- uploader: '',
142
- status: undefined,
143
- priority: undefined,
144
- description: '',
145
- created_time: '',
146
- confirm_time: '',
147
- finished_time: '',
148
- category: '',
149
- serial_number: ''
150
- },
151
- // 当前步骤
152
- step: 0,
153
- // 校验转移员工是否存在
154
- transferCheck: false,
155
- // 移交工单窗口可见性
156
- transVisible: false,
157
- // 转移工单对象
158
- transferTo: '',
159
- // 新增留言
160
- note: '',
161
- // 控制关闭订单按钮可用性
162
- disableCloseBtn: false,
163
- // 控制关闭工单确认框显示
164
- closeVisible: false,
165
- // 控制加载过程
166
- loadTicketDetails: false,
167
- // 工单类型字典
168
- categoryDictionary: []
169
- }
170
- },
171
- mounted () {
172
- this.getTicketCategory()
173
- this.initView()
174
- },
175
- computed: {
176
- ...mapState('account', { currUser: 'user' }),
177
- ...mapState('setting', ['isMobile'])
178
- },
179
- props: {
180
- ticketId: {
181
- type: String,
182
- required: true
183
- },
184
- visible: {
185
- type: Boolean,
186
- default: false
187
- }
188
- },
189
- methods: {
190
- // 初始化组件
191
- initView () {
192
- this.loadTicketDetails = true
193
- this.getTicketDetail(this.ticketId)
194
- this.loadTicketDetails = false
195
- },
196
- // 解析工单类型
197
- resolveCategory (key) {
198
- for (let i = 0; i < this.categoryDictionary.length; i++) {
199
- if (this.categoryDictionary[i].value == key) {
200
- return this.categoryDictionary[i].name
201
- }
202
- }
203
- },
204
- // 关闭工单确认后业务逻辑
205
- handleCloseOk () {
206
- return post(TicketDetailsViewApi.manualCloseTicket, {
207
- ticketId: this.ticketId,
208
- time: new Date()
209
- })
210
- .then(res => {
211
- if (res !== 0) {
212
- this.$message.success(
213
- '操作成功',
214
- 5
215
- )
216
- this.initView()
217
- this.closeVisible = false
218
- } else {
219
- this.$message.error(
220
- '操作失败',
221
- 5
222
- )
223
- }
224
- }, err => {
225
- console.error(err)
226
- })
227
- },
228
- // 关闭工单取消后业务逻辑
229
- handleCloseCancel () {
230
- this.closeVisible = false
231
- },
232
- // 确认工单按钮业务逻辑
233
- confirmTicketBtn () {
234
- const currentEmpId = this.getCurrentEmpId()
235
- return post(TicketDetailsViewApi.confirmTicket, {
236
- ticketId: this.ticketId,
237
- empId: currentEmpId,
238
- time: new Date()
239
- })
240
- .then(res => {
241
- if (res !== 0) {
242
- this.$message.success(
243
- '操作成功',
244
- 5
245
- )
246
- this.initView()
247
- } else {
248
- this.$message.error(
249
- '操作失败',
250
- 5
251
- )
252
- }
253
- }, err => {
254
- console.error(err)
255
- })
256
- },
257
- // 获取当前登陆员工ID
258
- getCurrentEmpId () {
259
- return this.currUser.id
260
- },
261
- // 转移工单按钮业务逻辑
262
- transferBtn () {
263
- this.transVisible = true
264
- },
265
- checkEmp () {
266
- return post(EmployeeDetailsViewApi.findEmpName, {
267
- empName: this.transferTo
268
- })
269
- .then(res => {
270
- const num = res.number
271
- this.transferCheck = num !== 0
272
- }, err => {
273
- console.error(err)
274
- })
275
- },
276
- // 获取工单状态撤销or关闭
277
- getStatus () {
278
- if (this.details.status === 2) {
279
- return '已撤销'
280
- } else {
281
- return '已关闭'
282
- }
283
- },
284
- // 关闭工单按钮业务逻辑
285
- closeBtn () {
286
- this.closeVisible = true
287
- },
288
- // 转移工单确认后逻辑
289
- handleTransferOk () {
290
- if (!this.transferCheck) {
291
- this.$message.error(
292
- '请先检查您输入的员工名',
293
- 2
294
- )
295
- } else {
296
- return post(TicketDetailsViewApi.transferTicketToOthers, {
297
- ticketId: this.ticketId,
298
- endTime: new Date(),
299
- transferTo: this.transferTo,
300
- note: this.note
301
- })
302
- .then(res => {
303
- const result = res
304
- this.note = ''
305
- this.transVisible = false
306
- if (result === 1) {
307
- this.$message.success(
308
- '操作成功',
309
- 5
310
- )
311
- this.initView()
312
- } else {
313
- this.$message.error(
314
- '操作失败',
315
- 5
316
- )
317
- }
318
- this.handleCancel()
319
- this.initView()
320
- }, err => {
321
- console.error(err)
322
- this.transVisible = false
323
- })
324
- }
325
- },
326
- // 转移工单取消后逻辑
327
- handleTransferCancel () {
328
- this.transferTo = ''
329
- this.note = ''
330
- this.transVisible = false
331
- this.transferCheck = false
332
- },
333
- // 关闭抽屉时回调
334
- onClose () {
335
- this.disableCloseBtn = false
336
- this.$emit('update:visible', false)
337
- },
338
- // 获取工单详情信息
339
- getTicketDetail (num) {
340
- this.loadTicketDetails = true
341
- return post(TicketDetailsViewApi.getTicketDetails, {
342
- ticketId: num
343
- })
344
- .then(res => {
345
- this.details = res[0]
346
- this.step = res[0].status
347
- if (this.details.status === 3) {
348
- this.disableCloseBtn = true
349
- }
350
- const categoryValue = this.details.category
351
- this.details.category = this.resolveCategory(categoryValue)
352
- }, err => {
353
- console.error(err)
354
- })
355
- },
356
- // 获取工单类别字典
357
- getTicketCategory () {
358
- return post(TicketDetailsViewApi.getTicketCategoryDictionary)
359
- .then(res => {
360
- this.categoryDictionary = res
361
- }, err => {
362
- console.log(err)
363
- })
364
- },
365
- // 日期格式化
366
- format (date, format) {
367
- return formatDate(date, format)
368
- },
369
- // 转换JSON
370
- toJSON (value) {
371
- try {
372
- return JSON.parse(value)
373
- } catch (e) {
374
- return value
375
- }
376
- },
377
- // 控制开始处理按钮可用状态
378
- handlerBtnDisable () {
379
- return this.step !== 0
380
- },
381
- // 控制移交他人按钮可用状态
382
- transferBtnDisable () {
383
- return this.step === 0
384
- },
385
- // 控制关闭工单按钮可用状态
386
- closeBtnDisable () {
387
- return this.step === 0 || this.disableCloseBtn || this.details.id != this.currUser.id
388
- },
389
- // 优先级文字显示
390
- showPriority () {
391
- if (this.details.priority === 2) {
392
- return '一般'
393
- } else if (this.details.priority === 1) {
394
- return '紧急'
395
- } else {
396
- return '非常紧急'
397
- }
398
- },
399
- // 优先度颜色控制
400
- showPriorityColorControl () {
401
- if (this.details.priority === 2) {
402
- return 'info'
403
- } else if (this.details.priority === 1) {
404
- return 'warning'
405
- } else {
406
- return 'error'
407
- }
408
- }
409
- },
410
- watch: {
411
- 'visible' (val) {
412
- if (val) {
413
- this.initView()
414
- }
415
- }
416
- }
417
- }
418
- </script>
419
-
420
- <style lang="less" scoped>
421
- .high-priority{
422
- background-color: rgba(163, 30, 30, 0.66);
423
- border: red solid 1px;
424
- font-size: large;
425
- padding: 5px;
426
- color: white;
427
- border-radius: 10px;
428
- }
429
-
430
- .detail-layout {
431
- margin-left: 44px;
432
- }
433
- .text {
434
- color: rgba(0, 0, 0, .45);
435
- }
436
-
437
- .heading {
438
- color: rgba(0, 0, 0, .85);
439
- font-size: 20px;
440
- }
441
-
442
- .no-data {
443
- color: rgba(0, 0, 0, .25);
444
- text-align: center;
445
- line-height: 64px;
446
- font-size: 16px;
447
-
448
- i {
449
- font-size: 24px;
450
- margin-right: 16px;
451
- position: relative;
452
- top: 3px;
453
- }
454
- }
455
-
456
- .mobile {
457
- .detail-layout {
458
- margin-left: unset;
459
- }
460
- .text {
461
-
462
- }
463
- .status-list {
464
- text-align: left;
465
- }
466
- }
467
-
468
- .row {
469
- display: flex;
470
-
471
- .content {
472
- -webkit-box-flex: 1;
473
- flex: auto;
474
- -ms-flex: auto;
475
- }
476
-
477
- .extra {
478
- flex: 0 1 auto;
479
- -webkit-box-flex: 0;
480
- -ms-flex: 0 1 auto;
481
- min-width: 242px;
482
- margin-left: 88px;
483
- text-align: right;
484
- }
485
- }
486
- </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-modal
10
+ title="移交工单"
11
+ :visible="transVisible"
12
+ @ok="handleTransferOk"
13
+ @cancel="handleTransferCancel"
14
+ :zIndex="1001"
15
+ >
16
+ <a-input placeholder="请输入要转移工单的员工名" v-model="transferTo" @blur="checkEmp()"/>
17
+ <span v-if="!transferCheck" style="color: red">您输入的员工不存在,请检查后再试</span>
18
+ <span v-if="transferCheck" style="color: green">您输入的员工已确认,可以进行工单转移</span>
19
+ <a-form-model-item label="留言">
20
+ <a-input v-model="note" type="textarea" />
21
+ </a-form-model-item>
22
+ </a-modal>
23
+ <a-modal
24
+ title="关闭工单"
25
+ :visible="closeVisible"
26
+ @ok="handleCloseOk"
27
+ @cancel="handleCloseCancel"
28
+ :zIndex="1002"
29
+ >
30
+ <p>是否确认手动关闭工单?</p>
31
+ <p style="color: red">(该操作不可撤销,请谨慎操作!)</p>
32
+ </a-modal>
33
+ <a-spin :spinning="loadTicketDetails">
34
+ <a-page-header :title="'订单:' + this.details.serial_number">
35
+ <div class="row">
36
+ <div class="content">
37
+ <a-descriptions size="small" :column="isMobile ? 1 : 2">
38
+ <a-descriptions-item label="优先级">
39
+ <a-alert
40
+ :type="showPriorityColorControl()"
41
+ :message="showPriority()"
42
+ :show-icon="true"/>
43
+ </a-descriptions-item>
44
+ <a-descriptions-item label="发起人">{{ details.uploader }}</a-descriptions-item>
45
+ <a-descriptions-item label="问题类型">{{ details.category }}</a-descriptions-item>
46
+ </a-descriptions>
47
+ </div>
48
+ </div>
49
+ <!-- 按钮 -->
50
+ <template v-slot:extra>
51
+ <a-button-group style="margin-right: 4px;">
52
+ <a-popover title="开始处理" placement="bottomLeft">
53
+ <template slot="content">
54
+ <p>开始处理当前工单</p>
55
+ </template>
56
+ <a-button type="primary" @click="confirmTicketBtn()" :disabled="handlerBtnDisable()">开始处理</a-button>
57
+ </a-popover>
58
+ <a-popover title="移交他人" placement="bottomLeft">
59
+ <template slot="content">
60
+ <p>将工单转交他人处理</p>
61
+ </template>
62
+ <a-button type="primary" @click="transferBtn()" :disabled="transferBtnDisable()">移交他人</a-button>
63
+ </a-popover>
64
+ <a-popover title="关闭工单" placement="bottomLeft">
65
+ <template slot="content">
66
+ <p>强制关闭当前工单</p>
67
+ <p style="color: red">此操作不可撤销,请谨慎使用</p>
68
+ </template>
69
+ <a-button type="danger" @click="closeBtn()" :disabled="closeBtnDisable()">关闭工单</a-button>
70
+ </a-popover>
71
+ </a-button-group>
72
+ </template>
73
+
74
+ <br/>
75
+ <br/>
76
+ <br/>
77
+
78
+ <!-- 进度条 -->
79
+ <a-card :bordered="false">
80
+ <a-steps :direction="'horizontal'" :current="step">
81
+ <a-step>
82
+ <template v-slot:title><span>待处理</span></template>
83
+ <template v-slot:description>
84
+ <div>工单已提交,等待处理<div>{{ format(details.created_time,'yyyy-MM-dd hh:mm:ss') }}</div></div>
85
+ </template>
86
+ </a-step>
87
+ <a-step>
88
+ <template v-slot:title><span>处理中</span></template>
89
+ <template v-slot:description>
90
+ <div v-if="step >= 1"><strong>{{ details.name }}</strong> 处理中...<div>{{ format(details.confirm_time,'yyyy-MM-dd hh:mm:ss') }}</div></div>
91
+ </template>
92
+ </a-step>
93
+ <a-step>
94
+ <template v-slot:title><span>{{ getStatus() }}</span></template>
95
+ <template v-slot:description>
96
+ <div v-if="step >= 2">{{ format(details.finished_time,'yyyy-MM-dd hh:mm:ss') }}</div>
97
+ </template>
98
+ </a-step>
99
+ </a-steps>
100
+ </a-card>
101
+ <br/>
102
+ <br/>
103
+ <br/>
104
+
105
+ <a-card title="问题详细描述" style="width: 100%">
106
+ <p>{{ details.description }}</p>
107
+ </a-card>
108
+
109
+ <ticket-details-flow v-if="details.id" :ticketId="ticketId" :disableCloseBtn="disableCloseBtn" :id="details.id"/>
110
+ </a-page-header>
111
+ </a-spin>
112
+ </a-drawer>
113
+ </template>
114
+
115
+ <script>
116
+ import JsonViewer from 'vue-json-viewer'
117
+ import { formatDate } from '@vue2-client/utils/util'
118
+ import { TicketDetailsViewApi } from '@vue2-client/services/api/TicketDetailsViewApi'
119
+ import { EmployeeDetailsViewApi } from '@vue2-client/services/api/EmployeeDetailsViewApi'
120
+ import { post } from '@vue2-client/services/api/restTools'
121
+ import XTable from '@vue2-client/base-client/components/common/XTable/XTable'
122
+ import { mapState } from 'vuex'
123
+ import TicketDetailsFlow from './part/TicketDetailsFlow'
124
+
125
+ export default {
126
+ name: 'TicketDetailsView',
127
+ components: {
128
+ TicketDetailsFlow,
129
+ JsonViewer,
130
+ XTable
131
+ },
132
+ data () {
133
+ return {
134
+ // 页面宽度
135
+ screenWidth: document.documentElement.clientWidth,
136
+ // 工单详情
137
+ details: {
138
+ // 当前负责人ID
139
+ id: undefined,
140
+ name: '',
141
+ uploader: '',
142
+ status: undefined,
143
+ priority: undefined,
144
+ description: '',
145
+ created_time: '',
146
+ confirm_time: '',
147
+ finished_time: '',
148
+ category: '',
149
+ serial_number: ''
150
+ },
151
+ // 当前步骤
152
+ step: 0,
153
+ // 校验转移员工是否存在
154
+ transferCheck: false,
155
+ // 移交工单窗口可见性
156
+ transVisible: false,
157
+ // 转移工单对象
158
+ transferTo: '',
159
+ // 新增留言
160
+ note: '',
161
+ // 控制关闭订单按钮可用性
162
+ disableCloseBtn: false,
163
+ // 控制关闭工单确认框显示
164
+ closeVisible: false,
165
+ // 控制加载过程
166
+ loadTicketDetails: false,
167
+ // 工单类型字典
168
+ categoryDictionary: []
169
+ }
170
+ },
171
+ mounted () {
172
+ this.getTicketCategory()
173
+ this.initView()
174
+ },
175
+ computed: {
176
+ ...mapState('account', { currUser: 'user' }),
177
+ ...mapState('setting', ['isMobile'])
178
+ },
179
+ props: {
180
+ ticketId: {
181
+ type: String,
182
+ required: true
183
+ },
184
+ visible: {
185
+ type: Boolean,
186
+ default: false
187
+ }
188
+ },
189
+ methods: {
190
+ // 初始化组件
191
+ initView () {
192
+ this.loadTicketDetails = true
193
+ this.getTicketDetail(this.ticketId)
194
+ this.loadTicketDetails = false
195
+ },
196
+ // 解析工单类型
197
+ resolveCategory (key) {
198
+ for (let i = 0; i < this.categoryDictionary.length; i++) {
199
+ if (this.categoryDictionary[i].value == key) {
200
+ return this.categoryDictionary[i].name
201
+ }
202
+ }
203
+ },
204
+ // 关闭工单确认后业务逻辑
205
+ handleCloseOk () {
206
+ return post(TicketDetailsViewApi.manualCloseTicket, {
207
+ ticketId: this.ticketId,
208
+ time: new Date()
209
+ })
210
+ .then(res => {
211
+ if (res !== 0) {
212
+ this.$message.success(
213
+ '操作成功',
214
+ 5
215
+ )
216
+ this.initView()
217
+ this.closeVisible = false
218
+ } else {
219
+ this.$message.error(
220
+ '操作失败',
221
+ 5
222
+ )
223
+ }
224
+ }, err => {
225
+ console.error(err)
226
+ })
227
+ },
228
+ // 关闭工单取消后业务逻辑
229
+ handleCloseCancel () {
230
+ this.closeVisible = false
231
+ },
232
+ // 确认工单按钮业务逻辑
233
+ confirmTicketBtn () {
234
+ const currentEmpId = this.getCurrentEmpId()
235
+ return post(TicketDetailsViewApi.confirmTicket, {
236
+ ticketId: this.ticketId,
237
+ empId: currentEmpId,
238
+ time: new Date()
239
+ })
240
+ .then(res => {
241
+ if (res !== 0) {
242
+ this.$message.success(
243
+ '操作成功',
244
+ 5
245
+ )
246
+ this.initView()
247
+ } else {
248
+ this.$message.error(
249
+ '操作失败',
250
+ 5
251
+ )
252
+ }
253
+ }, err => {
254
+ console.error(err)
255
+ })
256
+ },
257
+ // 获取当前登陆员工ID
258
+ getCurrentEmpId () {
259
+ return this.currUser.id
260
+ },
261
+ // 转移工单按钮业务逻辑
262
+ transferBtn () {
263
+ this.transVisible = true
264
+ },
265
+ checkEmp () {
266
+ return post(EmployeeDetailsViewApi.findEmpName, {
267
+ empName: this.transferTo
268
+ })
269
+ .then(res => {
270
+ const num = res.number
271
+ this.transferCheck = num !== 0
272
+ }, err => {
273
+ console.error(err)
274
+ })
275
+ },
276
+ // 获取工单状态撤销or关闭
277
+ getStatus () {
278
+ if (this.details.status === 2) {
279
+ return '已撤销'
280
+ } else {
281
+ return '已关闭'
282
+ }
283
+ },
284
+ // 关闭工单按钮业务逻辑
285
+ closeBtn () {
286
+ this.closeVisible = true
287
+ },
288
+ // 转移工单确认后逻辑
289
+ handleTransferOk () {
290
+ if (!this.transferCheck) {
291
+ this.$message.error(
292
+ '请先检查您输入的员工名',
293
+ 2
294
+ )
295
+ } else {
296
+ return post(TicketDetailsViewApi.transferTicketToOthers, {
297
+ ticketId: this.ticketId,
298
+ endTime: new Date(),
299
+ transferTo: this.transferTo,
300
+ note: this.note
301
+ })
302
+ .then(res => {
303
+ const result = res
304
+ this.note = ''
305
+ this.transVisible = false
306
+ if (result === 1) {
307
+ this.$message.success(
308
+ '操作成功',
309
+ 5
310
+ )
311
+ this.initView()
312
+ } else {
313
+ this.$message.error(
314
+ '操作失败',
315
+ 5
316
+ )
317
+ }
318
+ this.handleCancel()
319
+ this.initView()
320
+ }, err => {
321
+ console.error(err)
322
+ this.transVisible = false
323
+ })
324
+ }
325
+ },
326
+ // 转移工单取消后逻辑
327
+ handleTransferCancel () {
328
+ this.transferTo = ''
329
+ this.note = ''
330
+ this.transVisible = false
331
+ this.transferCheck = false
332
+ },
333
+ // 关闭抽屉时回调
334
+ onClose () {
335
+ this.disableCloseBtn = false
336
+ this.$emit('update:visible', false)
337
+ },
338
+ // 获取工单详情信息
339
+ getTicketDetail (num) {
340
+ this.loadTicketDetails = true
341
+ return post(TicketDetailsViewApi.getTicketDetails, {
342
+ ticketId: num
343
+ })
344
+ .then(res => {
345
+ this.details = res[0]
346
+ this.step = res[0].status
347
+ if (this.details.status === 3) {
348
+ this.disableCloseBtn = true
349
+ }
350
+ const categoryValue = this.details.category
351
+ this.details.category = this.resolveCategory(categoryValue)
352
+ }, err => {
353
+ console.error(err)
354
+ })
355
+ },
356
+ // 获取工单类别字典
357
+ getTicketCategory () {
358
+ return post(TicketDetailsViewApi.getTicketCategoryDictionary)
359
+ .then(res => {
360
+ this.categoryDictionary = res
361
+ }, err => {
362
+ console.log(err)
363
+ })
364
+ },
365
+ // 日期格式化
366
+ format (date, format) {
367
+ return formatDate(date, format)
368
+ },
369
+ // 转换JSON
370
+ toJSON (value) {
371
+ try {
372
+ return JSON.parse(value)
373
+ } catch (e) {
374
+ return value
375
+ }
376
+ },
377
+ // 控制开始处理按钮可用状态
378
+ handlerBtnDisable () {
379
+ return this.step !== 0
380
+ },
381
+ // 控制移交他人按钮可用状态
382
+ transferBtnDisable () {
383
+ return this.step === 0
384
+ },
385
+ // 控制关闭工单按钮可用状态
386
+ closeBtnDisable () {
387
+ return this.step === 0 || this.disableCloseBtn || this.details.id != this.currUser.id
388
+ },
389
+ // 优先级文字显示
390
+ showPriority () {
391
+ if (this.details.priority === 2) {
392
+ return '一般'
393
+ } else if (this.details.priority === 1) {
394
+ return '紧急'
395
+ } else {
396
+ return '非常紧急'
397
+ }
398
+ },
399
+ // 优先度颜色控制
400
+ showPriorityColorControl () {
401
+ if (this.details.priority === 2) {
402
+ return 'info'
403
+ } else if (this.details.priority === 1) {
404
+ return 'warning'
405
+ } else {
406
+ return 'error'
407
+ }
408
+ }
409
+ },
410
+ watch: {
411
+ 'visible' (val) {
412
+ if (val) {
413
+ this.initView()
414
+ }
415
+ }
416
+ }
417
+ }
418
+ </script>
419
+
420
+ <style lang="less" scoped>
421
+ .high-priority{
422
+ background-color: rgba(163, 30, 30, 0.66);
423
+ border: red solid 1px;
424
+ font-size: large;
425
+ padding: 5px;
426
+ color: white;
427
+ border-radius: 10px;
428
+ }
429
+
430
+ .detail-layout {
431
+ margin-left: 44px;
432
+ }
433
+ .text {
434
+ color: rgba(0, 0, 0, .45);
435
+ }
436
+
437
+ .heading {
438
+ color: rgba(0, 0, 0, .85);
439
+ font-size: 20px;
440
+ }
441
+
442
+ .no-data {
443
+ color: rgba(0, 0, 0, .25);
444
+ text-align: center;
445
+ line-height: 64px;
446
+ font-size: 16px;
447
+
448
+ i {
449
+ font-size: 24px;
450
+ margin-right: 16px;
451
+ position: relative;
452
+ top: 3px;
453
+ }
454
+ }
455
+
456
+ .mobile {
457
+ .detail-layout {
458
+ margin-left: unset;
459
+ }
460
+ .text {
461
+
462
+ }
463
+ .status-list {
464
+ text-align: left;
465
+ }
466
+ }
467
+
468
+ .row {
469
+ display: flex;
470
+
471
+ .content {
472
+ -webkit-box-flex: 1;
473
+ flex: auto;
474
+ -ms-flex: auto;
475
+ }
476
+
477
+ .extra {
478
+ flex: 0 1 auto;
479
+ -webkit-box-flex: 0;
480
+ -ms-flex: 0 1 auto;
481
+ min-width: 242px;
482
+ margin-left: 88px;
483
+ text-align: right;
484
+ }
485
+ }
486
+ </style>