@ctzy-web-client/plugin-component-vue 1.0.30 → 1.0.32

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.
@@ -18,8 +18,9 @@
18
18
  ref="advanceSelectRef"
19
19
  >
20
20
  <template #reference-content="{ selected }">
21
- <div :class="ns.e('content')" v-if="multiple">
22
- <div v-if="selected && selected.length > 0">
21
+ <!-- 多选模式 -->
22
+ <div v-if="multiple" :class="ns.e('content')" @click="handleContentClick">
23
+ <div v-if="selected && selected.length > 0" style="display: flex; align-items: center; flex-wrap: wrap; gap: 4px;">
23
24
  <ElTooltip :content="selected[0].label" placement="top" effect="light" append-to=".bwa-application">
24
25
  <el-tag :class="ns.e('tag')" closable @close="handleClose(selected[0])" type="info">{{selected[0].label}}
25
26
  </el-tag>
@@ -38,13 +39,47 @@
38
39
  </el-tag>
39
40
  </template>
40
41
  </div>
41
-
42
42
  </template>
43
43
  <el-tag :class="ns.e('tag')" type="info" v-if="selected.length > 1">+{{selected.length - 1}}</el-tag>
44
44
  </ElTooltip>
45
-
45
+ <!-- 搜索输入区域 -->
46
+ <div v-if="props.showSearch && !column.componentProps?.options" style="flex: 1; min-width: 80px; position: relative;">
47
+ <span v-if="!isSearchActive && !search" style="color: #999; cursor: text;">{{searchPlaceholderStr || '搜索'}}</span>
48
+ <span v-else style="color: #333;">{{search}}</span>
49
+ <!-- 闪烁光标 -->
50
+ <span v-if="isSearchActive" class="cursor-blink"></span>
51
+ <!-- 隐藏的输入框 -->
52
+ <input
53
+ v-if="props.showSearch && !column.componentProps?.options"
54
+ ref="inputRef"
55
+ v-model="search"
56
+ type="text"
57
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: text;"
58
+ @focus="handleInputFocus"
59
+ @blur="handleInputBlur"
60
+ @click.stop
61
+ />
62
+ </div>
63
+ </div>
64
+ <div v-else style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
65
+ <div style="flex: 1; position: relative; cursor: text;" @click="handleContentClick">
66
+ <span v-if="!isSearchActive && !search" :class="ns.e('contentBox_placeholder')">{{placeholderStr}}</span>
67
+ <span v-else style="color: #333;">{{search}}</span>
68
+ <!-- 闪烁光标 -->
69
+ <span v-if="isSearchActive" class="cursor-blink"></span>
70
+ <!-- 隐藏的输入框 -->
71
+ <input
72
+ v-if="props.showSearch && !column.componentProps?.options"
73
+ ref="inputRef"
74
+ v-model="search"
75
+ type="text"
76
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: text;"
77
+ @focus="handleInputFocus"
78
+ @blur="handleInputBlur"
79
+ @click.stop
80
+ />
81
+ </div>
46
82
  </div>
47
- <div v-else :class="ns.e('contentBox_placeholder')">{{placeholderStr}}</div>
48
83
  <ElIcon
49
84
  @mouseenter="isHoverIcon = true"
50
85
  @mouseleave="isHoverIcon = false"
@@ -59,11 +94,30 @@
59
94
  <ArrowDown v-else />
60
95
  </ElIcon>
61
96
  </div>
62
- <div v-else :class="ns.e('content')">
63
- <ElTooltip :disabled="!selected.label" :content="selected.label" placement="top" effect="light" append-to=".bwa-application">
64
- <div :class="[ns.e('contentBox'), ns.e('contentBox_label')]" v-if="selected.label">{{selected.label || placeholderStr}}</div>
65
- <div :class="[ns.e('contentBox'), ns.e('contentBox_placeholder')]" v-else>{{placeholderStr}}</div>
66
- </ElTooltip>
97
+ <!-- 单选模式 -->
98
+ <div v-else :class="ns.e('content')" @click="handleContentClick">
99
+ <div style="flex: 1; position: relative; cursor: text;">
100
+ <ElTooltip :disabled="!selected.label" :content="selected.label" placement="top" effect="light" append-to=".bwa-application">
101
+ <div v-if="selected.label" :class="[ns.e('contentBox'), ns.e('contentBox_label')]">{{selected.label || placeholderStr}}</div>
102
+ <div v-else style="display: flex; align-items: center; width: 100%;">
103
+ <span v-if="!isSearchActive && !search" :class="ns.e('contentBox_placeholder')">{{placeholderStr}}</span>
104
+ <span v-else style="color: #333;">{{search}}</span>
105
+ <!-- 闪烁光标 -->
106
+ <span v-if="isSearchActive" class="cursor-blink"></span>
107
+ </div>
108
+ </ElTooltip>
109
+ <!-- 隐藏的输入框 -->
110
+ <input
111
+ v-if="props.showSearch && !column.componentProps?.options"
112
+ ref="inputRef"
113
+ v-model="search"
114
+ type="text"
115
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: text;"
116
+ @focus="handleInputFocus"
117
+ @blur="handleInputBlur"
118
+ @click.stop
119
+ />
120
+ </div>
67
121
  <ElIcon
68
122
  :class="ns.be('option', 'selected')"
69
123
  >
@@ -72,19 +126,6 @@
72
126
  </ElIcon>
73
127
  </div>
74
128
  </template>
75
-
76
- <template #contentTop>
77
- <div :class="ns.e('contentTop')" v-if="showSearch && !column.componentProps?.options">
78
- <ElInput
79
- v-model="search"
80
- :class="ns.e('select')"
81
- :placeholder="searchPlaceholderStr"
82
- type="text"
83
- prefix-icon="Search"
84
- clearable
85
- />
86
- </div>
87
- </template>
88
129
  <slot>
89
130
  <BwaAdvanceOption
90
131
  v-for="item in data"
@@ -192,6 +233,8 @@ onMounted(() => {
192
233
  const ns = useNamespace('pctfilterpanel-item');
193
234
  const isShowPopper = ref(false)
194
235
  const isHoverIcon = ref(false)
236
+ const isSearchActive = ref(false)
237
+ const inputRef = ref(null)
195
238
 
196
239
  const attrs = useAttrs();
197
240
  const showTitle = computed(() => attrs.showTitle)
@@ -244,6 +287,44 @@ modelValue.value = currentModelValue.filter(item =>
244
287
  // 原有逻辑:切换下拉显隐
245
288
  isShowPopper.value = !isShowPopper.value;
246
289
  };
290
+
291
+ // 处理选择框点击事件
292
+ const handleContentClick = (event) => {
293
+ event.stopPropagation();
294
+ // 显示下拉菜单
295
+ isShowPopper.value = true;
296
+ // 如果支持搜索,聚焦输入框
297
+ if (props.showSearch && !column.value?.componentProps?.options) {
298
+ nextTick(() => {
299
+ if (inputRef.value) {
300
+ inputRef.value.focus();
301
+ isSearchActive.value = true;
302
+ }
303
+ });
304
+ }
305
+ };
306
+
307
+ // 处理输入框聚焦事件
308
+ const handleInputFocus = () => {
309
+ isSearchActive.value = true;
310
+ // 确保下拉菜单显示
311
+ isShowPopper.value = true;
312
+ };
313
+
314
+ // 处理输入框失焦事件
315
+ const handleInputBlur = (event) => {
316
+ // 检查是否点击了下拉菜单内部
317
+ const target = event.relatedTarget;
318
+ if (target && target.closest('.bwa-advance-select__popper')) {
319
+ // 点击了下拉菜单内部,保持搜索状态
320
+ return;
321
+ }
322
+ // 延迟处理,以便点击标签等操作能够正常执行
323
+ setTimeout(() => {
324
+ isSearchActive.value = false;
325
+ // 不清空搜索内容,保持用户输入
326
+ }, 200);
327
+ };
247
328
  const getData = async (query) => {
248
329
  loading.value = true
249
330
  const { itfInfo, searchAttr } = column.value.componentProps
@@ -278,8 +359,22 @@ const handleFieldSearch = (query) => {
278
359
  }
279
360
 
280
361
  const search = ref('')
362
+ let searchTimeout = null
281
363
  watch(() => search.value, val => {
282
364
  handleFieldSearch(val)
365
+ // 清除之前的定时器
366
+ if (searchTimeout) {
367
+ clearTimeout(searchTimeout)
368
+ }
369
+ // 设置新的定时器,0.5秒后唤起下拉菜单并获取数据
370
+ searchTimeout = setTimeout(() => {
371
+ if (val && props.showSearch && !column.value?.componentProps?.options) {
372
+ isShowPopper.value = true
373
+ if (column.value.componentProps) {
374
+ getData(val)
375
+ }
376
+ }
377
+ }, 500)
283
378
  })
284
379
 
285
380
  const modelValue = computed({