@ebiz/designer-components 0.0.18-beta.4 → 0.0.18-beta.40

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.
@@ -1,47 +1,16 @@
1
1
  <template>
2
- <t-upload
3
- :accept="accept"
4
- :action="internalAction"
5
- :allowUploadDuplicateFile="allowUploadDuplicateFile"
6
- :autoUpload="autoUpload"
7
- :beforeUpload="handleBeforeUpload"
8
- :data="data"
9
- :disabled="disabled"
10
- :draggable="draggable"
11
- :fileListDisplay="fileListDisplay"
12
- :files="internalFiles"
13
- :format="format"
14
- :formatRequest="formatRequest"
15
- :headers="headers"
16
- :isBatchUpload="isBatchUpload"
17
- :max="max"
18
- :method="method"
19
- :multiple="multiple"
20
- :name="name"
21
- :placeholder="placeholder"
2
+ <t-upload :accept="accept" :action="internalAction" :allowUploadDuplicateFile="allowUploadDuplicateFile"
3
+ :autoUpload="autoUpload" :beforeUpload="handleBeforeUpload" :data="data" :disabled="disabled"
4
+ :draggable="draggable" :fileListDisplay="fileListDisplay" :files="internalFiles" :format="format"
5
+ :formatRequest="formatRequest" :headers="headers" :isBatchUpload="isBatchUpload" :max="max" :method="method"
6
+ :multiple="multiple" :name="name" :placeholder="placeholder"
22
7
  :requestMethod="useInternalUpload ? customRequestMethod : requestMethod"
23
- :showUploadProgress="showUploadProgress"
24
- :sizeLimit="sizeLimit"
25
- :status="status"
26
- :theme="theme"
27
- :tips="tips"
28
- :uploadAllFilesInOneRequest="uploadAllFilesInOneRequest"
29
- :uploadButton="uploadButton"
30
- :useMockProgress="useMockProgress"
31
- :withCredentials="withCredentials"
32
- v-model="modelValue"
33
- @change="handleChange"
34
- @click="handleClick"
35
- @drag="handleDrag"
36
- @drop="handleDrop"
37
- @fail="handleFail"
38
- @preview="handlePreview"
39
- @progress="handleProgress"
40
- @remove="handleRemove"
41
- @select-change="handleSelectChange"
42
- @success="handleSuccess"
43
- @validate="handleValidate"
44
- >
8
+ :showUploadProgress="showUploadProgress" :sizeLimit="sizeLimit" :status="status" :theme="theme" :tips="tips"
9
+ :uploadAllFilesInOneRequest="uploadAllFilesInOneRequest" :uploadButton="uploadButton"
10
+ :useMockProgress="useMockProgress" :withCredentials="withCredentials" v-model="modelValue"
11
+ @change="handleChange" @click="handleClick" @drag="handleDrag" @drop="handleDrop" @fail="handleFail"
12
+ @preview="handlePreview" @progress="handleProgress" @remove="handleRemove" @select-change="handleSelectChange"
13
+ @success="handleSuccess" @validate="handleValidate">
45
14
  <!-- 默认插槽 -->
46
15
  <slot></slot>
47
16
 
@@ -105,34 +74,34 @@ const initializeFiles = () => {
105
74
  // 默认的格式化响应函数
106
75
  const defaultFormatResponse = (res) => {
107
76
  console.log('Default formatResponse handling:', res);
108
-
77
+
109
78
  // 处理不同的响应格式
110
79
  if (res === null || res === undefined) {
111
80
  return { url: '', error: '上传失败:未收到服务器响应' };
112
81
  }
113
-
82
+
114
83
  // 如果res已经是字符串(文件路径),直接使用
115
84
  if (typeof res === 'string') {
116
85
  return { url: res };
117
86
  }
118
-
87
+
119
88
  // 如果返回的就是服务器的原始响应 { code: 0, msg: '上传成功', data: '文件路径' }
120
89
  // axios拦截器应该已经提取了data部分,但我们做个双重检查
121
90
  if (res.code === 0 && res.data) {
122
91
  return { url: typeof res.data === 'string' ? res.data : '' };
123
92
  }
124
-
93
+
125
94
  // 如果是自定义对象,可能已经处理过
126
95
  if (res.url) {
127
96
  return { url: res.url };
128
97
  }
129
-
98
+
130
99
  // 直接处理服务器响应的标准格式
131
100
  if (typeof res === 'string') {
132
101
  // 直接是文件路径字符串
133
102
  return { url: res };
134
103
  }
135
-
104
+
136
105
  // 如果服务器直接响应了数据,没有包装
137
106
  if (res && !res.code && !res.data && typeof res === 'object') {
138
107
  // 尝试找到可能的URL字段
@@ -140,10 +109,10 @@ const defaultFormatResponse = (res) => {
140
109
  return { url: res.url || res.path || res.filePath || res.fileUrl };
141
110
  }
142
111
  }
143
-
112
+
144
113
  // 处理其他可能的情况
145
114
  console.warn('Unknown response format:', res);
146
-
115
+
147
116
  // 无法识别的格式,返回空URL
148
117
  return { url: '' };
149
118
  };
@@ -368,19 +337,19 @@ const internalAction = computed(() => {
368
337
  // 自定义上传方法,使用dataService进行上传
369
338
  const customRequestMethod = (options) => {
370
339
  console.log('Upload options:', options);
371
-
340
+
372
341
  try {
373
342
  // 解构选项,获取需要的属性
374
343
  const { raw, onProgress, onSuccess, onError, data, method, name } = options || {};
375
-
344
+
376
345
  // 创建FormData
377
346
  const formData = new FormData();
378
-
347
+
379
348
  // 创建一个执行上传的函数
380
349
  const executeUpload = (fileToUpload) => {
381
350
  console.log('Uploading file:', fileToUpload.name, fileToUpload.size);
382
351
  formData.append('file', fileToUpload);
383
-
352
+
384
353
  // 添加额外数据
385
354
  if (data) {
386
355
  Object.keys(data).forEach(key => {
@@ -401,10 +370,10 @@ const customRequestMethod = (options) => {
401
370
  .upload(INTERNAL_UPLOAD_URL, formData, safeProgressCallback)
402
371
  .then(response => {
403
372
  console.log('Upload response:', response);
404
-
373
+
405
374
  // 在组件内部处理响应数据
406
375
  let formattedResponse;
407
-
376
+
408
377
  try {
409
378
  // 使用内部处理逻辑,不依赖props.formatResponse
410
379
  formattedResponse = defaultFormatResponse(response);
@@ -412,7 +381,7 @@ const customRequestMethod = (options) => {
412
381
  console.error('Error formatting response:', error);
413
382
  formattedResponse = { url: '', error: error.message };
414
383
  }
415
-
384
+
416
385
  // 确保格式化后的响应包含文件基本信息
417
386
  const fileObject = {
418
387
  ...formattedResponse,
@@ -423,7 +392,7 @@ const customRequestMethod = (options) => {
423
392
  raw: fileToUpload, // 保存原始文件对象
424
393
  lastModified: fileToUpload.lastModified
425
394
  };
426
-
395
+
427
396
  // 构建TDesign期望的成功响应对象
428
397
  const successResponse = {
429
398
  file: fileObject, // 文件对象
@@ -436,9 +405,9 @@ const customRequestMethod = (options) => {
436
405
  e: { status: 'success' }, // 事件对象
437
406
  status: 'success' // 必须的状态字段,只能是success或fail
438
407
  };
439
-
408
+
440
409
  console.log('Final formatted response:', successResponse);
441
-
410
+
442
411
  // 安全地调用成功回调
443
412
  if (typeof onSuccess === 'function') {
444
413
  onSuccess(successResponse);
@@ -447,14 +416,14 @@ const customRequestMethod = (options) => {
447
416
  })
448
417
  .catch(error => {
449
418
  console.error('Upload failed:', error);
450
-
419
+
451
420
  // 构建错误响应对象
452
421
  const failResponse = {
453
422
  error: error,
454
423
  status: 'fail', // 必须的状态字段,值为fail
455
424
  e: { status: 'fail' }
456
425
  };
457
-
426
+
458
427
  // 安全地调用错误回调
459
428
  if (typeof onError === 'function') {
460
429
  onError(failResponse);
@@ -462,20 +431,20 @@ const customRequestMethod = (options) => {
462
431
  return Promise.reject(failResponse);
463
432
  });
464
433
  };
465
-
434
+
466
435
  // 尝试获取真实的文件对象
467
436
  // 1. 首先检查raw是否直接是File对象
468
437
  if (raw instanceof File) {
469
438
  console.log('Using raw as File directly');
470
439
  return executeUpload(raw);
471
- }
472
-
440
+ }
441
+
473
442
  // 2. 直接从options本身获取信息创建文件
474
443
  if (options && options.name && options.type && options.size) {
475
444
  // 我们找到了文件信息,但没有实际内容
476
445
  // 我们需要使用FileReader获取实际文件或创建一个伪文件
477
446
  console.log('Creating file from options properties');
478
-
447
+
479
448
  // 由于我们无法获取真实文件内容,创建一个伪文件
480
449
  // 注意:这在实际上传时可能会失败,因为没有真实内容
481
450
  const pseudoFileContent = new Blob([`Pseudo file content for ${options.name}`], { type: options.type });
@@ -483,7 +452,7 @@ const customRequestMethod = (options) => {
483
452
  type: options.type,
484
453
  lastModified: options.lastModified || Date.now()
485
454
  });
486
-
455
+
487
456
  // 创建一个隐藏的文件输入,让用户重新选择文件
488
457
  // 这是一个备选方案
489
458
  const fileInput = document.createElement('input');
@@ -491,11 +460,11 @@ const customRequestMethod = (options) => {
491
460
  fileInput.style.display = 'none';
492
461
  fileInput.accept = options.type;
493
462
  document.body.appendChild(fileInput);
494
-
463
+
495
464
  // 提示用户选择同一个文件
496
465
  console.log('Please select the same file again');
497
466
  alert(`上传出错:TDesign上传组件无法获取文件内容。请在出现的文件选择框中重新选择"${options.name}"文件。`);
498
-
467
+
499
468
  return new Promise((resolve, reject) => {
500
469
  fileInput.onchange = (e) => {
501
470
  const selectedFile = e.target.files[0];
@@ -513,7 +482,7 @@ const customRequestMethod = (options) => {
513
482
  reject(failResponse);
514
483
  }
515
484
  };
516
-
485
+
517
486
  fileInput.onerror = (error) => {
518
487
  document.body.removeChild(fileInput);
519
488
  const failResponse = {
@@ -523,12 +492,12 @@ const customRequestMethod = (options) => {
523
492
  };
524
493
  reject(failResponse);
525
494
  };
526
-
495
+
527
496
  // 触发文件选择
528
497
  fileInput.click();
529
498
  });
530
499
  }
531
-
500
+
532
501
  console.error('Cannot find valid file information', options);
533
502
  if (typeof onError === 'function') {
534
503
  const failResponse = {
@@ -573,26 +542,26 @@ watch(
573
542
  // 文件状态变化事件
574
543
  const handleChange = (value, context) => {
575
544
  console.log('Upload change event:', value, context);
576
-
545
+
577
546
  // 如果是上传成功,确保文件被添加到内部列表
578
547
  if (context && context.file && context.file.status === 'success') {
579
548
  const successFile = context.file;
580
-
549
+
581
550
  // 检查是否已存在于内部文件列表
582
551
  const fileExists = internalFiles.value.some(
583
552
  file => file.name === successFile.name && file.size === successFile.size
584
553
  );
585
-
554
+
586
555
  if (!fileExists) {
587
556
  console.log('Adding successful file from change event:', successFile);
588
557
  internalFiles.value = [...internalFiles.value, successFile];
589
-
558
+
590
559
  // 更新v-model和files属性
591
560
  emit('update:modelValue', internalFiles.value);
592
561
  emit('update:files', internalFiles.value);
593
562
  }
594
563
  }
595
-
564
+
596
565
  emit('change', value, context);
597
566
  };
598
567
 
@@ -631,19 +600,19 @@ const handleRemove = (context) => {
631
600
  if (context && context.file) {
632
601
  // 从内部文件列表中移除文件
633
602
  const removedFile = context.file;
634
-
603
+
635
604
  // 根据name和size过滤掉要删除的文件
636
605
  internalFiles.value = internalFiles.value.filter(
637
606
  file => !(file.name === removedFile.name && file.size === removedFile.size)
638
607
  );
639
-
608
+
640
609
  // 同时更新v-model绑定的值,保持一致性
641
610
  emit('update:modelValue', internalFiles.value);
642
-
611
+
643
612
  // 更新files属性,支持v-model:files双向绑定
644
613
  emit('update:files', internalFiles.value);
645
614
  }
646
-
615
+
647
616
  // 发出原始移除事件
648
617
  emit('remove', context);
649
618
  };
@@ -656,7 +625,7 @@ const handleSelectChange = (files, context) => {
656
625
  // 上传成功事件
657
626
  const handleSuccess = (context) => {
658
627
  console.log('Upload success event triggered:', context);
659
-
628
+
660
629
  // 将上传成功的文件添加到文件列表中
661
630
  // 首先检查文件是否已经在列表中
662
631
  if (context && context.file) {
@@ -669,24 +638,24 @@ const handleSuccess = (context) => {
669
638
  } else if (context.response && context.response.data && typeof context.response.data === 'string') {
670
639
  fileUrl = context.response.data;
671
640
  }
672
-
641
+
673
642
  const newFile = {
674
643
  ...context.file,
675
644
  url: fileUrl, // 确保有URL
676
645
  status: 'success', // 设置状态为成功
677
646
  response: context.response // 保留响应
678
647
  };
679
-
648
+
680
649
  console.log('Adding file to internal files:', newFile);
681
650
 
682
651
  // 创建新的文件列表副本,以便进行修改
683
652
  const currentFiles = [...internalFiles.value];
684
-
653
+
685
654
  // 检查文件是否已存在(基于name和size)
686
655
  const fileExists = currentFiles.some(
687
656
  file => file.name === newFile.name && file.size === newFile.size
688
657
  );
689
-
658
+
690
659
  // 如果文件不存在于列表中,则添加它
691
660
  if (!fileExists) {
692
661
  currentFiles.push(newFile);
@@ -701,18 +670,18 @@ const handleSuccess = (context) => {
701
670
  return file;
702
671
  });
703
672
  }
704
-
673
+
705
674
  console.log('Updated internal files:', internalFiles.value);
706
-
675
+
707
676
  // 同时更新v-model绑定的值,保持一致性
708
677
  emit('update:modelValue', internalFiles.value);
709
-
678
+
710
679
  // 更新files属性,支持v-model:files双向绑定
711
680
  emit('update:files', internalFiles.value);
712
681
  } else {
713
682
  console.warn('Missing file in success context:', context);
714
683
  }
715
-
684
+
716
685
  // 发出原始成功事件
717
686
  emit('success', context);
718
687
  };
@@ -728,7 +697,7 @@ const addUploadedFile = (file) => {
728
697
  console.error('Invalid file object. File must contain at least name and url properties.');
729
698
  return false;
730
699
  }
731
-
700
+
732
701
  // 构建完整的文件对象
733
702
  const fileObject = {
734
703
  name: file.name,
@@ -741,24 +710,24 @@ const addUploadedFile = (file) => {
741
710
  lastModified: file.lastModified || new Date().getTime(),
742
711
  ...file
743
712
  };
744
-
713
+
745
714
  // 检查文件是否已存在
746
715
  const fileExists = internalFiles.value.some(
747
716
  f => f.name === fileObject.name && f.url === fileObject.url
748
717
  );
749
-
718
+
750
719
  if (!fileExists) {
751
720
  // 更新内部文件列表
752
721
  internalFiles.value = [...internalFiles.value, fileObject];
753
-
722
+
754
723
  // 同时更新v-model绑定的值,保持一致性
755
724
  emit('update:modelValue', internalFiles.value);
756
-
725
+
757
726
  // 更新files属性,支持v-model:files双向绑定
758
727
  emit('update:files', internalFiles.value);
759
728
  return true;
760
729
  }
761
-
730
+
762
731
  return false;
763
732
  };
764
733
 
@@ -786,4 +755,4 @@ watch(
786
755
 
787
756
  <style lang="less" scoped>
788
757
  /* 自定义样式 */
789
- </style>
758
+ </style>
package/src/index.js CHANGED
@@ -22,6 +22,7 @@ import EbizMindmap from "./components/EbizMindmap/index.vue";
22
22
  import EbizRouteBreadcrumb from "./components/EbizRouteBreadcrumb.vue";
23
23
  import EbizFileUpload from "./components/EbizFileUpload.vue";
24
24
  import EbizTabHeader from "./components/EbizTabHeader.vue";
25
+ import EbizPageHeader from "./components/EbizPageHeader.vue";
25
26
  import TdesignCalendar from "./components/TdesignCalendar/index.vue";
26
27
  import TdesignCollapse from "./components/TdesignCollapse.vue";
27
28
  import TdesignCollapsePanel from "./components/TdesignCollapsePanel.vue";
@@ -46,6 +47,13 @@ import EbizWatermark from "./components/TdesignWatermark.vue";
46
47
  import EbizAvatar from "./components/EbizAvatar.vue";
47
48
  import EbizEmployeeInfo from "./components/EbizEmployeeInfo.vue";
48
49
  import EbizAlert from "./components/TdesignAlert.vue";
50
+ import EbizDialog from "./components/TdesignDialog.vue";
51
+ import EbizTable from "./components/EbizTable.vue";
52
+ import EbizTableColumn from './components/EbizTableColumn.vue';
53
+ import EbizTableSort from './components/EbizTableSort.vue';
54
+ import EbizDetailBlock from './components/EbizDetailBlock.vue';
55
+ import EbizTree from './components/EbizTree.vue';
56
+ import EbizTreeSelector from './components/EbizTreeSelector.vue';
49
57
  import { MessagePlugin as EbizMessage } from 'tdesign-vue-next';
50
58
 
51
59
  // 导入简洁数据服务
@@ -84,6 +92,8 @@ export {
84
92
  EbizRemoteSelect,
85
93
  EbizRouteBreadcrumb,
86
94
  EbizTabHeader,
95
+ // 页面头部组件
96
+ EbizPageHeader,
87
97
  // 思维导图
88
98
  EbizMindmap,
89
99
  // 文件上传组件
@@ -140,5 +150,17 @@ export {
140
150
  // 员工信息组件
141
151
  EbizEmployeeInfo,
142
152
  // 提示组件
143
- EbizAlert
153
+ EbizAlert,
154
+ // 对话框组件
155
+ EbizDialog,
156
+ // 表格组件
157
+ EbizTable,
158
+ EbizTableColumn,
159
+ // 表格排序组件
160
+ EbizTableSort,
161
+ // 详情块组件
162
+ EbizDetailBlock,
163
+ // 树组件
164
+ EbizTree,
165
+ EbizTreeSelector
144
166
  };
package/src/main.js CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  dataService
24
24
  } from './index.js'
25
25
 
26
- import "tdesign-vue-next/es/style/index.css"
27
- import "./assets/styles/charts/main.less"
26
+ import 'tdesign-vue-next/es/style/index.css'
27
+ import './assets/styles/charts/main.less'
28
28
 
29
29
  const app = createApp(App)
30
30
 
@@ -1,10 +1,13 @@
1
1
  import { createRouter, createWebHistory } from 'vue-router'
2
+ import Home from '../views/Home.vue'
3
+ import ButtonView from '../views/Button.vue'
4
+ import TableView from '../views/TableView.vue'
2
5
 
3
6
  const routes = [
4
7
  {
5
8
  path: '/',
6
9
  name: 'Home',
7
- component: () => import('../views/Home.vue'),
10
+ component: Home,
8
11
  meta: { title: '首页' }
9
12
  },
10
13
  {
@@ -15,10 +18,16 @@ const routes = [
15
18
  },
16
19
  {
17
20
  path: '/table',
18
- name: 'Table',
19
- component: () => import('../views/Table.vue'),
21
+ name: 'table',
22
+ component: TableView,
20
23
  meta: { title: '表格组件示例' }
21
24
  },
25
+ {
26
+ path: '/table-column',
27
+ name: 'table-column',
28
+ component: TableView,
29
+ meta: { title: '表格列组件示例' }
30
+ },
22
31
  {
23
32
  path: '/form',
24
33
  name: 'Form',
@@ -27,8 +36,8 @@ const routes = [
27
36
  },
28
37
  {
29
38
  path: '/button',
30
- name: 'Button',
31
- component: () => import('../views/Button.vue'),
39
+ name: 'button',
40
+ component: ButtonView,
32
41
  meta: { title: '按钮组件示例' }
33
42
  },
34
43
  {
@@ -228,6 +237,56 @@ const routes = [
228
237
  name: 'TdesignAlert',
229
238
  component: () => import('../views/TdesignAlert.vue'),
230
239
  meta: { title: 'TDesign提示组件示例' }
240
+ },
241
+ {
242
+ path: '/tdesign-dialog',
243
+ name: 'TdesignDialog',
244
+ component: () => import('../views/DialogDemo.vue'),
245
+ meta: { title: 'TDesign对话框组件示例' }
246
+ },
247
+ {
248
+ path: '/page-header',
249
+ name: 'PageHeader',
250
+ component: () => import('../views/PageHeaderDemo.vue'),
251
+ meta: { title: 'Ebiz页面头部组件示例', icon: 'header' }
252
+ },
253
+ {
254
+ path: '/table-demo',
255
+ name: 'TableDemo',
256
+ component: () => import('../views/TableDemo.vue'),
257
+ meta: { title: 'Ebiz表格组件示例' }
258
+ },
259
+ {
260
+ path: '/table-sort',
261
+ name: 'TableSort',
262
+ component: () => import('../views/TableSortDemo.vue'),
263
+ meta: { title: 'Ebiz表格排序组件示例' }
264
+ },
265
+ {
266
+ path: '/ebiz-detail-block',
267
+ name: 'EbizDetailBlock',
268
+ component: () => import('../views/EbizDetailBlockDemo.vue'),
269
+ meta: { title: 'Ebiz详情块组件示例' }
270
+ },
271
+ {
272
+ path: '/tree',
273
+ name: 'Tree',
274
+ component: () => import('../views/TreeDemo.vue'),
275
+ meta: { title: 'Ebiz树组件示例' }
276
+ },
277
+ {
278
+ path: '/tree-demo',
279
+ name: 'TreeDemo',
280
+ component: () => import('../views/TreeDemo.vue'),
281
+ meta: { title: 'Ebiz树组件示例' }
282
+ },
283
+ {
284
+ path: '/tree-selector-demo',
285
+ name: 'TreeSelectorDemo',
286
+ component: () => import('../views/TreeSelectorDemo.vue'),
287
+ meta: {
288
+ title: '树形选择器'
289
+ }
231
290
  }
232
291
  ]
233
292
 
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <ebiz-route-breadcrumb />
4
- <ebiz-button />
4
+ <ebiz-button :text="测试" :apiConfig="{ apiId: 802, apiType: 5 }" @prepare="onPrepare" />
5
5
  </div>
6
6
  </template>
7
7
 
@@ -12,9 +12,13 @@ export default {
12
12
  name: 'ButtonDemo',
13
13
  components: {
14
14
  EbizButton
15
+ },
16
+ methods: {
17
+ onPrepare() {
18
+
19
+ }
15
20
  }
16
21
  }
17
22
  </script>
18
23
 
19
- <style scoped>
20
- </style>
24
+ <style scoped></style>