paas-component-library 1.0.36 → 1.0.38

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "paas-component-library",
3
3
  "private": false,
4
- "version": "1.0.36",
4
+ "version": "1.0.38",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -6,12 +6,13 @@
6
6
  <a-button :loading="isLoading" :disabled="see" ref="uploadButton" v-show="false">
7
7
  </a-button>
8
8
  </a-upload>
9
- <a-button :loading="isLoading" :disabled="see" type="primary" v-bind="$attrs" @click="$refs.uploadButton.$el.click()">
9
+ <a-button :loading="isLoading" :disabled="see" type="primary" v-bind="$attrs" v-if="closeButton"
10
+ @click="$refs.uploadButton.$el.click()">
10
11
  <paas-icon v-if="icon" :icon="icon" />
11
- <span v-if="label">{{ label }}</span>
12
+ <span v-if="label">{{ label }}</span>
12
13
  </a-button>
13
14
  <!-- 文件统计信息 -->
14
- <div v-if="datas.length > 0 && showHis" class="file-stats">
15
+ <div v-if="datas.length > 0 && showHis" :style="fileStatsStyle">
15
16
  共 {{ datas.length }} 个文件
16
17
  <span v-if="paginatedDatas.length < datas.length">
17
18
  ,当前显示 {{ paginatedDatas.length }} 个
@@ -19,32 +20,34 @@
19
20
  </div>
20
21
 
21
22
  <!-- 使用卡片式布局展示已上传的文件 -->
22
- <div v-if="datas.length > 0 && showHis" class="file-list-container">
23
- <div v-for="(file, index) in paginatedDatas" :key="file.newName || index" class="file-card">
24
- <div class="file-icon">
23
+ <div v-if="datas.length > 0 && showHis" :style="fileListContainerStyle">
24
+ <div v-for="(file, index) in paginatedDatas" :key="file.newName || index" :style="fileCardStyle"
25
+ @mouseenter="$event.currentTarget.style.borderColor = '#40a9ff'; $event.currentTarget.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)'; $event.currentTarget.style.backgroundColor = '#fff'"
26
+ @mouseleave="$event.currentTarget.style.borderColor = '#d9d9d9'; $event.currentTarget.style.boxShadow = 'none'; $event.currentTarget.style.backgroundColor = '#fafafa'">
27
+ <div :style="fileIconStyle">
25
28
  <FileOutlined v-if="!isImage(file.originalName)" />
26
29
  <PictureOutlined v-else />
27
30
  </div>
28
- <div class="file-info">
29
- <div class="file-name" :title="file.originalName">{{ file.originalName }}</div>
30
- <div class="file-size" v-if="file.size">{{ formatFileSize(file.size) }}</div>
31
+ <div :style="fileInfoStyle">
32
+ <div :style="fileNameStyle" :title="file.originalName">{{ file.originalName }}</div>
33
+ <div :style="fileSizeStyle" v-if="file.size">{{ formatFileSize(file.size) }}</div>
31
34
  </div>
32
- <div class="file-actions">
35
+ <div :style="fileActionsStyle">
33
36
  <a-tooltip title="查看">
34
- <EyeOutlined @click="previewFile(file)" class="action-icon" />
37
+ <EyeOutlined @click="previewFile(file)" :style="actionIconStyle" @mouseenter="$event.currentTarget.style.color = '#1890ff'" @mouseleave="$event.currentTarget.style.color = '#595959'" />
35
38
  </a-tooltip>
36
39
  <a-tooltip title="下载">
37
- <DownloadOutlined @click="download(file)" v-show="!see" class="action-icon" />
40
+ <DownloadOutlined @click="download(file)" v-show="!see" :style="actionIconStyle" @mouseenter="$event.currentTarget.style.color = '#1890ff'" @mouseleave="$event.currentTarget.style.color = '#595959'" />
38
41
  </a-tooltip>
39
42
  <a-tooltip title="删除">
40
- <DeleteOutlined @click="deleteFile(file)" v-show="!see" class="action-icon delete-icon" />
43
+ <DeleteOutlined @click="deleteFile(file)" v-show="!see" :style="actionIconStyle" @mouseenter="$event.currentTarget.style.color = '#ff4d4f'" @mouseleave="$event.currentTarget.style.color = '#595959'" />
41
44
  </a-tooltip>
42
45
  </div>
43
46
  </div>
44
47
  </div>
45
48
 
46
49
  <!-- 分页控件 -->
47
- <div v-if="datas.length > pageSize && showHis" class="pagination-container">
50
+ <div v-if="datas.length > pageSize && showHis" :style="paginationContainerStyle">
48
51
  <a-pagination v-model:current="currentPage" :page-size="pageSize" :total="datas.length" size="small"
49
52
  show-less-items />
50
53
  </div>
@@ -76,6 +79,7 @@ export default {
76
79
  DeleteOutlined
77
80
  },
78
81
  inheritAttrs: false, // 禁用自动继承,手动控制透传
82
+ expose: ['openUpload'], // 暴露openUpload方法供外部调用
79
83
  inject: {
80
84
  labelWidth: {
81
85
  from: 'labelWidth',
@@ -87,6 +91,10 @@ export default {
87
91
  }
88
92
  },
89
93
  props: {
94
+ closeButton: {
95
+ type: Boolean,
96
+ default: false,
97
+ },
90
98
  icon: {
91
99
  type: String,
92
100
  default: "",
@@ -179,53 +187,137 @@ export default {
179
187
  fileList: [],
180
188
  isLoading: false,
181
189
  currentPage: 1,
182
- pageSize: 10, // 每页显示10个文件
183
- previewVisible: false, // 图片预览模态框可见性
184
- previewImage: '', // 预览图片的URL
185
- previewTitle: '', // 预览标题
186
- isUploading: false // 防止重复上传的标志
190
+ pageSize: 10,
191
+ previewVisible: false,
192
+ previewImage: '',
193
+ previewTitle: '',
194
+ isUploading: false,
195
+ windowWidth: window.innerWidth
187
196
  };
188
197
  },
189
198
  computed: {
190
199
  see() {
191
200
  return this.$store.forms.see;
192
201
  },
193
- // 计算当前页要显示的文件
194
202
  paginatedDatas() {
195
203
  const startIndex = (this.currentPage - 1) * this.pageSize;
196
204
  const endIndex = startIndex + this.pageSize;
197
205
  return this.datas.slice(startIndex, endIndex);
198
206
  },
199
- // 根据isOpen属性和multiple属性决定使用哪个上传URL
200
207
  currentUploadUrl() {
201
208
  let baseUrl = this.isOpen ? this.openUploadUrl : this.uploadUrl;
202
- // 如果是多文件上传,在URL末尾添加"s"
203
209
  if (this.multiple) {
204
- // 检查URL是否已经以"s"结尾
205
210
  if (!baseUrl.endsWith('s')) {
206
- // 如果URL包含".",在点之前添加"s"
207
211
  if (baseUrl.includes('.')) {
208
212
  const lastDotIndex = baseUrl.lastIndexOf('.');
209
213
  baseUrl = baseUrl.substring(0, lastDotIndex) + 's' + baseUrl.substring(lastDotIndex);
210
214
  } else {
211
- // 否则直接在末尾添加"s"
212
215
  baseUrl = baseUrl + 's';
213
216
  }
214
217
  }
215
218
  }
216
219
  return baseUrl;
217
220
  },
218
- // 根据isOpen属性决定使用哪个预览URL
219
221
  currentShowUrl() {
220
222
  return this.isOpen ? this.openShowUrl : this.showUrl;
221
223
  },
222
- // 根据isOpen属性决定使用哪个下载URL
223
224
  currentDownloadUrl() {
224
225
  return this.isOpen ? this.openDownloadUrl : this.downloadUrl;
225
226
  },
226
- // 根据isOpen属性决定使用哪个删除URL
227
227
  currentDeleteUrl() {
228
228
  return this.isOpen ? this.openDeleteUrl : this.deleteUrl;
229
+ },
230
+ isMobile() {
231
+ return this.windowWidth <= 768;
232
+ },
233
+ fileListContainerStyle() {
234
+ return {
235
+ marginTop: '8px',
236
+ maxWidth: '100%'
237
+ };
238
+ },
239
+ fileCardStyle() {
240
+ const baseStyle = {
241
+ display: 'flex',
242
+ alignItems: 'center',
243
+ padding: this.isMobile ? '8px' : '8px 12px',
244
+ border: '1px solid #d9d9d9',
245
+ borderRadius: '6px',
246
+ marginBottom: '8px',
247
+ transition: 'all 0.3s',
248
+ backgroundColor: '#fafafa',
249
+ boxSizing: 'border-box',
250
+ flexWrap: 'nowrap'
251
+ };
252
+ return baseStyle;
253
+ },
254
+ fileIconStyle() {
255
+ return {
256
+ fontSize: '24px',
257
+ color: '#1890ff',
258
+ marginRight: '12px',
259
+ flexShrink: 0,
260
+ width: '24px',
261
+ height: '24px',
262
+ display: 'flex',
263
+ alignItems: 'center',
264
+ justifyContent: 'center'
265
+ };
266
+ },
267
+ fileInfoStyle() {
268
+ return {
269
+ flex: 1,
270
+ minWidth: 0,
271
+ paddingRight: '8px'
272
+ };
273
+ },
274
+ fileNameStyle() {
275
+ return {
276
+ fontSize: this.isMobile ? '13px' : '14px',
277
+ color: '#262626',
278
+ overflow: 'hidden',
279
+ textOverflow: 'ellipsis',
280
+ whiteSpace: 'nowrap',
281
+ marginBottom: '2px'
282
+ };
283
+ },
284
+ fileSizeStyle() {
285
+ return {
286
+ fontSize: '12px',
287
+ color: '#8c8c8c',
288
+ marginTop: '0'
289
+ };
290
+ },
291
+ fileActionsStyle() {
292
+ return {
293
+ display: 'flex',
294
+ gap: this.isMobile ? '8px' : '12px',
295
+ flexShrink: 0,
296
+ alignItems: 'center'
297
+ };
298
+ },
299
+ actionIconStyle() {
300
+ return {
301
+ fontSize: this.isMobile ? '14px' : '16px',
302
+ color: '#595959',
303
+ cursor: 'pointer',
304
+ transition: 'color 0.3s',
305
+ padding: this.isMobile ? '2px' : '4px'
306
+ };
307
+ },
308
+ fileStatsStyle() {
309
+ return {
310
+ marginTop: '8px',
311
+ fontSize: '12px',
312
+ color: '#8c8c8c'
313
+ };
314
+ },
315
+ paginationContainerStyle() {
316
+ return {
317
+ marginTop: '12px',
318
+ display: 'flex',
319
+ justifyContent: 'flex-end'
320
+ };
229
321
  }
230
322
  },
231
323
  watch: {
@@ -235,7 +327,6 @@ export default {
235
327
  },
236
328
  immediate: true
237
329
  },
238
- // 当文件列表发生变化时,重置到第一页
239
330
  datas: {
240
331
  handler() {
241
332
  this.currentPage = 1;
@@ -243,7 +334,19 @@ export default {
243
334
  deep: true
244
335
  }
245
336
  },
337
+ mounted() {
338
+ window.addEventListener('resize', this.handleResize);
339
+ },
340
+ beforeUnmount() {
341
+ window.removeEventListener('resize', this.handleResize);
342
+ },
246
343
  methods: {
344
+ handleResize() {
345
+ this.windowWidth = window.innerWidth;
346
+ },
347
+ openUpload() {
348
+ this.$refs.uploadButton.$el.click();
349
+ },
247
350
  pushFile(newValue) {
248
351
  if (!newValue) {
249
352
  this.datas = [];
@@ -474,123 +577,4 @@ export default {
474
577
  }
475
578
  },
476
579
  };
477
- </script>
478
-
479
- <style scoped>
480
- .file-list-container {
481
- margin-top: 8px;
482
- max-width: 100%;
483
- }
484
-
485
- .file-card {
486
- display: flex !important;
487
- align-items: center !important;
488
- padding: 8px 12px;
489
- border: 1px solid #d9d9d9;
490
- border-radius: 6px;
491
- margin-bottom: 8px;
492
- transition: all 0.3s;
493
- background-color: #fafafa;
494
- box-sizing: border-box;
495
- flex-wrap: nowrap !important;
496
- }
497
-
498
- .file-card > div {
499
- display: inline-block !important;
500
- vertical-align: middle !important;
501
- }
502
-
503
- .file-card:hover {
504
- border-color: #40a9ff;
505
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
506
- background-color: #fff;
507
- }
508
-
509
- .file-icon {
510
- font-size: 24px;
511
- color: #1890ff;
512
- margin-right: 12px;
513
- flex-shrink: 0;
514
- width: 24px;
515
- height: 24px;
516
- display: flex;
517
- align-items: center;
518
- justify-content: center;
519
- }
520
-
521
- .file-info {
522
- flex: 1;
523
- min-width: 0;
524
- padding-right: 8px;
525
- }
526
-
527
- .file-name {
528
- font-size: 14px;
529
- color: #262626;
530
- overflow: hidden;
531
- text-overflow: ellipsis;
532
- white-space: nowrap;
533
- margin-bottom: 2px;
534
- }
535
-
536
- .file-size {
537
- font-size: 12px;
538
- color: #8c8c8c;
539
- margin-top: 0;
540
- }
541
-
542
- .file-actions {
543
- display: flex;
544
- gap: 12px;
545
- flex-shrink: 0;
546
- align-items: center;
547
- }
548
-
549
- .action-icon {
550
- font-size: 16px;
551
- color: #595959;
552
- cursor: pointer;
553
- transition: color 0.3s;
554
- padding: 4px;
555
- }
556
-
557
- .action-icon:hover {
558
- color: #1890ff;
559
- }
560
-
561
- .delete-icon:hover {
562
- color: #ff4d4f;
563
- }
564
-
565
- .file-stats {
566
- margin-top: 8px;
567
- font-size: 12px;
568
- color: #8c8c8c;
569
- }
570
-
571
- .pagination-container {
572
- margin-top: 12px;
573
- display: flex;
574
- justify-content: flex-end;
575
- }
576
-
577
- /* 响应式设计 */
578
- @media (max-width: 768px) {
579
- .file-card {
580
- padding: 8px;
581
- }
582
-
583
- .file-name {
584
- font-size: 13px;
585
- }
586
-
587
- .file-actions {
588
- gap: 8px;
589
- }
590
-
591
- .action-icon {
592
- font-size: 14px;
593
- padding: 2px;
594
- }
595
- }
596
- </style>
580
+ </script>