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

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,15 @@
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"
22
- :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
- >
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"
7
+ :showUploadProgress="showUploadProgress" :sizeLimit="sizeLimit" :status="status" :theme="theme" :tips="tips"
8
+ :uploadAllFilesInOneRequest="uploadAllFilesInOneRequest" :uploadButton="uploadButton"
9
+ :useMockProgress="useMockProgress" :withCredentials="withCredentials" v-model="modelValue"
10
+ @change="handleChange" @click="handleClick" @drag="handleDrag" @drop="handleDrop" @fail="handleFail"
11
+ @preview="handlePreview" @progress="handleProgress" @remove="handleRemove" @select-change="handleSelectChange"
12
+ @success="handleSuccess" @validate="handleValidate">
45
13
  <!-- 默认插槽 -->
46
14
  <slot></slot>
47
15
 
@@ -89,7 +57,7 @@ import { Upload as TUpload } from 'tdesign-vue-next';
89
57
  import dataService from '../apiService/simpleDataService';
90
58
 
91
59
  // 内部上传地址常量
92
- const INTERNAL_UPLOAD_URL = '/file/upload';
60
+ const INTERNAL_UPLOAD_URL = '/api/file/app/td-upload';
93
61
 
94
62
  // 内部维护的文件列表,代替直接使用props.files
95
63
  const internalFiles = ref([]);
@@ -105,34 +73,34 @@ const initializeFiles = () => {
105
73
  // 默认的格式化响应函数
106
74
  const defaultFormatResponse = (res) => {
107
75
  console.log('Default formatResponse handling:', res);
108
-
76
+
109
77
  // 处理不同的响应格式
110
78
  if (res === null || res === undefined) {
111
79
  return { url: '', error: '上传失败:未收到服务器响应' };
112
80
  }
113
-
81
+
114
82
  // 如果res已经是字符串(文件路径),直接使用
115
83
  if (typeof res === 'string') {
116
84
  return { url: res };
117
85
  }
118
-
86
+
119
87
  // 如果返回的就是服务器的原始响应 { code: 0, msg: '上传成功', data: '文件路径' }
120
88
  // axios拦截器应该已经提取了data部分,但我们做个双重检查
121
89
  if (res.code === 0 && res.data) {
122
90
  return { url: typeof res.data === 'string' ? res.data : '' };
123
91
  }
124
-
92
+
125
93
  // 如果是自定义对象,可能已经处理过
126
94
  if (res.url) {
127
95
  return { url: res.url };
128
96
  }
129
-
97
+
130
98
  // 直接处理服务器响应的标准格式
131
99
  if (typeof res === 'string') {
132
100
  // 直接是文件路径字符串
133
101
  return { url: res };
134
102
  }
135
-
103
+
136
104
  // 如果服务器直接响应了数据,没有包装
137
105
  if (res && !res.code && !res.data && typeof res === 'object') {
138
106
  // 尝试找到可能的URL字段
@@ -140,10 +108,10 @@ const defaultFormatResponse = (res) => {
140
108
  return { url: res.url || res.path || res.filePath || res.fileUrl };
141
109
  }
142
110
  }
143
-
111
+
144
112
  // 处理其他可能的情况
145
113
  console.warn('Unknown response format:', res);
146
-
114
+
147
115
  // 无法识别的格式,返回空URL
148
116
  return { url: '' };
149
117
  };
@@ -305,7 +273,7 @@ const props = defineProps({
305
273
  // 是否使用内部上传服务,如果为true则忽略action参数
306
274
  useInternalUpload: {
307
275
  type: Boolean,
308
- default: true
276
+ default: false
309
277
  }
310
278
  });
311
279
 
@@ -368,19 +336,19 @@ const internalAction = computed(() => {
368
336
  // 自定义上传方法,使用dataService进行上传
369
337
  const customRequestMethod = (options) => {
370
338
  console.log('Upload options:', options);
371
-
339
+
372
340
  try {
373
341
  // 解构选项,获取需要的属性
374
342
  const { raw, onProgress, onSuccess, onError, data, method, name } = options || {};
375
-
343
+
376
344
  // 创建FormData
377
345
  const formData = new FormData();
378
-
346
+
379
347
  // 创建一个执行上传的函数
380
348
  const executeUpload = (fileToUpload) => {
381
349
  console.log('Uploading file:', fileToUpload.name, fileToUpload.size);
382
350
  formData.append('file', fileToUpload);
383
-
351
+
384
352
  // 添加额外数据
385
353
  if (data) {
386
354
  Object.keys(data).forEach(key => {
@@ -401,10 +369,10 @@ const customRequestMethod = (options) => {
401
369
  .upload(INTERNAL_UPLOAD_URL, formData, safeProgressCallback)
402
370
  .then(response => {
403
371
  console.log('Upload response:', response);
404
-
372
+
405
373
  // 在组件内部处理响应数据
406
374
  let formattedResponse;
407
-
375
+
408
376
  try {
409
377
  // 使用内部处理逻辑,不依赖props.formatResponse
410
378
  formattedResponse = defaultFormatResponse(response);
@@ -412,7 +380,7 @@ const customRequestMethod = (options) => {
412
380
  console.error('Error formatting response:', error);
413
381
  formattedResponse = { url: '', error: error.message };
414
382
  }
415
-
383
+
416
384
  // 确保格式化后的响应包含文件基本信息
417
385
  const fileObject = {
418
386
  ...formattedResponse,
@@ -423,7 +391,7 @@ const customRequestMethod = (options) => {
423
391
  raw: fileToUpload, // 保存原始文件对象
424
392
  lastModified: fileToUpload.lastModified
425
393
  };
426
-
394
+
427
395
  // 构建TDesign期望的成功响应对象
428
396
  const successResponse = {
429
397
  file: fileObject, // 文件对象
@@ -436,9 +404,9 @@ const customRequestMethod = (options) => {
436
404
  e: { status: 'success' }, // 事件对象
437
405
  status: 'success' // 必须的状态字段,只能是success或fail
438
406
  };
439
-
407
+
440
408
  console.log('Final formatted response:', successResponse);
441
-
409
+
442
410
  // 安全地调用成功回调
443
411
  if (typeof onSuccess === 'function') {
444
412
  onSuccess(successResponse);
@@ -447,14 +415,14 @@ const customRequestMethod = (options) => {
447
415
  })
448
416
  .catch(error => {
449
417
  console.error('Upload failed:', error);
450
-
418
+
451
419
  // 构建错误响应对象
452
420
  const failResponse = {
453
421
  error: error,
454
422
  status: 'fail', // 必须的状态字段,值为fail
455
423
  e: { status: 'fail' }
456
424
  };
457
-
425
+
458
426
  // 安全地调用错误回调
459
427
  if (typeof onError === 'function') {
460
428
  onError(failResponse);
@@ -462,20 +430,20 @@ const customRequestMethod = (options) => {
462
430
  return Promise.reject(failResponse);
463
431
  });
464
432
  };
465
-
433
+
466
434
  // 尝试获取真实的文件对象
467
435
  // 1. 首先检查raw是否直接是File对象
468
436
  if (raw instanceof File) {
469
437
  console.log('Using raw as File directly');
470
438
  return executeUpload(raw);
471
- }
472
-
439
+ }
440
+
473
441
  // 2. 直接从options本身获取信息创建文件
474
442
  if (options && options.name && options.type && options.size) {
475
443
  // 我们找到了文件信息,但没有实际内容
476
444
  // 我们需要使用FileReader获取实际文件或创建一个伪文件
477
445
  console.log('Creating file from options properties');
478
-
446
+
479
447
  // 由于我们无法获取真实文件内容,创建一个伪文件
480
448
  // 注意:这在实际上传时可能会失败,因为没有真实内容
481
449
  const pseudoFileContent = new Blob([`Pseudo file content for ${options.name}`], { type: options.type });
@@ -483,7 +451,7 @@ const customRequestMethod = (options) => {
483
451
  type: options.type,
484
452
  lastModified: options.lastModified || Date.now()
485
453
  });
486
-
454
+
487
455
  // 创建一个隐藏的文件输入,让用户重新选择文件
488
456
  // 这是一个备选方案
489
457
  const fileInput = document.createElement('input');
@@ -491,11 +459,11 @@ const customRequestMethod = (options) => {
491
459
  fileInput.style.display = 'none';
492
460
  fileInput.accept = options.type;
493
461
  document.body.appendChild(fileInput);
494
-
462
+
495
463
  // 提示用户选择同一个文件
496
464
  console.log('Please select the same file again');
497
465
  alert(`上传出错:TDesign上传组件无法获取文件内容。请在出现的文件选择框中重新选择"${options.name}"文件。`);
498
-
466
+
499
467
  return new Promise((resolve, reject) => {
500
468
  fileInput.onchange = (e) => {
501
469
  const selectedFile = e.target.files[0];
@@ -513,7 +481,7 @@ const customRequestMethod = (options) => {
513
481
  reject(failResponse);
514
482
  }
515
483
  };
516
-
484
+
517
485
  fileInput.onerror = (error) => {
518
486
  document.body.removeChild(fileInput);
519
487
  const failResponse = {
@@ -523,12 +491,12 @@ const customRequestMethod = (options) => {
523
491
  };
524
492
  reject(failResponse);
525
493
  };
526
-
494
+
527
495
  // 触发文件选择
528
496
  fileInput.click();
529
497
  });
530
498
  }
531
-
499
+
532
500
  console.error('Cannot find valid file information', options);
533
501
  if (typeof onError === 'function') {
534
502
  const failResponse = {
@@ -573,26 +541,26 @@ watch(
573
541
  // 文件状态变化事件
574
542
  const handleChange = (value, context) => {
575
543
  console.log('Upload change event:', value, context);
576
-
544
+
577
545
  // 如果是上传成功,确保文件被添加到内部列表
578
546
  if (context && context.file && context.file.status === 'success') {
579
547
  const successFile = context.file;
580
-
548
+
581
549
  // 检查是否已存在于内部文件列表
582
550
  const fileExists = internalFiles.value.some(
583
551
  file => file.name === successFile.name && file.size === successFile.size
584
552
  );
585
-
553
+
586
554
  if (!fileExists) {
587
555
  console.log('Adding successful file from change event:', successFile);
588
556
  internalFiles.value = [...internalFiles.value, successFile];
589
-
557
+
590
558
  // 更新v-model和files属性
591
559
  emit('update:modelValue', internalFiles.value);
592
560
  emit('update:files', internalFiles.value);
593
561
  }
594
562
  }
595
-
563
+
596
564
  emit('change', value, context);
597
565
  };
598
566
 
@@ -631,19 +599,19 @@ const handleRemove = (context) => {
631
599
  if (context && context.file) {
632
600
  // 从内部文件列表中移除文件
633
601
  const removedFile = context.file;
634
-
602
+
635
603
  // 根据name和size过滤掉要删除的文件
636
604
  internalFiles.value = internalFiles.value.filter(
637
605
  file => !(file.name === removedFile.name && file.size === removedFile.size)
638
606
  );
639
-
607
+
640
608
  // 同时更新v-model绑定的值,保持一致性
641
609
  emit('update:modelValue', internalFiles.value);
642
-
610
+
643
611
  // 更新files属性,支持v-model:files双向绑定
644
612
  emit('update:files', internalFiles.value);
645
613
  }
646
-
614
+
647
615
  // 发出原始移除事件
648
616
  emit('remove', context);
649
617
  };
@@ -656,7 +624,7 @@ const handleSelectChange = (files, context) => {
656
624
  // 上传成功事件
657
625
  const handleSuccess = (context) => {
658
626
  console.log('Upload success event triggered:', context);
659
-
627
+
660
628
  // 将上传成功的文件添加到文件列表中
661
629
  // 首先检查文件是否已经在列表中
662
630
  if (context && context.file) {
@@ -669,24 +637,24 @@ const handleSuccess = (context) => {
669
637
  } else if (context.response && context.response.data && typeof context.response.data === 'string') {
670
638
  fileUrl = context.response.data;
671
639
  }
672
-
640
+
673
641
  const newFile = {
674
642
  ...context.file,
675
643
  url: fileUrl, // 确保有URL
676
644
  status: 'success', // 设置状态为成功
677
645
  response: context.response // 保留响应
678
646
  };
679
-
647
+
680
648
  console.log('Adding file to internal files:', newFile);
681
649
 
682
650
  // 创建新的文件列表副本,以便进行修改
683
651
  const currentFiles = [...internalFiles.value];
684
-
652
+
685
653
  // 检查文件是否已存在(基于name和size)
686
654
  const fileExists = currentFiles.some(
687
655
  file => file.name === newFile.name && file.size === newFile.size
688
656
  );
689
-
657
+
690
658
  // 如果文件不存在于列表中,则添加它
691
659
  if (!fileExists) {
692
660
  currentFiles.push(newFile);
@@ -701,18 +669,18 @@ const handleSuccess = (context) => {
701
669
  return file;
702
670
  });
703
671
  }
704
-
672
+
705
673
  console.log('Updated internal files:', internalFiles.value);
706
-
674
+
707
675
  // 同时更新v-model绑定的值,保持一致性
708
676
  emit('update:modelValue', internalFiles.value);
709
-
677
+
710
678
  // 更新files属性,支持v-model:files双向绑定
711
679
  emit('update:files', internalFiles.value);
712
680
  } else {
713
681
  console.warn('Missing file in success context:', context);
714
682
  }
715
-
683
+
716
684
  // 发出原始成功事件
717
685
  emit('success', context);
718
686
  };
@@ -728,7 +696,7 @@ const addUploadedFile = (file) => {
728
696
  console.error('Invalid file object. File must contain at least name and url properties.');
729
697
  return false;
730
698
  }
731
-
699
+
732
700
  // 构建完整的文件对象
733
701
  const fileObject = {
734
702
  name: file.name,
@@ -741,24 +709,24 @@ const addUploadedFile = (file) => {
741
709
  lastModified: file.lastModified || new Date().getTime(),
742
710
  ...file
743
711
  };
744
-
712
+
745
713
  // 检查文件是否已存在
746
714
  const fileExists = internalFiles.value.some(
747
715
  f => f.name === fileObject.name && f.url === fileObject.url
748
716
  );
749
-
717
+
750
718
  if (!fileExists) {
751
719
  // 更新内部文件列表
752
720
  internalFiles.value = [...internalFiles.value, fileObject];
753
-
721
+
754
722
  // 同时更新v-model绑定的值,保持一致性
755
723
  emit('update:modelValue', internalFiles.value);
756
-
724
+
757
725
  // 更新files属性,支持v-model:files双向绑定
758
726
  emit('update:files', internalFiles.value);
759
727
  return true;
760
728
  }
761
-
729
+
762
730
  return false;
763
731
  };
764
732
 
@@ -786,4 +754,4 @@ watch(
786
754
 
787
755
  <style lang="less" scoped>
788
756
  /* 自定义样式 */
789
- </style>
757
+ </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>