@ebiz/designer-components 0.0.22 → 0.0.24

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebiz/designer-components",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <div>
3
+ <t-cascader v-model="selectedValue" :options="departmentTreeData" :placeholder="placeholder" :clearable="clearable"
4
+ :disabled="disabled" :size="size" :multiple="multiple" :max="max" :checkStrictly="checkStrictly"
5
+ :filterable="filterable" :loading="loading" @change="handleChange">
6
+ <template v-if="$slots.empty" #empty>
7
+ <slot name="empty"></slot>
8
+ </template>
9
+ <template v-if="$slots.dropdownItem" #dropdownItem="slotProps">
10
+ <slot name="dropdownItem" v-bind="slotProps"></slot>
11
+ </template>
12
+ <template v-if="$slots.collapsedItems" #collapsedItems="slotProps">
13
+ <slot name="collapsedItems" v-bind="slotProps"></slot>
14
+ </template>
15
+ <template v-if="$slots.suffix" #suffix>
16
+ <slot name="suffix"></slot>
17
+ </template>
18
+ <template v-if="$slots.prefixIcon" #prefixIcon>
19
+ <slot name="prefixIcon"></slot>
20
+ </template>
21
+ </t-cascader>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ import { ref, computed, onMounted, watch } from 'vue';
27
+ import { Cascader as TCascader } from 'tdesign-vue-next';
28
+ import { dataService } from '../index.js';
29
+
30
+ // 定义组件属性
31
+ const props = defineProps({
32
+ modelValue: {
33
+ type: [String, Number, Array],
34
+ default: undefined
35
+ },
36
+ placeholder: {
37
+ type: String,
38
+ default: '请选择部门'
39
+ },
40
+ clearable: {
41
+ type: Boolean,
42
+ default: true
43
+ },
44
+ disabled: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ size: {
49
+ type: String,
50
+ default: undefined,
51
+ validator: (val) => ['small', 'medium', 'large'].includes(val)
52
+ },
53
+ multiple: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ max: {
58
+ type: Number,
59
+ default: 0
60
+ },
61
+ checkStrictly: {
62
+ type: Boolean,
63
+ default: true
64
+ },
65
+ filterable: {
66
+ type: Boolean,
67
+ default: true
68
+ }
69
+ });
70
+
71
+ // 定义组件事件
72
+ const emit = defineEmits(['update:modelValue', 'change']);
73
+
74
+ // 内部状态变量
75
+ const departmentData = ref([]);
76
+ const departmentTreeData = ref([]);
77
+ const loading = ref(false);
78
+ const selectedValue = computed({
79
+ get: () => props.modelValue,
80
+ set: (val) => emit('update:modelValue', val)
81
+ });
82
+
83
+ // 处理变更事件
84
+ const handleChange = (value, context) => {
85
+ console.log(value, context.node.data);
86
+ emit('change', value, context);
87
+ };
88
+
89
+ // 将部门列表数据转换为树形结构
90
+ const buildDepartmentTree = (data, parentId = null) => {
91
+ return data
92
+ .filter(item => item.manager_dept === parentId)
93
+ .map(item => {
94
+ const children = buildDepartmentTree(data, item.id);
95
+ return {
96
+ ...item,
97
+ label: item.name,
98
+ value: item.id,
99
+ children: children.length > 0 ? children : undefined
100
+ };
101
+ });
102
+ };
103
+
104
+ // 加载部门数据
105
+ const loadDepartmentData = async () => {
106
+ try {
107
+ loading.value = true;
108
+ dataService.fetch({},{
109
+ apiId: 1933,
110
+ apiType: 'MULTIPLE_DATA_SEARCH'
111
+ }).then(res => {
112
+ departmentData.value = res.data || [];
113
+ departmentTreeData.value = buildDepartmentTree(departmentData.value,0);
114
+ }).catch(err => {
115
+ console.error('获取部门数据失败:', err);
116
+ }).finally(() => {
117
+ loading.value = false;
118
+ });
119
+ } catch (error) {
120
+ console.error('获取部门数据失败:', error);
121
+ departmentData.value = [];
122
+ departmentTreeData.value = [];
123
+ } finally {
124
+ loading.value = false;
125
+ }
126
+ };
127
+
128
+ // 组件挂载时加载数据
129
+ onMounted(() => {
130
+ loadDepartmentData();
131
+ });
132
+ </script>
133
+
134
+ <style>
135
+ .ebiz-department-selector {
136
+ width: 100%;
137
+ }
138
+ </style>
@@ -194,7 +194,7 @@ const handleBlur = (value, context) => {
194
194
  // 值变化处理函数
195
195
  const handleChange = (value, context) => {
196
196
  emit('update:modelValue', value);
197
- emit('change', value, context);
197
+ emit('change', value, context, options.value);
198
198
  };
199
199
 
200
200
  // 组件挂载时,如果有默认值则加载对应的选项
package/src/index.js CHANGED
@@ -59,6 +59,7 @@ import EbizPopconfirm from './components/EbizPopconfirm.vue';
59
59
  import EbizTreeMergeTable from './components/EbizTreeMergeTable.vue';
60
60
  import EbizTdesignLoading from './components/EbizTdesignLoading.vue';
61
61
  import EbizAutoForm from './components/EbizAutoForm.vue';
62
+ import EbizDepartmentSelector from './components/EbizDepartmentSelector.vue';
62
63
  import { MessagePlugin as EbizMessage } from 'tdesign-vue-next';
63
64
 
64
65
  // import EbizDescriptions from './components/EbizDescriptions.vue';
@@ -183,6 +184,8 @@ export {
183
184
  EbizTreeMergeTable,
184
185
  // 自动表单组件
185
186
  EbizAutoForm,
187
+ // 部门选择器组件
188
+ EbizDepartmentSelector,
186
189
  // 新增 EbizDescriptions 和 EbizDescriptionsItem
187
190
  EbizDescriptions,
188
191
  EbizDescriptionsItem,
@@ -304,6 +304,12 @@ const routes = [
304
304
  name: 'TreeMergeTableDemo',
305
305
  component: () => import('../views/TreeMergeTableDemo.vue'),
306
306
  meta: { title: '树形合并表格组件示例' }
307
+ },
308
+ {
309
+ path: '/ebiz-department-selector',
310
+ name: 'EbizDepartmentSelector',
311
+ component: () => import('../views/EbizDepartmentSelectorDemo.vue'),
312
+ meta: { title: 'Ebiz部门选择器组件示例' }
307
313
  }
308
314
  ]
309
315
 
@@ -0,0 +1,170 @@
1
+ <template>
2
+ <div class="department-selector-demo">
3
+ <h1>部门选择器组件</h1>
4
+
5
+ <section class="demo-section">
6
+ <h2>基础用法</h2>
7
+ <div>
8
+ <EbizDepartmentSelector v-model="selectedDepartment" placeholder="请选择部门" />
9
+ <div class="result-container">
10
+ <p>选中结果: {{ selectedDepartment }}</p>
11
+ </div>
12
+ </div>
13
+ </section>
14
+
15
+ <section class="demo-section">
16
+ <h2>多选模式</h2>
17
+ <div class="demo-box">
18
+ <EbizDepartmentSelector
19
+ v-model="selectedMultipleDepartments"
20
+ placeholder="请选择多个部门"
21
+ :multiple="true"
22
+ />
23
+ <div class="result-container">
24
+ <p>选中结果: {{ selectedMultipleDepartments }}</p>
25
+ </div>
26
+ </div>
27
+ </section>
28
+
29
+ <section class="demo-section">
30
+ <h2>可选择任意层级</h2>
31
+ <div class="demo-box">
32
+ <EbizDepartmentSelector
33
+ v-model="selectedWithStrictly"
34
+ placeholder="任意层级皆可选择"
35
+ :checkStrictly="true"
36
+ :multiple="true"
37
+ />
38
+ <div class="result-container">
39
+ <p>选中结果: {{ selectedWithStrictly }}</p>
40
+ </div>
41
+ </div>
42
+ </section>
43
+
44
+ <section class="demo-section">
45
+ <h2>不同尺寸</h2>
46
+ <div class="demo-box">
47
+ <div class="size-row">
48
+ <EbizDepartmentSelector
49
+ v-model="selectedSizeSmall"
50
+ placeholder="小型尺寸"
51
+ size="small"
52
+ />
53
+ <EbizDepartmentSelector
54
+ v-model="selectedSizeMedium"
55
+ placeholder="中型尺寸"
56
+ size="medium"
57
+ />
58
+ <EbizDepartmentSelector
59
+ v-model="selectedSizeLarge"
60
+ placeholder="大型尺寸"
61
+ size="large"
62
+ />
63
+ </div>
64
+ </div>
65
+ </section>
66
+
67
+ <section class="demo-section">
68
+ <h2>自定义API地址</h2>
69
+ <div class="demo-box">
70
+ <EbizDepartmentSelector
71
+ v-model="selectedCustomApi"
72
+ placeholder="自定义API地址"
73
+ apiUrl="/api/custom-departments"
74
+ />
75
+ </div>
76
+ </section>
77
+
78
+ <section class="demo-section">
79
+ <h2>禁用状态</h2>
80
+ <div class="demo-box">
81
+ <EbizDepartmentSelector
82
+ v-model="selectedDisabled"
83
+ placeholder="禁用状态"
84
+ :disabled="true"
85
+ />
86
+ </div>
87
+ </section>
88
+ </div>
89
+ </template>
90
+
91
+ <script setup>
92
+ import { ref } from 'vue';
93
+ import { EbizDepartmentSelector } from '../index.js';
94
+
95
+ // 单选模式
96
+ const selectedDepartment = ref(90);
97
+
98
+ // 多选模式
99
+ const selectedMultipleDepartments = ref([]);
100
+
101
+ // 可选择任意层级
102
+ const selectedWithStrictly = ref([]);
103
+
104
+ // 不同尺寸
105
+ const selectedSizeSmall = ref();
106
+ const selectedSizeMedium = ref();
107
+ const selectedSizeLarge = ref();
108
+
109
+ // 自定义API地址
110
+ const selectedCustomApi = ref();
111
+
112
+ // 禁用状态
113
+ const selectedDisabled = ref();
114
+
115
+ // 模拟的Mock数据,用于在实际环境无法请求API时展示
116
+ // 在实际开发环境下,可以查看浏览器控制台的网络请求
117
+ // 这里模拟的数据可在开发环境下直接测试组件功能
118
+ console.log('提示:实际环境中组件会请求API获取数据,这里为了演示效果,提供一些模拟数据');
119
+ console.log('模拟数据结构:[{ id: 1, name: "总部", manager_dept: null }, { id: 2, name: "研发部", manager_dept: 1 }, ...]');
120
+
121
+ </script>
122
+
123
+ <style scoped>
124
+ .department-selector-demo {
125
+ padding: 20px;
126
+ max-width: 1000px;
127
+ margin: 0 auto;
128
+ }
129
+
130
+ h1 {
131
+ margin-bottom: 30px;
132
+ font-size: 24px;
133
+ font-weight: 500;
134
+ color: #0052d9;
135
+ }
136
+
137
+ .demo-section {
138
+ margin-bottom: 40px;
139
+ }
140
+
141
+ h2 {
142
+ margin-bottom: 16px;
143
+ font-size: 18px;
144
+ font-weight: 500;
145
+ color: #333;
146
+ }
147
+
148
+ .demo-box {
149
+ padding: 24px;
150
+ border: 1px solid #e7e7e7;
151
+ border-radius: 6px;
152
+ background-color: #fff;
153
+ }
154
+
155
+ .result-container {
156
+ margin-top: 16px;
157
+ padding: 12px;
158
+ background-color: #f9f9f9;
159
+ border-radius: 4px;
160
+ }
161
+
162
+ .size-row {
163
+ display: flex;
164
+ gap: 16px;
165
+ }
166
+
167
+ .size-row > * {
168
+ flex: 1;
169
+ }
170
+ </style>
@@ -78,7 +78,8 @@ export default {
78
78
  { path: '/tdesign-descriptions', title: 'Ebiz描述列表组件示例' },
79
79
  { path: '/popconfirm', title: 'Ebiz气泡确认框组件示例' },
80
80
  { path: '/tree-merge-table-demo', title: '树形合并表格组件示例' },
81
- { path: '/auto-form-demo', title: 'Ebiz自动表单组件示例' }
81
+ { path: '/auto-form-demo', title: 'Ebiz自动表单组件示例' },
82
+ { path: '/ebiz-department-selector', title: 'Ebiz部门选择器组件示例' }
82
83
  ]
83
84
 
84
85
  return {