@skyfox2000/webui 1.3.7 → 1.3.9

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": "@skyfox2000/webui",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "后台前端通用组件定义",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -19,18 +19,14 @@ const attrs = useAttrs(); // 手动获取 $attrs
19
19
  <Popover placement="topRight">
20
20
  <template #content>
21
21
  <slot>
22
- <div class="text-[14px]" :style="{ maxWidth }">
22
+ <div class="text-[14px]" :class="[maxWidth]">
23
23
  {{ text }}
24
24
  </div>
25
25
  </slot>
26
26
  </template>
27
27
  <span class="ml-2">
28
- <ToolIcon
29
- icon="icon-question-circle"
30
- class="text-[#888]"
31
- :class="[size ? 'w-' + size + ' h-' + size : 'w-5 h-5']"
32
- v-bind="attrs"
33
- />
28
+ <ToolIcon icon="icon-question-circle" class="text-[#888]"
29
+ :class="[size ? 'w-' + size + ' h-' + size : 'w-5 h-5']" v-bind="attrs" />
34
30
  </span>
35
31
  </Popover>
36
32
  </template>
@@ -412,13 +412,10 @@ const dialogSave = async (uploadFile: UploadFile) => {
412
412
  });
413
413
 
414
414
  if (result?.status === ResStatus.SUCCESS) {
415
- message.success('数据保存成功!');
416
415
  if (excelCtrl.afterSave) {
417
416
  excelCtrl.afterSave();
418
417
  }
419
418
  excelCtrl.visible.value = false;
420
- } else {
421
- message.error('保存失败:' + (result?.msg || '未知错误'));
422
419
  }
423
420
  } catch (error) {
424
421
  console.error('保存错误:', error);
@@ -60,6 +60,7 @@ const getRule = (rule: Array<string>, ruleObj: Record<string, any> | undefined):
60
60
  if (rule.length === 1) {
61
61
  return ruleObj[key];
62
62
  }
63
+ if (!ruleObj[key]) return undefined;
63
64
  return getRule(rest, ruleObj[key].fields as Record<string, any>);
64
65
  };
65
66
  /**
@@ -92,18 +93,13 @@ const required = computed(() => {
92
93
  </script>
93
94
  <template>
94
95
  <div :class="['relative', bottomMargin ? bottomMargin : 'mb-1']">
95
- <FormItem
96
- v-if="visible"
97
- :required="required"
98
- class="relative"
99
- :class="[nextLine ? 'mb-0' : rule ? '' : 'mb-3']"
100
- v-bind="attrs"
101
- >
96
+ <FormItem v-if="visible" :required="required" class="relative" :class="[nextLine ? 'mb-0' : rule ? '' : 'mb-3']"
97
+ v-bind="attrs">
102
98
  <template #label>
103
99
  <span :class="[errInfo.errClass ? 'text-[#ff4d4f]' : '', 'w-full']"> {{ label }}</span>
104
100
  </template>
105
- <div class="flex items-center" :class="width ? width : 'w-full'" v-if="!nextLine">
106
- <div class="flex-grow">
101
+ <div class="flex items-center" :class="width ? width : 'w-full'">
102
+ <div class="flex-grow" v-if="!nextLine">
107
103
  <slot></slot>
108
104
  </div>
109
105
  <div class="w-8 mt-[-2px]">
@@ -113,18 +109,12 @@ const required = computed(() => {
113
109
  </div>
114
110
  </div>
115
111
  </FormItem>
116
- <div
117
- v-if="nextLine"
118
- class="w-[95%] flex items-center relative"
119
- :class="[nextLine ? (rule ? 'mb-7' : 'mb-3') : '']"
120
- >
112
+ <div v-if="nextLine" class="w-[95%] flex items-center relative"
113
+ :class="[nextLine ? (rule ? 'mb-7' : 'mb-3') : '']">
121
114
  <slot></slot>
122
115
  </div>
123
- <span
124
- :style="{ left: nextLine ? '2px' : labelWidth }"
125
- class="absolute bottom-[3px] text-[12px] text-[#ff4d4fcc]"
126
- v-if="errInfo.errClass"
127
- >
116
+ <span :style="{ left: nextLine ? '2px' : labelWidth }" class="absolute bottom-[3px] text-[12px] text-[#ff4d4fcc]"
117
+ v-if="errInfo.errClass">
128
118
  {{ errInfo.msg }}
129
119
  </span>
130
120
  </div>
@@ -58,7 +58,7 @@ optionCtrl.fieldMap = {
58
58
  };
59
59
 
60
60
  /// 避免类型错误
61
- const innerValue = ref<SelectValue | undefined>(optionCtrl?.selected.value || undefined);
61
+ const innerValue = ref<SelectValue | undefined>(undefined);
62
62
 
63
63
  watch(
64
64
  () => props.value,
@@ -137,15 +137,8 @@ onUnmounted(() => {
137
137
 
138
138
  <template>
139
139
  <div>
140
- <AutoComplete
141
- v-model:value="innerValue"
142
- :class="['w-full', errInfo?.errClass]"
143
- :options="selectOptions"
144
- @search="onSearch"
145
- @select="onSelected"
146
- v-bind="attrs"
147
- :allow-clear="false"
148
- >
140
+ <AutoComplete v-model:value="innerValue" :class="['w-full', errInfo?.errClass]" :options="selectOptions"
141
+ @search="onSearch" @select="onSelected" v-bind="attrs" :allow-clear="false">
149
142
  <Input allow-clear :placeholder="'请输入并选择' + labelText" />
150
143
  <template #option="{ label }">
151
144
  {{ label }}
@@ -70,11 +70,42 @@ const innerValue = ref<string | number | string[] | number[] | undefined>(option
70
70
  const emit = defineEmits(['change', 'update:value', 'update:label', 'update:labels']);
71
71
  inputFactory.inputEmit = emit;
72
72
 
73
+ const onChanged = (value: any) => {
74
+ const selectedOptions = onOptionChanged(optionCtrl, props, value as SelectValue);
75
+ const labels: string[] = getSelectedLabels(selectedOptions);
76
+
77
+ innerValue.value = value;
78
+ emit('update:labels', labels);
79
+ emit('update:label', labels.join(";"));
80
+ emit('change', value);
81
+
82
+ if (errInfo?.value.errClass && editorCtrl) {
83
+ /// 重新开始验证
84
+ formValidate(editorCtrl);
85
+ }
86
+ };
73
87
  /**
74
88
  * 实际的选择项
75
89
  */
76
90
  const selectOptions = ref<OptionItemProps[]>(optionCtrl?.options.value || []);
77
91
 
92
+ const updateInnerValue = (newVal: OptionItemProps[]) => {
93
+ if (newVal.length > 0 && isEmpty(props.value) && !!props.selectFirst) {
94
+ for (let i = 0; i < newVal.length; i++) {
95
+ const item = newVal[i];
96
+
97
+ if (item.disabled === undefined || item.disabled === false) {
98
+ innerValue.value = item.value;
99
+ break;
100
+ }
101
+ }
102
+ } else if (newVal.length > 0) {
103
+ // 当选项加载完成后,设置实际的 value 值
104
+ innerValue.value = props.value === null ? undefined : props.value;
105
+ }
106
+ if (newVal.length > 0 && innerValue.value !== undefined) onChanged(innerValue.value);
107
+ };
108
+
78
109
  // 监听 optionCtrl.options 的变化,确保 selectOptions 能响应式更新
79
110
  if (optionCtrl) {
80
111
  watch(
@@ -86,31 +117,10 @@ if (optionCtrl) {
86
117
  );
87
118
  }
88
119
 
89
- const onChanged = (value: any) => {
90
- const selectedOptions = onOptionChanged(optionCtrl, props, value as SelectValue);
91
- const labels: string[] = getSelectedLabels(selectedOptions);
92
-
93
- innerValue.value = value;
94
- emit('update:labels', labels);
95
- emit('update:label', labels.join(";"));
96
- emit('change', value);
97
-
98
- if (errInfo?.value.errClass && editorCtrl) {
99
- /// 重新开始验证
100
- formValidate(editorCtrl);
101
- }
102
- };
103
-
104
120
  watch(
105
121
  () => selectOptions.value,
106
122
  (newVal) => {
107
- if (newVal.length && isEmpty(props.value) && props.selectFirst) {
108
- innerValue.value = newVal[0].value;
109
- } else {
110
- // 当选项加载完成后,设置实际的 value 值
111
- innerValue.value = props.value === null ? undefined : props.value;
112
- }
113
- if (newVal.length > 0 && innerValue.value) onChanged(innerValue.value);
123
+ updateInnerValue(newVal);
114
124
  },
115
125
  );
116
126
 
@@ -136,6 +146,7 @@ watch(
136
146
  },
137
147
  );
138
148
 
149
+
139
150
  onMounted(() => {
140
151
  if (url.value && !url.value.fieldMap) {
141
152
  url.value.fieldMap = {
@@ -147,7 +158,19 @@ onMounted(() => {
147
158
  if (props.dataKey) {
148
159
  const options = JSON.parse(JSON.stringify(OPTIONS.getOptions(props.dataKey)));
149
160
  selectOptions.value = options;
150
- } else if (optionCtrl) loadOption(optionCtrl.autoload, optionCtrl, props);
161
+ updateInnerValue(options);
162
+ } else if (optionCtrl) {
163
+ // 检查是否已经有预加载的选项
164
+ const preloadedOptions = optionCtrl.options.value || [];
165
+ if (preloadedOptions.length > 0) {
166
+ // 选项已经加载完成,直接更新selectOptions并执行updateInnerValue
167
+ selectOptions.value = preloadedOptions;
168
+ updateInnerValue(preloadedOptions);
169
+ } else {
170
+ // 选项尚未加载,执行加载操作
171
+ loadOption(optionCtrl.autoload, optionCtrl, props);
172
+ }
173
+ }
151
174
  });
152
175
 
153
176
  onUnmounted(() => {
@@ -30,7 +30,7 @@ const props = defineProps({
30
30
  });
31
31
 
32
32
  // 如果初始value为undefined,自动设置undefValue为true
33
- const undefValue = props.value === undefined ? true : props.undefValue;
33
+ const undefVal = props.value === undefined ? true : props.undefValue;
34
34
 
35
35
  const treeCtrl = props.treeCtrl;
36
36
 
@@ -54,6 +54,12 @@ watch(
54
54
  },
55
55
  { immediate: true },
56
56
  );
57
+ watch(
58
+ () => currentValue.value,
59
+ (newVal) => {
60
+ emit('update:value', newVal);
61
+ },
62
+ );
57
63
 
58
64
  // 监听树数据变化
59
65
  watch(
@@ -71,10 +77,14 @@ const handleChange = (value: SelectValue) => {
71
77
  if (props.multiple) {
72
78
  currentValue.value = value ?? [];
73
79
  } else {
74
- currentValue.value = value ?? undefValue ? undefined : null;
80
+ // 修复原始代码中的逻辑错误
81
+ if (value === undefined || value === null) {
82
+ currentValue.value = undefVal ? undefined : null;
83
+ } else {
84
+ currentValue.value = value;
85
+ }
75
86
  }
76
87
  emit('change', currentValue.value);
77
- emit('update:value', currentValue.value);
78
88
  };
79
89
 
80
90
  // 组件挂载时加载数据
@@ -94,8 +104,9 @@ onMounted(() => {
94
104
  queryTree(props.treeCtrl);
95
105
  }
96
106
  });
107
+
97
108
  const onClear = () => {
98
- currentValue.value = undefValue ? undefined : null;
109
+ currentValue.value = undefVal ? undefined : null;
99
110
  };
100
111
  </script>
101
112
 
@@ -109,4 +120,4 @@ const onClear = () => {
109
120
  border-color: #ef444480;
110
121
  box-shadow: 0 0 3px 0 #ff4d4f;
111
122
  }
112
- </style>
123
+ </style>