vue2-client 1.14.50 → 1.14.52

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.
@@ -0,0 +1,485 @@
1
+ <template>
2
+ <div class="upload-files-container">
3
+ <div class="filter-container">
4
+ <div class="filter-group">
5
+ <a-date-picker
6
+ v-model="upload_date"
7
+ placeholder="上传日期"
8
+ @change="selfSearch"
9
+ class="filter-item"
10
+ />
11
+ <a-select
12
+ class="filter-item"
13
+ v-model="fusetype"
14
+ :options="fusetypes"
15
+ placeholder="分类"
16
+ @change="selfSearch"
17
+ allow-clear
18
+ />
19
+ <a-button type="primary" @click="selfSearch" class="search-btn">
20
+ 查询
21
+ </a-button>
22
+ </div>
23
+ </div>
24
+
25
+ <div v-if="files.length === 0" class="empty-state">
26
+ <i class="anticon anticon-inbox empty-icon"></i>
27
+ <p>暂无附件数据</p>
28
+ </div>
29
+
30
+ <div v-else class="file-timeline">
31
+ <div v-for="(item, index) in files" :key="'fileGroup' + index" class="date-group">
32
+ <div class="date-header">
33
+ <i class="anticon anticon-calendar"></i>
34
+ <span>{{ item.days }}</span>
35
+ </div>
36
+ <div class="file-grid">
37
+ <div v-for="file in item.arrays" :key="'fileItem' + file.id" class="file-card">
38
+ <div class="card-content">
39
+ <div class="file-preview">
40
+ <img
41
+ v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')"
42
+ :src="file.f_downloadpath"
43
+ class="preview-image"
44
+ @click="previewImage(file.f_downloadpath)"
45
+ />
46
+ <div v-else class="file-icon">
47
+ <i class="anticon anticon-file"></i>
48
+ </div>
49
+ </div>
50
+ <div class="file-info">
51
+ <div class="info-row">
52
+ <span class="info-label"><i class="anticon anticon-clock-circle"></i> 上传时间:</span>
53
+ <span class="info-value">{{ file.f_uploaddate }}</span>
54
+ </div>
55
+ <div class="info-row">
56
+ <span class="info-label"><i class="anticon anticon-user"></i> 操作员:</span>
57
+ <span class="info-value">{{ file.f_username }}</span>
58
+ </div>
59
+ <div class="info-row">
60
+ <span class="info-label"><i class="anticon anticon-tag"></i> 分类:</span>
61
+ <span class="info-value">{{ file.fusetype }}</span>
62
+ </div>
63
+ <div class="info-row remarks">
64
+ <span class="info-label"><i class="anticon anticon-message"></i> 说明:</span>
65
+ <span class="info-value">{{ file.fremarks || '无' }}</span>
66
+ </div>
67
+ </div>
68
+ <div class="file-actions">
69
+ <a-button
70
+ type="link"
71
+ :href="file.f_downloadpath"
72
+ target="_blank"
73
+ class="action-btn preview-btn"
74
+ >
75
+ <i class="anticon anticon-eye"></i>
76
+ 预览
77
+ </a-button>
78
+ <a-button
79
+ v-if="isDelete === '1'"
80
+ type="link"
81
+ danger
82
+ @click="delet(file.id)"
83
+ class="action-btn delete-btn"
84
+ >
85
+ <i class="anticon anticon-delete"></i>
86
+ 删除
87
+ </a-button>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </template>
96
+
97
+ <script>
98
+ import { post } from '@vue2-client/services/api'
99
+ import { del } from '@vue2-client/services/api/restTools'
100
+
101
+ export default {
102
+ name: 'XUploadFilesView',
103
+ props: {
104
+ currUserInfo: {
105
+ type: Object,
106
+ default: () => undefined
107
+ }
108
+ },
109
+ data () {
110
+ return {
111
+ upload_date: null,
112
+ fusetype: null,
113
+ files: [],
114
+ fusetypes: [],
115
+ isDelete: '0'
116
+ }
117
+ },
118
+ methods: {
119
+ async getfusetypes () {
120
+ this.fusetypes = [{ label: '全部', value: '' }]
121
+ const res = await post('/api/af-revenue/logic/getFileUseType', {})
122
+ this.fusetypes.push(...res
123
+ .filter(item => item.fusetype && item.fusetype.trim() !== '')
124
+ .map(item => ({ label: item.fusetype, value: item.fusetype })))
125
+ this.fusetype = ''
126
+ },
127
+ async getFiles () {
128
+ if (!this.currUserInfo) return
129
+ this.files = []
130
+ let condition = `f_blobid = '${this.currUserInfo.f_userinfo_id}'`
131
+ if (this.upload_date) {
132
+ condition += ` and CONVERT(VARCHAR(100), f_uploaddate, 23) = '${this.upload_date}'`
133
+ }
134
+ if (this.fusetype) {
135
+ condition += ` and fusetype = '${this.fusetype}'`
136
+ }
137
+ const res = await post('/api/af-revenue/logic/getAllFiles', { data: { condition } })
138
+ this.files = res.days.map(day => ({
139
+ days: day.uploadday,
140
+ arrays: res.array.filter(file => file.uploadday === day.uploadday)
141
+ }))
142
+ },
143
+ async delet (fileId) {
144
+ await del('api/af-revenue/entity/save/t_files', { id: fileId }, { resolveMsg: '删除成功', rejectMsg: '删除失败' })
145
+ this.getFiles()
146
+ },
147
+ selfSearch () {
148
+ this.getFiles()
149
+ },
150
+ previewImage (url) {
151
+ window.open(url, '_blank')
152
+ }
153
+ },
154
+ mounted () {
155
+ if (this.$login.r.includes('上传附件删除')) {
156
+ this.isDelete = '1'
157
+ }
158
+ this.getFiles()
159
+ this.getfusetypes()
160
+ }
161
+ }
162
+ </script>
163
+
164
+ <style scoped>
165
+ .upload-files-container {
166
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
167
+ background-color: #f9fafc;
168
+ border-radius: 12px;
169
+ padding: 24px;
170
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
171
+ }
172
+
173
+ /* 过滤区样式 */
174
+ .filter-container {
175
+ background-color: #fff;
176
+ border-radius: 10px;
177
+ padding: 20px;
178
+ margin-bottom: 24px;
179
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
180
+ border: 1px solid rgba(240, 240, 240, 0.8);
181
+ transition: all 0.3s ease;
182
+ }
183
+
184
+ .filter-container:hover {
185
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
186
+ }
187
+
188
+ .filter-group {
189
+ display: flex;
190
+ flex-wrap: wrap;
191
+ gap: 16px;
192
+ align-items: center;
193
+ }
194
+
195
+ .filter-item {
196
+ min-width: 200px;
197
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
198
+ border-radius: 6px;
199
+ }
200
+
201
+ .search-btn {
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 6px;
205
+ height: 32px;
206
+ border-radius: 6px;
207
+ padding: 0 16px;
208
+ font-weight: 500;
209
+ transition: all 0.3s ease;
210
+ box-shadow: 0 2px 5px rgba(24, 144, 255, 0.2);
211
+ justify-content: center;
212
+ }
213
+
214
+ .search-btn:hover {
215
+ transform: translateY(-1px);
216
+ box-shadow: 0 4px 8px rgba(24, 144, 255, 0.3);
217
+ }
218
+
219
+ /* 空状态样式 */
220
+ .empty-state {
221
+ display: flex;
222
+ flex-direction: column;
223
+ align-items: center;
224
+ justify-content: center;
225
+ padding: 80px 0;
226
+ background-color: #fff;
227
+ border-radius: 10px;
228
+ color: #8c8c8c;
229
+ border: 1px dashed #e8e8e8;
230
+ transition: all 0.3s ease;
231
+ }
232
+
233
+ .empty-icon {
234
+ font-size: 48px;
235
+ color: #bfbfbf;
236
+ margin-bottom: 16px;
237
+ }
238
+
239
+ .empty-state p {
240
+ font-size: 16px;
241
+ margin-top: 8px;
242
+ color: #8c8c8c;
243
+ }
244
+
245
+ /* 文件时间线 */
246
+ .file-timeline {
247
+ display: flex;
248
+ flex-direction: column;
249
+ gap: 28px;
250
+ }
251
+
252
+ .date-group {
253
+ background-color: #fff;
254
+ border-radius: 10px;
255
+ overflow: hidden;
256
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
257
+ border: 1px solid rgba(240, 240, 240, 0.8);
258
+ transition: all 0.3s ease;
259
+ }
260
+
261
+ .date-group:hover {
262
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
263
+ transform: translateY(-2px);
264
+ }
265
+
266
+ .date-header {
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 10px;
270
+ padding: 16px 20px;
271
+ background: linear-gradient(135deg, #e6f7ff, #f0f5ff);
272
+ border-bottom: 1px solid #e6f0ff;
273
+ font-weight: 500;
274
+ color: #1890ff;
275
+ font-size: 15px;
276
+ }
277
+
278
+ .date-header i {
279
+ font-size: 18px;
280
+ }
281
+
282
+ /* 文件网格 */
283
+ .file-grid {
284
+ display: grid;
285
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
286
+ gap: 20px;
287
+ padding: 20px;
288
+ }
289
+
290
+ /* 文件卡片 */
291
+ .file-card {
292
+ border-radius: 10px;
293
+ overflow: hidden;
294
+ transition: all 0.3s ease;
295
+ border: 1px solid #f0f0f0;
296
+ height: 100%;
297
+ background-color: #fff;
298
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.03);
299
+ }
300
+
301
+ .file-card:hover {
302
+ transform: translateY(-5px);
303
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
304
+ border-color: #e6f7ff;
305
+ }
306
+
307
+ .card-content {
308
+ display: flex;
309
+ flex-direction: column;
310
+ height: 100%;
311
+ }
312
+
313
+ /* 文件预览 */
314
+ .file-preview {
315
+ height: 200px;
316
+ background-color: #f5f5f5;
317
+ display: flex;
318
+ align-items: center;
319
+ justify-content: center;
320
+ overflow: hidden;
321
+ position: relative;
322
+ border-bottom: 1px solid #f0f0f0;
323
+ }
324
+
325
+ .preview-image {
326
+ width: 100%;
327
+ height: 100%;
328
+ object-fit: cover;
329
+ transition: transform 0.5s ease;
330
+ cursor: zoom-in;
331
+ }
332
+
333
+ .preview-image:hover {
334
+ transform: scale(1.08);
335
+ }
336
+
337
+ .file-icon {
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ width: 100%;
342
+ height: 100%;
343
+ font-size: 64px;
344
+ color: #bfbfbf;
345
+ background-color: #fafafa;
346
+ transition: all 0.3s ease;
347
+ }
348
+
349
+ .file-icon:hover {
350
+ color: #1890ff;
351
+ }
352
+
353
+ .file-icon i {
354
+ opacity: 0.7;
355
+ }
356
+
357
+ /* 文件信息 */
358
+ .file-info {
359
+ padding: 16px;
360
+ flex-grow: 1;
361
+ display: flex;
362
+ flex-direction: column;
363
+ gap: 10px;
364
+ background-color: #fff;
365
+ }
366
+
367
+ .info-row {
368
+ display: flex;
369
+ align-items: flex-start;
370
+ gap: 8px;
371
+ font-size: 14px;
372
+ color: #595959;
373
+ line-height: 1.5;
374
+ }
375
+
376
+ .info-label {
377
+ font-weight: 500;
378
+ color: #8c8c8c;
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 4px;
382
+ min-width: 80px;
383
+ }
384
+
385
+ .info-label i {
386
+ font-size: 14px;
387
+ color: #1890ff;
388
+ }
389
+
390
+ .info-value {
391
+ color: #262626;
392
+ flex: 1;
393
+ overflow: hidden;
394
+ text-overflow: ellipsis;
395
+ white-space: nowrap;
396
+ }
397
+
398
+ .remarks .info-value {
399
+ white-space: normal;
400
+ display: -webkit-box;
401
+ -webkit-line-clamp: 2;
402
+ -webkit-box-orient: vertical;
403
+ line-height: 1.6;
404
+ color: #434343;
405
+ }
406
+
407
+ /* 操作按钮 */
408
+ .file-actions {
409
+ display: flex;
410
+ justify-content: space-between;
411
+ padding: 12px 16px;
412
+ border-top: 1px solid #f0f0f0;
413
+ background-color: #fafafa;
414
+ }
415
+
416
+ .action-btn {
417
+ display: flex;
418
+ align-items: center;
419
+ gap: 6px;
420
+ font-size: 14px;
421
+ border-radius: 4px;
422
+ padding: 4px 12px;
423
+ transition: all 0.3s ease;
424
+ }
425
+
426
+ .action-btn i {
427
+ font-size: 14px;
428
+ }
429
+
430
+ .preview-btn {
431
+ color: #1890ff;
432
+ }
433
+
434
+ .preview-btn:hover {
435
+ background-color: #e6f7ff;
436
+ }
437
+
438
+ .delete-btn {
439
+ color: #ff4d4f;
440
+ }
441
+
442
+ .delete-btn:hover {
443
+ background-color: #fff1f0;
444
+ }
445
+
446
+ /* 响应式调整 */
447
+ @media (max-width: 768px) {
448
+ .filter-group {
449
+ flex-direction: column;
450
+ align-items: stretch;
451
+ }
452
+
453
+ .filter-item {
454
+ width: 100%;
455
+ min-width: auto;
456
+ }
457
+
458
+ .search-btn {
459
+ width: 100%;
460
+ }
461
+
462
+ .file-grid {
463
+ grid-template-columns: 1fr;
464
+ }
465
+
466
+ .upload-files-container {
467
+ padding: 16px;
468
+ }
469
+ }
470
+
471
+ @media (max-width: 480px) {
472
+ .file-preview {
473
+ height: 160px;
474
+ }
475
+
476
+ .date-header {
477
+ padding: 12px 16px;
478
+ }
479
+
480
+ .file-grid {
481
+ padding: 12px;
482
+ gap: 12px;
483
+ }
484
+ }
485
+ </style>
@@ -6,7 +6,7 @@
6
6
  <label class="form-label">{{ item.label }}</label>
7
7
  <a-input
8
8
  :value="data[item.field]"
9
- disabled
9
+ :disabled="item.disabled"
10
10
  class="form-input"
11
11
  />
12
12
  </a-col>
@@ -86,6 +86,9 @@ export default {
86
86
  this.getConfig(this.queryParamsName, {})
87
87
  },
88
88
  methods: {
89
+ selectMethod (value) {
90
+ this.$emit('method', value)
91
+ },
89
92
  getConfig (configName, param) {
90
93
  getConfigByName(configName, 'af-his', res => {
91
94
  this.config = res
@@ -7,7 +7,7 @@
7
7
  title="流程详情"
8
8
  @close="onClose"
9
9
  class="modern-workflow-drawer"
10
- :bodyStyle="{ padding: '0', background: '#f5f7fa' }"
10
+ :bodyStyle="{ padding: '0', background: '#f5f7fa', flex: 1 }"
11
11
  :headerStyle="{ borderBottom: '1px solid #eaedf2', padding: '16px 24px' }"
12
12
  >
13
13
  <div class="workflow-container">
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  <!-- 内容区域 -->
27
- <div class="content-section" :style="{ minHeight: screenHeight * 0.7 + 'px' }">
27
+ <div class="content-section">
28
28
  <a-card class="content-card" :bordered="false">
29
29
  <a-tabs
30
30
  :activeKey="activeKey"
@@ -34,21 +34,23 @@
34
34
  >
35
35
  <!-- 查看/编辑进度标签页 -->
36
36
  <a-tab-pane key="1" tab="开始工作">
37
- <WorkFlowHandle
38
- v-if="activeKey === '1' && details.f_state !== undefined && steps !== undefined"
39
- ref="workflowHandle"
40
- :workflow-id="workflowId"
41
- :workflowState="details.f_state === 1"
42
- :complete-time="details.f_complete_time"
43
- :stepsForChild="steps"
44
- :visible="visible"
45
- :taskName="details.f_task_name"
46
- :details="details"
47
- @refresh="stepChanged"
48
- @success="success"
49
- @nextClick="nextClick"
50
- class="handle-content"
51
- />
37
+ <template v-if="details">
38
+ <WorkFlowHandle
39
+ v-if="activeKey === '1' && details.f_state !== undefined && steps !== undefined"
40
+ ref="workflowHandle"
41
+ :workflow-id="workflowId"
42
+ :workflowState="details.f_state === 1"
43
+ :complete-time="details.f_complete_time"
44
+ :stepsForChild="steps"
45
+ :visible="visible"
46
+ :taskName="details.f_task_name"
47
+ :details="details"
48
+ @refresh="stepChanged"
49
+ @success="success"
50
+ @nextClick="nextClick"
51
+ class="handle-content"
52
+ />
53
+ </template>
52
54
  </a-tab-pane>
53
55
 
54
56
  <!-- 任务流转记录标签页 -->
@@ -71,16 +73,27 @@
71
73
  />
72
74
  </span>
73
75
  <div class="message-content">
74
- <leave-message
75
- :workflowId="workflowId"
76
- :projectName="details.f_task_name"
77
- :data="messageList"
78
- :loading="messageLoading"
79
- @success="success"
80
- class="leave-message-component"
81
- />
76
+ <template v-if="activeKey === '4' && details">
77
+ <leave-message
78
+ :workflowId="workflowId"
79
+ :projectName="details.f_task_name"
80
+ :data="messageList"
81
+ :loading="messageLoading"
82
+ @success="success"
83
+ class="leave-message-component"
84
+ />
85
+ </template>
82
86
  </div>
83
87
  </a-tab-pane>
88
+
89
+ <!-- 查看附件标签页 -->
90
+ <!-- <a-tab-pane key="5" tab="查看附件">-->
91
+ <!-- <template v-if="details">-->
92
+ <!-- <XUploadFilesView-->
93
+ <!-- :currUserInfo="{ f_userinfo_id: 90613 }"-->
94
+ <!-- />-->
95
+ <!-- </template>-->
96
+ <!-- </a-tab-pane>-->
84
97
  </a-tabs>
85
98
  </a-card>
86
99
  </div>
@@ -97,6 +110,7 @@ import { postByServiceName } from '@vue2-client/services/api/restTools'
97
110
  import { workFlowViewApi } from '@vue2-client/services/api/workFlow'
98
111
  import WorkflowLog from './WorkflowPageDetail/WorkflowLog.vue'
99
112
  import LeaveMessage from './WorkflowPageDetail/LeaveMessage'
113
+ import XUploadFilesView from '@vue2-client/base-client/components/common/XUploadFilesView/index.vue'
100
114
 
101
115
  export default {
102
116
  name: 'WorkflowDetail',
@@ -105,7 +119,8 @@ export default {
105
119
  WorkFlowHandle,
106
120
  XFormTable,
107
121
  WorkflowLog,
108
- LeaveMessage
122
+ LeaveMessage,
123
+ XUploadFilesView
109
124
  },
110
125
  data () {
111
126
  return {
@@ -118,7 +133,7 @@ export default {
118
133
  // 保存流程和留言信息
119
134
  steps: undefined,
120
135
  // 基础信息
121
- details: {},
136
+ details: undefined,
122
137
  // 是否已完成
123
138
  allStepDown: false,
124
139
  // 给XFormTable增加额外查询条件
@@ -133,7 +148,7 @@ export default {
133
148
  messageList: [],
134
149
  messageLoading: true,
135
150
  workflowId: '',
136
- direction: '',
151
+ direction: 'right',
137
152
  visible: false
138
153
  }
139
154
  },
@@ -170,7 +185,7 @@ export default {
170
185
  this.visible = false
171
186
  this.activeKey = '1'
172
187
  this.allStepDown = false
173
- this.details = {}
188
+ this.details = undefined
174
189
  this.fixedAddForm = {}
175
190
  this.fixedQueryForm = {}
176
191
  this.steps = undefined
@@ -200,7 +215,7 @@ export default {
200
215
  this.fixedAddForm.a_f_workflow_id = this.workflowId
201
216
  },
202
217
  // 初始化两张固定表
203
- async init ({ workflowId, direction, visible = true }) {
218
+ async init ({ workflowId, direction = 'right', visible = true }) {
204
219
  this.workflowId = workflowId
205
220
  this.direction = direction
206
221
  this.visible = visible
@@ -242,6 +257,7 @@ export default {
242
257
  .content-card {
243
258
  border-radius: 8px;
244
259
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
260
+ min-height: 100%;
245
261
 
246
262
  /deep/ .ant-card-body {
247
263
  padding: 12px 24px 24px;
@@ -278,7 +294,6 @@ export default {
278
294
  }
279
295
 
280
296
  .message-content {
281
- max-width: 900px;
282
297
 
283
298
  .leave-message-component {
284
299
  width: 100%;
@@ -317,4 +332,9 @@ export default {
317
332
  }
318
333
  }
319
334
  }
335
+
336
+ :deep(.ant-drawer-wrapper-body) {
337
+ display: flex;
338
+ flex-direction: column;
339
+ }
320
340
  </style>