vue2-client 1.8.85 → 1.8.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Change Log
2
2
  > 所有关于本项目的变化都在该文档里。
3
3
 
4
+ **1.8.86 -2024-3-8 @张振宇**
5
+ - 解决 STable refresh 时排序失效问题
6
+
4
7
  **1.8.82 - 1.8.85 -2024-3-7 @江超**
5
8
  - 删除过时组件
6
9
  - XFormItem的下拉框数据源现在支持从配置中心获取了
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.8.85",
3
+ "version": "1.8.87",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -11,7 +11,10 @@ export default {
11
11
 
12
12
  localLoading: false,
13
13
  localDataSource: [],
14
- localPagination: Object.assign({}, this.pagination)
14
+ localPagination: Object.assign({}, this.pagination),
15
+
16
+ sortField: undefined,
17
+ sortOrder: undefined
15
18
  }
16
19
  },
17
20
  props: Object.assign({}, T.props, {
@@ -137,20 +140,22 @@ export default {
137
140
  */
138
141
  loadData (pagination, filters, sorter) {
139
142
  this.localLoading = true
143
+ // 暂存排序方式,避免 refresh 之后排序失效
144
+ if (sorter && sorter.field) {
145
+ this.sortField = sorter.field
146
+ }
147
+ if (sorter && sorter.order) {
148
+ this.sortOrder = sorter.order
149
+ }
140
150
  const parameter = Object.assign({
141
151
  pageNo: (pagination && pagination.current) ||
142
152
  this.showPagination && this.localPagination.current || this.pageNum,
143
153
  pageSize: (pagination && pagination.pageSize) ||
144
154
  this.showPagination && this.localPagination.pageSize || this.pageSize
145
155
  },
146
- (sorter && sorter.field && {
147
- sortField: sorter.field
148
- }) || {},
149
- (sorter && sorter.order && {
150
- sortOrder: sorter.order
151
- }) || {}, {
152
- ...filters
153
- }
156
+ (this.sortField && { sortField: this.sortField }) || {},
157
+ (this.sortOrder && { sortOrder: this.sortOrder }) || {},
158
+ { ...filters }
154
159
  )
155
160
  const result = this.data(parameter)
156
161
  // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.totalCount, r.data
@@ -1,51 +1,51 @@
1
- <template>
2
- <div>
3
- <a-list v-show="!loading" size="small" :data-source="data">
4
- <a-list-item slot="renderItem" slot-scope="item">
5
- <div>
6
- <p><a @click="$emit('openFavorites', item.uuid)">{{ item.question }} </a></p>
7
- <p>{{ item.date }}</p>
8
- </div>
9
- <a class="delete_item">
10
- <a-icon type="close" @click="$emit('saveToFavorites', item.uuid)"/>
11
- </a>
12
- </a-list-item>
13
- </a-list>
14
- </div>
15
- </template>
16
-
17
- <script>
18
- import { indexedDB } from '@vue2-client/utils/indexedDB'
19
-
20
- export default {
21
- name: 'FavoriteList',
22
- data () {
23
- return {
24
- data: [],
25
- loading: false
26
- }
27
- },
28
- mounted () {
29
- this.loadData()
30
- },
31
- methods: {
32
- loadData () {
33
- console.warn(123)
34
- indexedDB.getAll((data) => {
35
- const realData = data.filter(item => item.data && item.data.uuid)
36
- .map(item => item.data)
37
- this.data = realData
38
- })
39
- }
40
- }
41
- }
42
- </script>
43
- <style lang="less" scoped>
44
- .delete_item {
45
- margin-left: 8px;
46
- color: #333;
47
- }
48
- p {
49
- margin: 0
50
- }
51
- </style>
1
+ <template>
2
+ <div>
3
+ <a-list v-show="!loading" size="small" :data-source="data">
4
+ <a-list-item slot="renderItem" slot-scope="item">
5
+ <div>
6
+ <p><a @click="$emit('openFavorites', item.uuid)">{{ item.question }} </a></p>
7
+ <p>{{ item.date }}</p>
8
+ </div>
9
+ <a class="delete_item">
10
+ <a-icon type="close" @click="$emit('saveToFavorites', item.uuid)"/>
11
+ </a>
12
+ </a-list-item>
13
+ </a-list>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import { indexedDB } from '@vue2-client/utils/indexedDB'
19
+
20
+ export default {
21
+ name: 'FavoriteList',
22
+ data () {
23
+ return {
24
+ data: [],
25
+ loading: false
26
+ }
27
+ },
28
+ mounted () {
29
+ this.loadData()
30
+ },
31
+ methods: {
32
+ loadData () {
33
+ console.warn(123)
34
+ indexedDB.getAll((data) => {
35
+ const realData = data.filter(item => item.data && item.data.uuid)
36
+ .map(item => item.data)
37
+ this.data = realData
38
+ })
39
+ }
40
+ }
41
+ }
42
+ </script>
43
+ <style lang="less" scoped>
44
+ .delete_item {
45
+ margin-left: 8px;
46
+ color: #333;
47
+ }
48
+ p {
49
+ margin: 0
50
+ }
51
+ </style>
@@ -8,7 +8,7 @@
8
8
  title="工单状态"
9
9
  width="70%"
10
10
  @cancel="onSuccessCancel">
11
- <submit-ticket-success v-if="serialNumber" :serialNumber="serialNumber" />
11
+ <submit-ticket-success v-if="serialNumber" :serialNumber="serialNumber" @afterSubmit="afterSubmit"/>
12
12
  </a-modal>
13
13
  <!-- 两个使用手册弹框 -->
14
14
  <a-modal
@@ -237,6 +237,7 @@
237
237
  <a-tab-pane key="workHistory" tab="历史工单">
238
238
  <!-- 查询表单 -->
239
239
  <x-form-table
240
+ ref="searchTable"
240
241
  v-if="tabActiveKey === 'workHistory'"
241
242
  :fixed-query-form="fixedQueryForm"
242
243
  serviceName="af-system"
@@ -416,6 +417,11 @@ export default {
416
417
  this.infoFormVisible = false
417
418
  }
418
419
  })
420
+ },
421
+ // 用户 退回/提交 工单回调
422
+ afterSubmit () {
423
+ this.$refs.searchTable.refreshTable()
424
+ this.successVisible = false
419
425
  }
420
426
  },
421
427
  watch: {
@@ -45,22 +45,71 @@
45
45
  </div>
46
46
  </result>
47
47
  <div class="ticket-detail">
48
- <a-row class="item">
49
- <a-col :span="3"><span class="title">问题描述</span></a-col>
50
- <a-col :span="17"><span>{{ details.description }}</span></a-col>
51
- </a-row>
52
- <a-row class="item">
53
- <a-col :span="3"><span class="title">问题截图</span></a-col>
54
- <a-col :span="21"><image-item :images="details.images" :width="120" @preview="handleFilePreview" /></a-col>
55
- </a-row>
56
- <a-row v-if="details.files.length" class="item">
57
- <a-col :span="3"><span class="title">附件</span></a-col>
58
- <a-col :span="21"><file-item :files="details.files" :downloadable="false" @preview="handleFilePreview" /></a-col>
59
- </a-row>
60
- <a-row v-if="details.resultrecord" class="item">
61
- <a-col :span="3"><span class="title">处理结果</span></a-col>
62
- <a-col :span="17"><span>{{ details.resultrecord }}</span></a-col>
63
- </a-row>
48
+ <a-tabs :default-active-key="tabActiveKey">
49
+ <a-tab-pane key="1" tab="工单问题">
50
+ <a-row class="item">
51
+ <a-col :span="3"><span class="title">问题描述</span></a-col>
52
+ <a-col :span="17"><span>{{ details.description }}</span></a-col>
53
+ </a-row>
54
+ <a-row class="item">
55
+ <a-col :span="3"><span class="title">问题截图</span></a-col>
56
+ <a-col :span="21"><image-item :images="details.images" :width="120" @preview="handleFilePreview" /></a-col>
57
+ </a-row>
58
+ <a-row v-if="details.files.length" class="item">
59
+ <a-col :span="3"><span class="title">附件</span></a-col>
60
+ <a-col :span="21"><file-item :files="details.files" :downloadable="false" @preview="handleFilePreview" /></a-col>
61
+ </a-row>
62
+ <a-row v-if="details.resultrecord" class="item">
63
+ <a-col :span="3"><span class="title">处理结果</span></a-col>
64
+ <a-col :span="17"><span>{{ details.resultrecord }}</span></a-col>
65
+ </a-row>
66
+ </a-tab-pane>
67
+ <a-tab-pane key="2" tab="工单确认" v-show="this.details.status === 4">
68
+ <a-row class="item">
69
+ <a-form :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
70
+ <!-- 是否完成 -->
71
+ <a-form-item label="是否完成">
72
+ <a-select placeholder="请选择" v-model="customerSure.sfwc">
73
+ <a-select-option value="是">
74
+
75
+ </a-select-option>
76
+ <a-select-option value="否">
77
+
78
+ </a-select-option>
79
+ </a-select>
80
+ </a-form-item>
81
+ <!-- 退回原因 -->
82
+ <a-form-item label="退回原因" v-show="customerSure.sfwc === '否'">
83
+ <a-textarea placeholder="请输入退回原因" v-model="customerSure.thyy"></a-textarea>
84
+ </a-form-item>
85
+ <!-- 售后评价 -->
86
+ <a-form-item label="售后评价" v-show="customerSure.sfwc === '是'">
87
+ <a-select placeholder="请选择" v-model="customerSure.shpj">
88
+ <a-select-option value="满意">
89
+ 满意
90
+ </a-select-option>
91
+ <a-select-option value="不满意">
92
+ 不满意
93
+ </a-select-option>
94
+ </a-select>
95
+ </a-form-item>
96
+ <!-- 反馈意见 -->
97
+ <a-form-item label="反馈意见" v-show="customerSure.sfwc === '是'">
98
+ <a-textarea placeholder="请输入反馈意见" v-model="customerSure.fkyj"></a-textarea>
99
+ </a-form-item>
100
+ <!-- 表单底部按钮 -->
101
+ <a-form-item :wrapper-col="{ span: 12, offset: 5 }">
102
+ <a-button type="primary" @click="rollBack" :disabled="customerSure.sfwc === '是'" style="margin-right: 10px">
103
+ 退回
104
+ </a-button>
105
+ <a-button type="primary" @click="submit" :disabled="customerSure.sfwc === '否'">
106
+ 提交
107
+ </a-button>
108
+ </a-form-item>
109
+ </a-form>
110
+ </a-row>
111
+ </a-tab-pane>
112
+ </a-tabs>
64
113
  </div>
65
114
  <a-modal v-model="filePreviewVisible" :footer="null" :dialog-style="{ top: '30px' }" width="80%" :z-index="1001">
66
115
  <file-preview :path="filePath" />
@@ -121,7 +170,16 @@ export default {
121
170
  icon: true,
122
171
  // 文件预览
123
172
  filePreviewVisible: false,
124
- filePath: ''
173
+ filePath: '',
174
+ tabActiveKey: '1',
175
+ customerSure: {
176
+ shpj: '满意',
177
+ fkyj: undefined,
178
+ sfwc: '是',
179
+ thyy: ''
180
+ },
181
+ // 工单id
182
+ applyId: 0
125
183
  }
126
184
  },
127
185
  mounted () {
@@ -183,6 +241,7 @@ export default {
183
241
  serialNumber: this.serialNumber
184
242
  })
185
243
  .then(res => {
244
+ this.applyId = res.apply_id
186
245
  this.details.uploader = res.uploader
187
246
  // 判断负责人有没有值
188
247
  if (res.name === undefined) {
@@ -216,11 +275,110 @@ export default {
216
275
  handleFilePreview (path) {
217
276
  this.filePath = path
218
277
  this.filePreviewVisible = true
278
+ },
279
+ // 用户确认提交
280
+ submit () {
281
+ return post(TicketDetailsViewApi.afterApplyFinalStepSubmit, {
282
+ applyId: this.applyId
283
+ })
284
+ .then(
285
+ res => {
286
+ this.onSubmit()
287
+ this.saveWorkflowLog('确认完工', '最后一步: 客户确认', { notes: '' })
288
+ this.$message.success('已完工!')
289
+ // 修改工单状态为 3(已关闭)
290
+ post(TicketDetailsViewApi.clientSubmit, {
291
+ status: 3,
292
+ serial_number: this.serialNumber
293
+ }).then(res => {
294
+ console.log('res', res)
295
+ })
296
+ this.getTicketDetail()
297
+ this.$emit('afterSubmit')
298
+ },
299
+ err => {
300
+ this.$message.error('提交失败!')
301
+ console.log(err)
302
+ }
303
+ )
304
+ },
305
+ // 回退
306
+ rollBack () {
307
+ if (this.customerSure.thyy === '') {
308
+ this.$message.warn('请填写退回原因')
309
+ return
310
+ }
311
+ const notes = this.customerSure.thyy
312
+ return post(TicketDetailsViewApi.updateApplySubState, {
313
+ stepId: 11,
314
+ applyId: this.applyId
315
+ }).then(
316
+ res => {
317
+ this.saveWorkflowLog('退回', '第12步: 客户确认 ---> 第11步: 售后确认', { notes })
318
+ this.$message.success('退回成功')
319
+ // 修改工单状态为 1(待处理)
320
+ post(TicketDetailsViewApi.clientSubmit, {
321
+ status: 1,
322
+ serial_number: this.serialNumber
323
+ }).then(res => {
324
+ console.log('res', res)
325
+ })
326
+ this.getTicketDetail()
327
+ this.$emit('afterSubmit')
328
+ },
329
+ err => {
330
+ this.$message.error('退回失败!')
331
+ console.log(err)
332
+ }
333
+ )
334
+ },
335
+ // 保存工作流日志
336
+ saveWorkflowLog (operation, desc, extra) {
337
+ post(TicketDetailsViewApi.saveApplyWorkflowLog, {
338
+ applyId: this.applyId,
339
+ operation,
340
+ desc,
341
+ operator: '客户确认',
342
+ notes: '客户确认',
343
+ setHandler: '客户确认',
344
+ setDeadline: '',
345
+ ...extra
346
+ })
347
+ },
348
+ //
349
+ onSubmit () {
350
+ const time = this.format(new Date(), 'yyyy-MM-dd hh:mm:ss')
351
+ const form = {
352
+ shpj: this.customerSure.shpj,
353
+ fkyj: this.customerSure.fkyj,
354
+ sfwc: this.customerSure.sfwc
355
+ }
356
+ return post(TicketDetailsViewApi.saveApplyStepFormData, {
357
+ applyId: this.applyId,
358
+ stepId: 12,
359
+ form: form,
360
+ data: time,
361
+ handler: '客户确认',
362
+ note: ''
363
+ })
364
+ .then(
365
+ res => {
366
+ console.log('表单提交成功')
367
+ this.note = ''
368
+ this.showForm = false
369
+ this.stepDone = true
370
+ },
371
+ err => {
372
+ this.$message.error('保存失败,请检查后重试')
373
+ console.log(err)
374
+ }
375
+ )
219
376
  }
220
377
  },
221
378
  computed: {
222
379
  // 用于进度条,进度显示控制
223
380
  step () {
381
+ console.log('status', this.details.status)
224
382
  if (this.details.status !== 0 && this.details.status !== 1) {
225
383
  return 2
226
384
  } else {
@@ -28,7 +28,15 @@ const TicketDetailsViewApi = {
28
28
  // 发起售后工单流程
29
29
  createTicket: '/api/af-system/logic/createTicket',
30
30
  // 查询:获取所有员工名,供前端展示备选项
31
- getAllEmployeeName: '/api/af-system/logic/getAllEmployeeName'
31
+ getAllEmployeeName: '/api/af-system/logic/getAllEmployeeName',
32
+ // 改变报装进度
33
+ updateApplySubState: '/api/af-system/logic/updateApplySubState',
34
+ // 保存工作流日志
35
+ saveApplyWorkflowLog: '/api/af-system/logic/saveApplyWorkflowLog',
36
+ // 完工确认后更改报装状态
37
+ afterApplyFinalStepSubmit: '/api/af-system/logic/afterApplyFinalStepSubmit',
38
+ // 保存用户每一步输入的表单内容
39
+ saveApplyStepFormData: '/api/af-system/logic/saveApplyStepFormData',
32
40
  }
33
41
 
34
42
  export { TicketDetailsViewApi }
@@ -1,18 +1,18 @@
1
- import { post } from '@vue2-client/services/api/restTools'
2
-
3
- const entityApi = {
4
- // 根据ID查询数据
5
- getById: (entityName, id, data = {}, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
6
- return post(`/api/${serviceName}/entity/query/${entityName}/${id}`, data)
7
- },
8
- // 根据ID集合查询所有数据
9
- findAllByIds: (entityName, data, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
10
- return post(`/api/${serviceName}/entity/query/${entityName}`, data)
11
- },
12
- // 查询实体的总数量
13
- getCount: (entityName, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
14
- return post(`/api/${serviceName}/entity/queryCount/${entityName}`, {})
15
- }
16
- }
17
-
18
- export { entityApi }
1
+ import { post } from '@vue2-client/services/api/restTools'
2
+
3
+ const entityApi = {
4
+ // 根据ID查询数据
5
+ getById: (entityName, id, data = {}, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
6
+ return post(`/api/${serviceName}/entity/query/${entityName}/${id}`, data)
7
+ },
8
+ // 根据ID集合查询所有数据
9
+ findAllByIds: (entityName, data, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
10
+ return post(`/api/${serviceName}/entity/query/${entityName}`, data)
11
+ },
12
+ // 查询实体的总数量
13
+ getCount: (entityName, serviceName = process.env.VUE_APP_SYSTEM_NAME) => {
14
+ return post(`/api/${serviceName}/entity/queryCount/${entityName}`, {})
15
+ }
16
+ }
17
+
18
+ export { entityApi }
@@ -1,31 +1,31 @@
1
- /**
2
- * @description: createWaterMark.js 加水印功能
3
- */
4
- let waterMarkDOM
5
-
6
- const clearWaterMark = () => {
7
- if (waterMarkDOM) waterMarkDOM.remove()
8
- }
9
- /**
10
- * @description: 创建水印
11
- * @param waterMarkName 水印内容
12
- */
13
- export default function createWaterMark (waterMarkName) {
14
- clearWaterMark()
15
- if (!waterMarkName) {
16
- return
17
- }
18
- const width = window.parseInt(document.body.clientWidth)
19
- const canvasWidth = width / window.parseInt(width / 320)
20
- const fontFamily = window.getComputedStyle(document.body)['font-family']
21
- const fragment = document.createDocumentFragment()
22
- waterMarkDOM = document.createElement('div')
23
- waterMarkDOM.className = 'water-mark-wrap'
24
- let spanStr = ''
25
- for (let i = 0; i < 100; i++) {
26
- spanStr += `<span class="water-word" style=width:${canvasWidth}px;height:200px;font: ${fontFamily}>${waterMarkName}</span>`
27
- }
28
- waterMarkDOM.innerHTML = spanStr
29
- fragment.appendChild(waterMarkDOM)
30
- document.body.appendChild(fragment)
31
- }
1
+ /**
2
+ * @description: createWaterMark.js 加水印功能
3
+ */
4
+ let waterMarkDOM
5
+
6
+ const clearWaterMark = () => {
7
+ if (waterMarkDOM) waterMarkDOM.remove()
8
+ }
9
+ /**
10
+ * @description: 创建水印
11
+ * @param waterMarkName 水印内容
12
+ */
13
+ export default function createWaterMark (waterMarkName) {
14
+ clearWaterMark()
15
+ if (!waterMarkName) {
16
+ return
17
+ }
18
+ const width = window.parseInt(document.body.clientWidth)
19
+ const canvasWidth = width / window.parseInt(width / 320)
20
+ const fontFamily = window.getComputedStyle(document.body)['font-family']
21
+ const fragment = document.createDocumentFragment()
22
+ waterMarkDOM = document.createElement('div')
23
+ waterMarkDOM.className = 'water-mark-wrap'
24
+ let spanStr = ''
25
+ for (let i = 0; i < 100; i++) {
26
+ spanStr += `<span class="water-word" style=width:${canvasWidth}px;height:200px;font: ${fontFamily}>${waterMarkName}</span>`
27
+ }
28
+ waterMarkDOM.innerHTML = spanStr
29
+ fragment.appendChild(waterMarkDOM)
30
+ document.body.appendChild(fragment)
31
+ }