vue2-client 1.2.0 → 1.2.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.
Files changed (134) hide show
  1. package/README.md +65 -65
  2. package/babel.config.js +1 -0
  3. package/docs/notice.md +22 -0
  4. package/index.js +28 -28
  5. package/package.json +1 -1
  6. package/src/App.vue +93 -93
  7. package/src/assets/img/SunClientDownload.png +0 -0
  8. package/src/assets/img/SunClientManual/1.png +0 -0
  9. package/src/assets/img/SunClientManual/2.png +0 -0
  10. package/src/assets/img/SunClientManual/3.png +0 -0
  11. package/src/assets/img/SunClientManual/4.png +0 -0
  12. package/src/assets/img/ToDeskDownload.png +0 -0
  13. package/src/assets/img/ToDeskManual/1.png +0 -0
  14. package/src/assets/img/ToDeskManual/2.png +0 -0
  15. package/src/assets/img/ToDeskManual/3.png +0 -0
  16. package/src/assets/img/ToDeskManual/4.png +0 -0
  17. package/src/assets/sound/newNote.mp3 +0 -0
  18. package/src/base-client/all.js +57 -57
  19. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +1157 -1159
  20. package/src/base-client/components/common/CreateQuery/index.md +42 -42
  21. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQuery.vue +540 -540
  22. package/src/base-client/components/common/CreateSimpleFormQuery/index.md +42 -42
  23. package/src/base-client/components/common/CustomColumnsDrawer/index.md +46 -46
  24. package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +150 -150
  25. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  26. package/src/base-client/components/common/FormGroupQuery/index.md +43 -43
  27. package/src/base-client/components/common/XAddForm/XAddForm.vue +323 -323
  28. package/src/base-client/components/common/XAddForm/index.md +60 -60
  29. package/src/base-client/components/common/XBadge/index.md +39 -39
  30. package/src/base-client/components/common/XCard/index.md +43 -43
  31. package/src/base-client/components/common/XForm/XForm.vue +275 -275
  32. package/src/base-client/components/common/XForm/XFormItem.vue +217 -217
  33. package/src/base-client/components/common/XForm/index.md +196 -196
  34. package/src/base-client/components/common/XFormCol/index.md +35 -35
  35. package/src/base-client/components/common/XFormTable/XFormTable.vue +407 -405
  36. package/src/base-client/components/common/XFormTable/index.md +89 -89
  37. package/src/base-client/components/common/XTable/XTable.vue +262 -262
  38. package/src/base-client/components/common/XTable/index.md +255 -255
  39. package/src/base-client/components/common/XTreeOne/XTreeOne.vue +105 -105
  40. package/src/base-client/components/iot/CustomerDetailsView/CustomerDetailsView.vue +226 -226
  41. package/src/base-client/components/iot/CustomerDetailsView/index.md +41 -41
  42. package/src/base-client/components/iot/DataAnalysisUser/DataAnalysisUser.vue +127 -127
  43. package/src/base-client/components/iot/DataAnalysisView/DataAnalysisView.vue +244 -250
  44. package/src/base-client/components/iot/DataAnalysisViewGD/DataAnalysisViewGD.vue +548 -548
  45. package/src/base-client/components/iot/DeviceBrandDetailsView/DeviceBrandDetailsView.vue +453 -453
  46. package/src/base-client/components/iot/DeviceDetailsView/DeviceDetailsView.vue +231 -231
  47. package/src/base-client/components/iot/DeviceDetailsView/index.md +43 -43
  48. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsCount.vue +330 -330
  49. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsException.vue +57 -57
  50. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsInstruct.vue +122 -122
  51. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsInstructOperate.vue +122 -122
  52. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsMain.vue +225 -225
  53. package/src/base-client/components/iot/DeviceDetailsView/part/DeviceDetailsRead.vue +135 -135
  54. package/src/base-client/components/iot/DeviceTypeDetailsView/DeviceTypeDetailsView.vue +277 -277
  55. package/src/base-client/components/iot/InstructDetailsView/InstructDetailsView.vue +472 -472
  56. package/src/base-client/components/iot/InstructDetailsView/index.md +45 -45
  57. package/src/base-client/components/iot/LogDetailsView/LogDetailsView.vue +380 -380
  58. package/src/base-client/components/iot/LogDetailsView/index.md +43 -43
  59. package/src/base-client/components/iot/MeterDetailsView/MeterDetailsView.vue +360 -360
  60. package/src/base-client/components/iot/MeterDetailsView/index.md +43 -43
  61. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsCount.vue +335 -335
  62. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsException.vue +185 -185
  63. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsHandPlan.vue +292 -292
  64. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsInstruct.vue +237 -237
  65. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsMain.vue +257 -257
  66. package/src/base-client/components/iot/MeterDetailsView/part/MeterDetailsSellGas.vue +190 -190
  67. package/src/base-client/components/iot/WebmeterAnalysisView/WebmeterAnalysisView.vue +723 -723
  68. package/src/base-client/components/iot/WebmeterAnalysisView/index.md +48 -48
  69. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  70. package/src/base-client/components/system/DictionaryDetailsView/index.md +41 -41
  71. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +248 -248
  72. package/src/base-client/components/ticket/EmployeeDetailsView/EmployeeDetailsView.vue +371 -406
  73. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +838 -486
  74. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +261 -184
  75. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +528 -303
  76. package/src/base-client/plugins/AppData.js +69 -69
  77. package/src/base-client/plugins/GetLoginInfoService.js +221 -221
  78. package/src/base-client/plugins/index.js +21 -21
  79. package/src/bootstrap.js +27 -27
  80. package/src/components/Ellipsis/Ellipsis.vue +64 -64
  81. package/src/components/Ellipsis/index.md +38 -38
  82. package/src/components/NumberInfo/index.md +43 -43
  83. package/src/components/STable/README.md +341 -341
  84. package/src/components/Trend/index.md +45 -45
  85. package/src/components/cache/AKeepAlive.js +172 -172
  86. package/src/components/checkbox/index.js +7 -7
  87. package/src/components/index.js +36 -36
  88. package/src/components/menu/menu.js +273 -273
  89. package/src/components/setting/Setting.vue +237 -237
  90. package/src/components/table/advance/AdvanceTable.vue +275 -275
  91. package/src/components/transition/PageToggleTransition.vue +97 -97
  92. package/src/layouts/CommonLayout.vue +42 -42
  93. package/src/layouts/PageLayout.vue +151 -151
  94. package/src/layouts/SinglePageView.vue +74 -74
  95. package/src/layouts/header/AdminHeader.vue +109 -109
  96. package/src/layouts/header/HeaderAvatar.vue +60 -60
  97. package/src/layouts/header/HeaderNotice.vue +97 -97
  98. package/src/layouts/tabs/TabsHead.vue +190 -190
  99. package/src/layouts/tabs/TabsView.vue +355 -355
  100. package/src/main.js +20 -20
  101. package/src/mock/goods/index.js +108 -108
  102. package/src/mock/index.js +12 -12
  103. package/src/mock/project/index.js +17 -17
  104. package/src/mock/user/current.js +13 -13
  105. package/src/mock/user/login.js +39 -39
  106. package/src/mock/workplace/index.js +15 -15
  107. package/src/pages/exception/403.vue +25 -25
  108. package/src/pages/exception/404.vue +25 -25
  109. package/src/pages/exception/500.vue +25 -25
  110. package/src/pages/login/Login.vue +194 -194
  111. package/src/pages/report/ReportTableHome.vue +28 -28
  112. package/src/pages/resourceManage/resourceManageMain.vue +55 -55
  113. package/src/pages/system/applyInstallView/Core.vue +570 -570
  114. package/src/pages/system/applyInstallView/index.vue +34 -34
  115. package/src/pages/system/dictionary/index.vue +41 -41
  116. package/src/pages/system/queryParams/index.vue +41 -41
  117. package/src/router/async/config.async.js +25 -25
  118. package/src/router/async/router.map.js +59 -59
  119. package/src/router/guards.js +104 -104
  120. package/src/router/index.js +27 -27
  121. package/src/services/api/EmployeeDetailsViewApi.js +3 -1
  122. package/src/services/api/TicketDetailsViewApi.js +9 -1
  123. package/src/services/api/common.js +37 -39
  124. package/src/services/api/restTools.js +23 -23
  125. package/src/services/dataSource.js +12 -12
  126. package/src/services/user.js +34 -34
  127. package/src/store/modules/setting.js +114 -114
  128. package/src/utils/i18n.js +80 -80
  129. package/src/utils/indexedDB.js +146 -146
  130. package/src/utils/request.js +197 -197
  131. package/src/utils/routerUtil.js +15 -2
  132. package/tests/unit/ReportTable.spec.js +15 -15
  133. package/vue.config.js +153 -153
  134. package/webpack.config.js +12 -12
@@ -1,303 +1,528 @@
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-card class="result-success" :bordered="false">
10
- <result :is-success="icon" :description="description" :title="title" :title-class="titleClass">
11
- <template slot="action">
12
- <span style="margin-right: 10px" v-if="countDown > 0">{{ countDownFormat() }}</span>
13
- <a-tooltip placement="topLeft" :title="tip" arrow-point-at-center>
14
- <a-button type="primary" v-if="UrgentAvailable" :disabled="urgentAccess" style="margin-right: 20px" @click="urgent">请求加急处理</a-button>
15
- </a-tooltip>
16
- <a-button type="danger" @click="closeBtn" >撤销工单</a-button>
17
- </template>
18
- <a-modal
19
- title="关闭工单"
20
- :visible="closeVisible"
21
- @ok="handleCloseOk"
22
- @cancel="handleCloseCancel"
23
- :zIndex="1002"
24
- >
25
- <p>是否确认手动关闭工单?</p>
26
- <p style="color: red">(该操作不可撤销,请谨慎操作!)</p>
27
- </a-modal>
28
- <div>
29
- <div class="project-name">工单处理进度</div>
30
- <detail-list size="small" style="max-width: 800px; margin-bottom: 8px">
31
- <detail-list-item term="工单编号">{{ serialNumber }}</detail-list-item>
32
- <detail-list-item term="提交时间">{{ format(details.createdTime, 'yyyy-MM-dd') }}</detail-list-item>
33
- </detail-list>
34
- <a-steps :current="step" progressDot>
35
- <a-step title="工单提交">
36
- <a-step-item-group slot="description">
37
- <a-step-item :title="details.uploader" />
38
- <a-step-item :title="details.createdTime"/>
39
- </a-step-item-group>
40
- </a-step>
41
- <a-step title="工单处理中" >
42
- <a-step-item-group slot="description">
43
- <a-step-item :title="details.name" v-if="step >= 1" />
44
- <a-step-item :title="details.confirmTime" v-if="step >= 1"/>
45
- </a-step-item-group>
46
- </a-step>
47
- <a-step title="工单完成" >
48
- <a-step-item-group slot="description">
49
- <a-step-item :title="details.finishedTime" v-if="step >= 2"/>
50
- </a-step-item-group>
51
- </a-step>
52
- </a-steps>
53
- </div>
54
- </result>
55
- </a-card>
56
- </a-drawer>
57
- </template>
58
-
59
- <script>
60
- import Result from '@vue2-client/components/result/Result'
61
- import DetailList from '@vue2-client/components/tool/DetailList'
62
- import AStepItem from '@vue2-client/components/tool/AStepItem'
63
- import { TicketDetailsViewApi } from '@vue2-client/services/api/TicketDetailsViewApi'
64
- import { post } from '@vue2-client/services/api/restTools'
65
- import { mapState } from 'vuex'
66
- import { formatDate } from '@vue2-client/utils/util'
67
-
68
- const AStepItemGroup = AStepItem.Group
69
- const DetailListItem = DetailList.Item
70
- export default {
71
- name: 'submitTicketSuccess',
72
- components: { AStepItemGroup, AStepItem, DetailListItem, DetailList, Result },
73
- data () {
74
- return {
75
- // 页面宽度
76
- screenWidth: document.documentElement.clientWidth,
77
- title: '提交成功',
78
- description: '您创建的工单已成功提交,请保持电话畅通,我们的工作人员将尽快与您取得联系',
79
- // 加急按钮气泡文字
80
- tip: '如果需要加急,请在5分钟倒计时结束后点击加急按钮,加急后我们将优先处理您的工单',
81
- // 控制标题样式
82
- titleClass: 'title',
83
- // 工单详情
84
- details: {
85
- uploader: '',
86
- status: '',
87
- name: '',
88
- priority: undefined,
89
- createdTime: '',
90
- confirmTime: '',
91
- finishedTime: ''
92
- },
93
- // 控制加急按钮
94
- urgentAccess: true,
95
- // 倒计时
96
- countDown: 0,
97
- // 控制加急按钮显示
98
- UrgentAvailable: true,
99
- // 刷新页面的定时器
100
- timer: undefined,
101
- // 取消工单确认框可见性
102
- closeVisible: false,
103
- // 控制页面大图标
104
- icon: true,
105
- // 控制加急后定时器
106
- showTelephoneCountDown: 0
107
- }
108
- },
109
- props: {
110
- serialNumber: {
111
- type: String,
112
- required: true
113
- },
114
- visible: {
115
- type: Boolean,
116
- default: false
117
- }
118
- },
119
- mounted () {
120
- this.getTicketDetail()
121
- this.refresh()
122
- this.countDown = 0
123
- },
124
- methods: {
125
- // 关闭抽屉时回调
126
- onClose () {
127
- this.urgentAccess = true
128
- clearInterval(this.timer)
129
- this.$emit('update:visible', false)
130
- this.titleClass = 'title'
131
- this.description = '您创建的工单已成功提交,请保持电话畅通,我们的工作人员将尽快与您取得联系'
132
- this.title = '提交成功'
133
- this.UrgentAvailable = true
134
- },
135
- format (date, format) {
136
- return formatDate(date, format)
137
- },
138
- // 关闭工单确认后操作
139
- handleCloseOk () {
140
- return post(TicketDetailsViewApi.manualCloseTicketByCustomer, {
141
- serialNumber: this.serialNumber,
142
- time: new Date()
143
- })
144
- .then(res => {
145
- this.closeVisible = false
146
- this.title = '工单已关闭'
147
- this.description = ''
148
- this.icon = false
149
- clearInterval(this.timer)
150
- }, err => {
151
- console.error(err)
152
- })
153
- },
154
- // 关闭工单取消后业务逻辑
155
- handleCloseCancel () {
156
- this.closeVisible = false
157
- },
158
- // 关闭工单按钮
159
- closeBtn () {
160
- this.closeVisible = true
161
- },
162
- // 过10s刷新一下页面数据
163
- refresh () {
164
- this.timer = setInterval(() => {
165
- this.getTicketDetail()
166
- }, 10 * 1000)
167
- },
168
- // 对工单进行加急处理
169
- urgent () {
170
- return post(TicketDetailsViewApi.rushTicket, {
171
- serialNumber: this.serialNumber
172
- })
173
- .then(res => {
174
- if (res === 1) {
175
- this.$message.success(
176
- '操作成功',
177
- 5
178
- )
179
- this.title = '加急成功'
180
- this.titleClass = 'title_danger'
181
- this.description = '您的工单已经被加急处理,我们的工作人员会马上与您取得联系'
182
- this.UrgentAvailable = false
183
- this.showPhoneNumberTimer()
184
- } else {
185
- this.$message.error(
186
- '操作失败',
187
- 5
188
- )
189
- }
190
- }, err => {
191
- console.log(err)
192
- })
193
- },
194
- // 格式化倒计时
195
- countDownFormat () {
196
- const hours = '00'
197
- let mins = Math.floor(this.countDown / 60)
198
- let secs = this.countDown % 60
199
- if (mins < 10) {
200
- mins = '0' + mins
201
- }
202
- if (secs < 10) {
203
- secs = '0' + secs
204
- }
205
- return hours + ':' + mins + ':' + secs
206
- },
207
- // 设置用于控制加急按钮倒计时定时器,加急按钮5分钟后才可点击
208
- setTimer () {
209
- this.countDown = 5
210
- const time = setInterval(() => {
211
- this.countDown--
212
- if (this.countDown <= 0) {
213
- this.urgentAccess = false
214
- clearInterval(time)
215
- this.countDown = -1
216
- }
217
- }, 1000)
218
- },
219
- // 设定关于加急后的定时器,5分钟后仍没人联系,显示联系电话
220
- showPhoneNumberTimer () {
221
- this.showTelephoneCountDown = 5
222
- const time = setInterval(() => {
223
- this.showTelephoneCountDown--
224
- if (this.showTelephoneCountDown <= 0) {
225
- this.description = '很抱歉让您久等,029-88888888 您可以直接拨打此电话,与我们技术人员直接交谈!'
226
- clearInterval(time)
227
- this.showTelephoneCountDown = -1
228
- }
229
- }, 1000)
230
- },
231
- // 获取工单详情
232
- getTicketDetail () {
233
- return post(TicketDetailsViewApi.getTicketDetailsForUploader, {
234
- serialNumber: this.serialNumber
235
- })
236
- .then(res => {
237
- this.details.uploader = res.uploader
238
- // 判断负责人有没有值
239
- if (res.name === undefined) {
240
- this.details.name = ''
241
- } else {
242
- this.details.name = res.name
243
- }
244
- // 判断工单被确认时间
245
- if (res.confirmtime === undefined) {
246
- this.details.confirmTime = ''
247
- } else {
248
- this.details.confirmTime = this.format(res.confirmtime, 'yyyy-MM-dd hh:mm:ss')
249
- }
250
- // 判断工单完成时间
251
- if (res.finishedtime === undefined) {
252
- this.details.finishedTime = ''
253
- } else {
254
- this.details.finishedTime = this.format(res.finishedtime, 'yyyy-MM-dd hh:mm:ss')
255
- }
256
- this.details.createdTime = this.format(res.createdtime, 'yyyy-MM-dd hh:mm:ss')
257
- this.details.status = res.status
258
- this.details.priority = res.priority
259
-
260
- // 如果当前状态为一般,设置定时器,五分钟后允许加急
261
- if (this.details.priority > 1 && this.countDown === 0) {
262
- this.setTimer()
263
- }
264
- }, err => {
265
- console.log(err)
266
- })
267
- }
268
- },
269
- computed: {
270
- ...mapState('account', { currUser: 'user' }),
271
- ...mapState('setting', ['isMobile']),
272
- // 用于进度条,进度显示控制
273
- step () {
274
- if (this.details.status !== 0 && this.details.status !== 1) {
275
- return 2
276
- } else {
277
- return this.details.status
278
- }
279
- }
280
- },
281
- watch: {
282
- 'serialNumber' () {
283
- this.getTicketDetail()
284
- this.refresh()
285
- this.countDown = 0
286
- }
287
- }
288
- }
289
- </script>
290
-
291
- <style scoped lang="less">
292
- .result-success{
293
- .action:not(:first-child){
294
- margin-left: 8px;
295
- }
296
- .project-name{
297
- font-size: 16px;
298
- color: @title-color;
299
- font-weight: 500;
300
- margin-bottom: 20px;
301
- }
302
- }
303
- </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
+ <!-- 添加描述弹框 -->
10
+ <a-modal
11
+ title="追加问题描述"
12
+ :visible="addOnVisible"
13
+ @ok="handleAddOn"
14
+ @cancel="handleCancelAddOn"
15
+ :zIndex="1001"
16
+ >
17
+ <a-form-model-item label="描述">
18
+ <a-input v-model="desc" type="textarea" />
19
+ </a-form-model-item>
20
+ <div class="clearfix">
21
+ <a-upload
22
+ name="avatar"
23
+ list-type="picture-card"
24
+ :before-upload="beforeUpload"
25
+ action="/webmeteruploadapi/upload"
26
+ :file-list="fileList"
27
+ @preview="handlePreview"
28
+ @change="handleChange"
29
+ :remove="remove"
30
+ >
31
+ <div v-if="fileList.length < 5">
32
+ <a-icon type="plus" />
33
+ <div class="ant-upload-text">点击上传</div>
34
+ </div>
35
+ </a-upload>
36
+ <a-modal
37
+ :visible="previewVisible"
38
+ :footer="null"
39
+ @cancel="handleCancel"
40
+ >
41
+ <img style="width: 100%" :src="previewImage" alt="图片上传"/>
42
+ </a-modal>
43
+ </div>
44
+ </a-modal>
45
+ <a-card class="result-success" :bordered="false">
46
+ <result :is-success="icon" :description="getDescription()" :title="getTitle()" :title-class="titleClass">
47
+ <template slot="action">
48
+ <a-space v-show="btnGroup">
49
+ <!--<a-tooltip placement="topLeft" :title="tip" arrow-point-at-center>-->
50
+ <!-- <a-button type="primary" v-if="UrgentAvailable && details.status === 0 && details.priority === 2" :disabled="urgentAccess" @click="urgent">请求加急处理</a-button>-->
51
+ <!--</a-tooltip>-->
52
+ <a-button type="primary" @click="addOnVisible = true" >追加问题描述</a-button>
53
+ <a-button type="danger" @click="closeBtn" >撤销工单</a-button>
54
+ </a-space>
55
+ <a-button v-show="!btnGroup" type="primary" @click="onClose">返回</a-button>
56
+ </template>
57
+ <a-modal
58
+ title="关闭工单"
59
+ :visible="closeVisible"
60
+ @ok="handleCloseOk"
61
+ @cancel="handleCloseCancel"
62
+ :zIndex="1002"
63
+ >
64
+ <p>是否确认手动关闭工单?</p>
65
+ <p style="color: red">(该操作不可撤销,请谨慎操作!)</p>
66
+ </a-modal>
67
+ <div>
68
+ <div class="project-name">工单处理进度</div>
69
+ <detail-list size="small" style="max-width: 800px; margin-bottom: 8px">
70
+ <detail-list-item term="工单编号">{{ serialNumber }}</detail-list-item>
71
+ <detail-list-item term="提交时间">{{ format(details.createdTime, 'yyyy-MM-dd') }}</detail-list-item>
72
+ </detail-list>
73
+ <a-steps :current="step" progressDot>
74
+ <a-step title="工单提交">
75
+ <a-step-item-group slot="description">
76
+ <a-step-item :title="details.uploader" />
77
+ <a-step-item :title="details.createdTime"/>
78
+ </a-step-item-group>
79
+ </a-step>
80
+ <a-step title="工单处理中" >
81
+ <a-step-item-group slot="description">
82
+ <a-step-item :title="details.name" v-if="step >= 1" />
83
+ <a-step-item :title="details.confirmTime" v-if="step >= 1"/>
84
+ </a-step-item-group>
85
+ </a-step>
86
+ <a-step title="工单完成" >
87
+ <a-step-item-group slot="description">
88
+ <a-step-item :title="details.finishedTime" v-if="step >= 2"/>
89
+ </a-step-item-group>
90
+ </a-step>
91
+ </a-steps>
92
+ </div>
93
+ </result>
94
+ </a-card>
95
+ </a-drawer>
96
+ </template>
97
+
98
+ <script>
99
+ import Result from '@vue2-client/components/result/Result'
100
+ import DetailList from '@vue2-client/components/tool/DetailList'
101
+ import AStepItem from '@vue2-client/components/tool/AStepItem'
102
+ import { TicketDetailsViewApi } from '@vue2-client/services/api/TicketDetailsViewApi'
103
+ import { post } from '@vue2-client/services/api/restTools'
104
+ import { mapState } from 'vuex'
105
+ import { formatDate } from '@vue2-client/utils/util'
106
+ function getBase64 (file) {
107
+ return new Promise((resolve, reject) => {
108
+ const reader = new FileReader()
109
+ reader.readAsDataURL(file)
110
+ reader.onload = () => resolve(reader.result)
111
+ reader.onerror = error => reject(error)
112
+ })
113
+ }
114
+
115
+ const AStepItemGroup = AStepItem.Group
116
+ const DetailListItem = DetailList.Item
117
+ export default {
118
+ name: 'submitTicketSuccess',
119
+ components: { AStepItemGroup, AStepItem, DetailListItem, DetailList, Result },
120
+ data () {
121
+ return {
122
+ // 页面宽度
123
+ screenWidth: document.documentElement.clientWidth,
124
+ title: '',
125
+ description: '',
126
+ // 控制标题样式
127
+ titleClass: 'title',
128
+ // 工单详情
129
+ details: {
130
+ uploader: '',
131
+ status: '',
132
+ name: '',
133
+ priority: undefined,
134
+ createdTime: '',
135
+ confirmTime: '',
136
+ finishedTime: '',
137
+ createdTimestamp: undefined
138
+ },
139
+ // 控制加急按钮
140
+ urgentAccess: true,
141
+ // 倒计时
142
+ countDown: 0,
143
+ // 控制加急按钮显示
144
+ UrgentAvailable: true,
145
+ // 刷新页面的定时器
146
+ timer: undefined,
147
+ // 取消工单确认框可见性
148
+ closeVisible: false,
149
+ // 控制页面大图标
150
+ icon: true,
151
+ // 控制加急后定时器
152
+ showTelephoneCountDown: 0,
153
+ // 控制预览显示
154
+ previewVisible: false,
155
+ // 图片真实地址
156
+ previewImage: '',
157
+ // 图片列表
158
+ fileList: [],
159
+ // 控制添加描述框显示
160
+ addOnVisible: false,
161
+ // 描述
162
+ desc: '',
163
+ // 等待时间计时器
164
+ waitTimer: undefined,
165
+ // 控制三个按钮显示
166
+ btnGroup: true,
167
+ // 控制工单关闭后标题显示
168
+ titleEnd: 0,
169
+ // 控制显示文字
170
+ descriptionUrgentLevel: 0
171
+ }
172
+ },
173
+ props: {
174
+ serialNumber: {
175
+ type: String,
176
+ required: true
177
+ },
178
+ visible: {
179
+ type: Boolean,
180
+ default: false
181
+ },
182
+ categoryStr: {
183
+ type: String,
184
+ required: true
185
+ }
186
+ },
187
+ mounted () {
188
+ this.initView()
189
+ },
190
+ methods: {
191
+ initView () {
192
+ this.getTicketDetail()
193
+ this.refresh()
194
+ this.titleClass = 'title'
195
+ this.countDown = 0
196
+ },
197
+ // 提交添加描述
198
+ handleAddOn () {
199
+ return post(TicketDetailsViewApi.AddonDescriptionToTicket, {
200
+ description: this.desc,
201
+ fileList: this.fileList,
202
+ serialNumber: this.serialNumber
203
+ })
204
+ .then(res => {
205
+ this.$message.success('提交成功!')
206
+ this.desc = ''
207
+ this.fileList = []
208
+ this.addOnVisible = false
209
+ }, err => {
210
+ console.log(err)
211
+ })
212
+ },
213
+ // 放弃添加
214
+ handleCancelAddOn () {
215
+ return post(TicketDetailsViewApi.removeAllImages, {
216
+ fileList: this.fileList
217
+ })
218
+ .then(res => {
219
+ this.desc = ''
220
+ this.fileList = []
221
+ this.addOnVisible = false
222
+ }, err => {
223
+ console.log(err)
224
+ })
225
+ },
226
+ // 图像修改检测
227
+ handleChange ({ fileList }) {
228
+ this.fileList = fileList.filter((item) => {
229
+ return item.status === 'done' || item.status === 'uploading'
230
+ })
231
+ },
232
+ // 在上传页面,点击图片上的垃圾桶,撤销上传
233
+ remove (file) {
234
+ return post(TicketDetailsViewApi.revocationImage, {
235
+ file: file
236
+ })
237
+ .then(res => {
238
+ if (res === 'success') {
239
+ this.$message.success('删除成功')
240
+ }
241
+ this.fileList = this.fileList.filter((item) => {
242
+ return item.response.name !== file.response.name
243
+ })
244
+ }, err => {
245
+ console.log(err)
246
+ })
247
+ },
248
+ // 上传头像前校验
249
+ beforeUpload (file) {
250
+ const isJpgOrPng =
251
+ file.type === 'image/jpeg' ||
252
+ file.type === 'image/jpg' ||
253
+ file.type === 'image/png'
254
+ const Lt2M = file.size / 1024 / 1024 < 2
255
+ if (!Lt2M) {
256
+ this.$message.error('图片不得大于2MB!')
257
+ }
258
+ if (!isJpgOrPng) {
259
+ this.$message.error('只能上传jpg/png格式的图片')
260
+ }
261
+ return isJpgOrPng && Lt2M
262
+ },
263
+ handleCancel () {
264
+ this.previewVisible = false
265
+ },
266
+ // 处理预览图像
267
+ async handlePreview (file) {
268
+ if (!file.url && !file.preview) {
269
+ file.preview = await getBase64(file.originFileObj)
270
+ }
271
+ this.previewImage = file.url || file.preview
272
+ this.previewVisible = true
273
+ },
274
+ // 关闭抽屉时回调
275
+ onClose () {
276
+ this.titleEnd = 0
277
+ this.urgentAccess = true
278
+ clearInterval(this.timer)
279
+ clearInterval(this.waitTimer)
280
+ this.timer = undefined
281
+ this.waitTimer = undefined
282
+ this.btnGroup = true
283
+ this.$emit('update:visible', false)
284
+ this.titleClass = 'title'
285
+ this.descriptionUrgentLevel = 0
286
+ this.title = '提交成功'
287
+ this.UrgentAvailable = true
288
+ },
289
+ format (date, format) {
290
+ return formatDate(date, format)
291
+ },
292
+ // 关闭工单确认后操作
293
+ handleCloseOk () {
294
+ return post(TicketDetailsViewApi.manualCloseTicketByCustomer, {
295
+ serialNumber: this.serialNumber,
296
+ time: new Date()
297
+ })
298
+ .then(res => {
299
+ this.closeVisible = false
300
+ this.details.status = 2
301
+ clearInterval(this.timer)
302
+ clearInterval(this.waitTimer)
303
+ this.timer = undefined
304
+ this.waitTimer = undefined
305
+ this.btnGroup = false
306
+ this.titleEnd = 1
307
+ this.getTicketDetail()
308
+ }, err => {
309
+ console.error(err)
310
+ })
311
+ },
312
+ // 关闭工单取消后业务逻辑
313
+ handleCloseCancel () {
314
+ this.closeVisible = false
315
+ },
316
+ // 关闭工单按钮
317
+ closeBtn () {
318
+ this.closeVisible = true
319
+ },
320
+ // 过10s刷新一下页面数据
321
+ refresh () {
322
+ if (this.timer === undefined) {
323
+ this.timer = setInterval(() => {
324
+ this.getTicketDetail()
325
+ }, 5000)
326
+ }
327
+ },
328
+ // 对工单进行加急处理
329
+ urgent () {
330
+ return post(TicketDetailsViewApi.rushTicket, {
331
+ serialNumber: this.serialNumber,
332
+ categoryStr: this.categoryStr
333
+ })
334
+ .then(res => {
335
+ if (res === 1) {
336
+ this.$message.success(
337
+ '已为您自动加急',
338
+ 5
339
+ )
340
+ this.details.priority = 1
341
+ this.UrgentAvailable = false
342
+ } else {
343
+ this.$message.error(
344
+ '自动加急失败',
345
+ 5
346
+ )
347
+ }
348
+ }, err => {
349
+ console.log(err)
350
+ })
351
+ },
352
+ // 格式化倒计时
353
+ countDownFormat () {
354
+ let mins = Math.floor(this.countDown / 60)
355
+ let secs = this.countDown % 60
356
+ if (mins < 10) {
357
+ mins = '0' + mins
358
+ }
359
+ if (secs < 10) {
360
+ secs = '0' + secs
361
+ }
362
+ return mins + ':' + secs
363
+ },
364
+ // 设置用于控制加急按钮倒计时定时器,加急按钮5分钟后才可点击
365
+ setTimer () {
366
+ this.countDown = this.timePass()
367
+ if (this.waitTimer === undefined) {
368
+ this.waitTimer = setInterval(() => {
369
+ this.countDown++
370
+ if (this.countDown >= 300 && this.details.priority === 2) {
371
+ this.urgent()
372
+ this.details.priority = 1
373
+ }
374
+ }, 1000)
375
+ }
376
+ },
377
+ // 获取显示文字内容
378
+ getDescription () {
379
+ if (this.details.status === 1) {
380
+ // 处理中
381
+ return '工单已被接受,请保持电话畅通。我们的工作人员正在尽快为您解决问题'
382
+ }
383
+ if (this.details.status >= 2) {
384
+ // 已关闭
385
+ return ''
386
+ }
387
+ // 已提交,判断优先级
388
+ if (this.details.priority >= 2) {
389
+ // 低优先级
390
+ // 判断用时
391
+ if (this.timePass() < 300) {
392
+ // 5分钟以内
393
+ return '您创建的工单已成功提交,请保持电话畅通,我们的工作人员将在5分钟内与您联系'
394
+ } else if (this.timePass() >= 300 && this.timePass() <= 600) {
395
+ // 5-10分钟
396
+ return '由于您的工单等待时间过长,系统已为您自动加急工单,请保持电话畅通,感谢您的理解'
397
+ } else {
398
+ // 超过十分钟
399
+ return '很抱歉让您久等,029-88888888 您可以直接拨打此电话,与我们技术人员直接交谈!'
400
+ }
401
+ } else {
402
+ // 高优先级
403
+ // 判断用时
404
+ if (this.timePass() < 300) {
405
+ // 5分钟以内
406
+ return '您的工单已经被加急处理,我们的工作人员会马上与您取得联系'
407
+ } else if (this.timePass() >= 300 && this.timePass() <= 600) {
408
+ // 5-10分钟
409
+ return '您的工单已经被加急处理,我们的工作人员会马上与您取得联系'
410
+ } else {
411
+ // 超过十分钟
412
+ return '很抱歉让您久等,029-88888888 您可以直接拨打此电话,与我们技术人员直接交谈!'
413
+ }
414
+ }
415
+ },
416
+ // 获取标题内容
417
+ getTitle () {
418
+ const titleTime = this.countDownFormat()
419
+ if (this.details.status === 1) {
420
+ // 处理中
421
+ this.titleClass = 'title'
422
+ return '工单正在处理中'
423
+ }
424
+ if (this.details.status >= 2) {
425
+ // 已关闭
426
+ this.titleClass = 'title'
427
+ return '工单已关闭'
428
+ }
429
+ // 已提交,判断优先级
430
+ if (this.details.priority >= 2) {
431
+ // 低优先级
432
+ this.titleClass = 'title'
433
+ return '已提交工单' + '\xa0\xa0\xa0\xa0\xa0(\xa0已等待\xa0\xa0' + titleTime + '\xa0)'
434
+ } else {
435
+ // 高优先级
436
+ this.titleClass = 'title_danger'
437
+ return '加急成功' + '\xa0\xa0\xa0\xa0\xa0(\xa0已等待\xa0\xa0' + titleTime + '\xa0)'
438
+ }
439
+ },
440
+ // 获取工单创建以来过了多久,单位:秒
441
+ timePass () {
442
+ const now = new Date().getTime()
443
+ return Math.floor((now - this.details.createdTimestamp) / 1000)
444
+ },
445
+ // 获取工单详情
446
+ getTicketDetail () {
447
+ return post(TicketDetailsViewApi.getTicketDetailsForUploader, {
448
+ serialNumber: this.serialNumber
449
+ })
450
+ .then(res => {
451
+ this.details.uploader = res.uploader
452
+ // 判断负责人有没有值
453
+ if (res.name === undefined) {
454
+ this.details.name = ''
455
+ } else {
456
+ this.details.name = res.name
457
+ }
458
+ // 判断工单被确认时间
459
+ if (res.confirmtime === undefined) {
460
+ this.details.confirmTime = ''
461
+ } else {
462
+ this.details.confirmTime = this.format(res.confirmtime, 'yyyy-MM-dd hh:mm:ss')
463
+ }
464
+ // 判断工单完成时间
465
+ if (res.finishedtime === undefined) {
466
+ this.details.finishedTime = ''
467
+ } else {
468
+ this.details.finishedTime = this.format(res.finishedtime, 'yyyy-MM-dd hh:mm:ss')
469
+ }
470
+ this.details.createdTime = this.format(res.createdtime, 'yyyy-MM-dd hh:mm:ss')
471
+ this.details.status = res.status
472
+ this.details.priority = res.priority
473
+ const dateStr = formatDate(this.details.createdTime)
474
+ this.details.createdTimestamp = new Date(dateStr).getTime()
475
+ const timepass = this.timePass()
476
+ // 如果当前状态为一般,设置定时器,五分钟后允许加急
477
+ if (this.countDown === 0 && this.details.status === 0) {
478
+ this.setTimer()
479
+ }
480
+ if (timepass > 300) {
481
+ this.urgentAccess = false
482
+ }
483
+ if (this.details.status >= 2) {
484
+ this.btnGroup = false
485
+ }
486
+ if (this.details.priority <= 1 && this.details.status === 0) {
487
+ this.descriptionUrgentLevel = 2
488
+ }
489
+ }, err => {
490
+ console.log(err)
491
+ })
492
+ }
493
+ },
494
+ computed: {
495
+ ...mapState('account', { currUser: 'user' }),
496
+ ...mapState('setting', ['isMobile']),
497
+ // 用于进度条,进度显示控制
498
+ step () {
499
+ if (this.details.status !== 0 && this.details.status !== 1) {
500
+ return 2
501
+ } else {
502
+ return this.details.status
503
+ }
504
+ }
505
+ },
506
+ watch: {
507
+ 'visible' (val) {
508
+ if (val) {
509
+ this.initView()
510
+ }
511
+ }
512
+ }
513
+ }
514
+ </script>
515
+
516
+ <style scoped lang="less">
517
+ .result-success{
518
+ .action:not(:first-child){
519
+ margin-left: 8px;
520
+ }
521
+ .project-name{
522
+ font-size: 16px;
523
+ color: @title-color;
524
+ font-weight: 500;
525
+ margin-bottom: 20px;
526
+ }
527
+ }
528
+ </style>