|
|
@@ -178,6 +178,11 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
type: String,
|
|
|
default: "",
|
|
|
},
|
|
|
+ // 新增:是否允许回车换行,默认false禁止换行 by xu 20251212
|
|
|
+ multiline: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
},
|
|
|
emits: ["update:modelValue", "input", "blur", "change"], // 允许更新 v-model 绑定的值
|
|
|
setup(props, { emit }) {
|
|
|
@@ -294,17 +299,33 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
};
|
|
|
|
|
|
// 检查是否应该显示浮动窗口(需要同时满足:有焦点 + 内容超出)
|
|
|
+ // 修复新增页面点击就出现floatdiv的问题 by xu 20251212
|
|
|
const checkShouldShowFloatingDiv = () => {
|
|
|
const textarea = inputRef.value;
|
|
|
if (!textarea) return false;
|
|
|
|
|
|
- // 判断内容是否超出:scrollHeight > clientHeight
|
|
|
- // scrollHeight 是内容的完整高度(包括不可见部分)
|
|
|
- // clientHeight 是可视区域高度(不包括滚动的部分)
|
|
|
- const isOverflow = textarea.scrollHeight > textarea.clientHeight;
|
|
|
+ // 首先检查是否有内容,没有内容时不显示floatdiv by xu 20251212
|
|
|
+ if (!inputValue.value || inputValue.value.toString().trim() === '') {
|
|
|
+ console.log('[floatdiv] 内容为空,不显示floatdiv');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断内容是否超出 by xu 20251212
|
|
|
+ // 同时检查横向和纵向溢出,任一方向溢出都应显示floatdiv
|
|
|
+ // 纵向溢出需要加容差值,避免padding/border导致的误判 by xu 20251212
|
|
|
+ const verticalTolerance = 5; // 容差值5px
|
|
|
+ const isHorizontalOverflow = textarea.scrollWidth > textarea.clientWidth;
|
|
|
+ const isVerticalOverflow = textarea.scrollHeight > textarea.clientHeight + verticalTolerance;
|
|
|
+ const isOverflow = isHorizontalOverflow || isVerticalOverflow;
|
|
|
+
|
|
|
+ console.log('[floatdiv] 溢出检测 - scrollWidth:', textarea.scrollWidth, 'clientWidth:', textarea.clientWidth, 'horizontalOverflow:', isHorizontalOverflow);
|
|
|
+ console.log('[floatdiv] 溢出检测 - scrollHeight:', textarea.scrollHeight, 'clientHeight:', textarea.clientHeight, 'tolerance:', verticalTolerance, 'verticalOverflow:', isVerticalOverflow);
|
|
|
+
|
|
|
+ const shouldShow = isFocused.value && isOverflow;
|
|
|
+ console.log('[floatdiv] 最终判断 - isFocused:', isFocused.value, 'isOverflow:', isOverflow, 'shouldShow:', shouldShow);
|
|
|
|
|
|
// 需要同时满足:有焦点 + 内容超出
|
|
|
- return isFocused.value && isOverflow;
|
|
|
+ return shouldShow;
|
|
|
};
|
|
|
|
|
|
// 定义事件处理函数
|
|
|
@@ -365,6 +386,14 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
// contentFloatingDiv.value = false
|
|
|
};
|
|
|
|
|
|
+ // 处理键盘按下事件,禁止回车换行 by xu 20251212
|
|
|
+ const onKeydown = (event) => {
|
|
|
+ // 如果不允许多行且按下的是回车键,阻止默认行为
|
|
|
+ if (!props.multiline && event.key === 'Enter') {
|
|
|
+ event.preventDefault();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
// 附件按钮点击处理(从 SsEditor 搬运)
|
|
|
const onAttachmentClick = (e) => {
|
|
|
e.preventDefault();
|
|
|
@@ -428,6 +457,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
onChange,
|
|
|
onMouseover,
|
|
|
onMouseleave,
|
|
|
+ onKeydown, // 新增:键盘事件处理 by xu 20251212
|
|
|
contentFloatingDiv,
|
|
|
floatingDivPosition,
|
|
|
getFloatingDivTop,
|
|
|
@@ -478,6 +508,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
onFocus: this.onFocus,
|
|
|
onBlur: this.onBlur,
|
|
|
onChange: this.onChange,
|
|
|
+ onKeydown: this.onKeydown, // 新增:禁止回车换行 by xu 20251212
|
|
|
placeholder: this.placeholder,
|
|
|
onMouseover: this.onMouseover, // 监听鼠标悬停
|
|
|
onMouseleave: this.onMouseleave, // 监听鼠标离开
|
|
|
@@ -532,6 +563,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
onInput: this.onInput,
|
|
|
onBlur: this.onBlur,
|
|
|
onFocus: this.onFocus,
|
|
|
+ onKeydown: this.onKeydown, // 新增:禁止回车换行 by xu 20251212
|
|
|
onMouseover: this.onMouseover, // 监听鼠标悬停
|
|
|
onMouseleave: this.onMouseleave, // 监听鼠标离开
|
|
|
autocomplete: "off",
|
|
|
@@ -758,6 +790,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
|
|
|
const filteredOptions = Vue.ref(props.opt);
|
|
|
const popupDirection = Vue.ref("bottom");
|
|
|
+ const popupMaxHeight = Vue.ref("none"); // popup最大高度,用于空间不足时限制高度并出滚动条 by xu 20251212
|
|
|
|
|
|
// const showRequired = Vue.computed(() => {
|
|
|
// const hasValidationRule = window.ssVm?.validations?.has(props.name);
|
|
|
@@ -958,15 +991,17 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 先清空选项 by xu 20251212
|
|
|
+ if (props.opt) {
|
|
|
+ props.opt.length = 0;
|
|
|
+ } else {
|
|
|
+ props.opt = [];
|
|
|
+ }
|
|
|
+
|
|
|
if (response.data.result) {
|
|
|
const keys = Object.keys(response.data.result);
|
|
|
// console.log("params:"+params+"@@response.data:"+JSON.stringify(response.data));
|
|
|
if (keys.length > 0) {
|
|
|
- if (props.opt)
|
|
|
- props.opt.length = 0; //通过修改数组的length属性,直接清空数组元素,内存会被自动释放。这是性能最优的方式
|
|
|
- else {
|
|
|
- props.opt = [];
|
|
|
- }
|
|
|
for (let k in response.data.result) {
|
|
|
props.opt.push({
|
|
|
label: response.data.result[k],
|
|
|
@@ -987,6 +1022,15 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
.toLowerCase()
|
|
|
.includes(inputText.value.toLowerCase())
|
|
|
);
|
|
|
+
|
|
|
+ // 可录入的objPicker,当搜索结果只有一项时,自动选中这一项 by xu 20251212
|
|
|
+ if (filteredOptions.value.length === 1) {
|
|
|
+ const autoSelectItem = filteredOptions.value[0];
|
|
|
+ console.log("[objp] 搜索结果只有一项,自动选中:", autoSelectItem);
|
|
|
+ doSelectItem(autoSelectItem);
|
|
|
+ return; // 自动选中后直接返回,不需要显示popup
|
|
|
+ }
|
|
|
+
|
|
|
filteredOptions.value.unshift({ label: "", value: "" });
|
|
|
|
|
|
// console.log('###做了过滤:'+inputText.value.toLowerCase()+';');
|
|
|
@@ -995,12 +1039,21 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
filteredOptions.value.unshift({ label: "", value: "" });
|
|
|
}
|
|
|
|
|
|
- if (!popupWinVisible.value) {
|
|
|
- popupWinVisible.value = true; // 确保下拉框在输入时打开
|
|
|
- }
|
|
|
-
|
|
|
console.log("props.opt11:" + JSON.stringify(props.opt));
|
|
|
+ } else {
|
|
|
+ // 没有数据时,清空过滤选项 by xu 20251212
|
|
|
+ filteredOptions.value = [];
|
|
|
+ console.log("[objp] 接口返回空数据");
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // result不存在时,清空过滤选项 by xu 20251212
|
|
|
+ filteredOptions.value = [];
|
|
|
+ console.log("[objp] 接口返回无result");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无论是否有数据,都显示popup by xu 20251212
|
|
|
+ if (!popupWinVisible.value) {
|
|
|
+ popupWinVisible.value = true;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -1009,7 +1062,8 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 计算弹出方向的方法
|
|
|
+ // 计算弹出方向和最大高度的方法 by xu 20251212
|
|
|
+ // 当空间不足时限制popup高度并显示滚动条
|
|
|
const calculatePopupDirection = () => {
|
|
|
// 1. 获取select容器元素
|
|
|
const selectEl = document
|
|
|
@@ -1021,20 +1075,39 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const selectRect = selectEl.getBoundingClientRect();
|
|
|
const viewportHeight = window.innerHeight;
|
|
|
|
|
|
- // 3. 简单判断:如果下方剩余空间小于300px就向上弹出
|
|
|
- const spaceBelow = viewportHeight - selectRect.bottom;
|
|
|
-
|
|
|
- // 调试信息
|
|
|
- // console.log('空间判断:', {
|
|
|
- // elementBottom: selectRect.bottom,
|
|
|
- // viewportHeight,
|
|
|
- // spaceBelow,
|
|
|
- // willPopUp: spaceBelow < 300,
|
|
|
- // popupDirection: popupDirection.value
|
|
|
- // });
|
|
|
-
|
|
|
- // 4. 设置方向
|
|
|
- popupDirection.value = spaceBelow < 300 ? "top" : "bottom";
|
|
|
+ // 3. 计算上下可用空间
|
|
|
+ const spaceBelow = viewportHeight - selectRect.bottom - 10; // 减10px留边距
|
|
|
+ const spaceAbove = selectRect.top - 10; // 减10px留边距
|
|
|
+
|
|
|
+ // 4. popup预估高度(假设每项36px,最多显示8项 + padding)
|
|
|
+ const estimatedPopupHeight = 300;
|
|
|
+ const minPopupHeight = 100; // 最小高度
|
|
|
+
|
|
|
+ console.log('[popup] 空间计算 - spaceAbove:', spaceAbove, 'spaceBelow:', spaceBelow, 'estimatedHeight:', estimatedPopupHeight);
|
|
|
+
|
|
|
+ // 5. 判断方向和最大高度 by xu 20251212
|
|
|
+ if (spaceBelow >= estimatedPopupHeight) {
|
|
|
+ // 下方空间足够,向下展开,不限制高度
|
|
|
+ popupDirection.value = "bottom";
|
|
|
+ popupMaxHeight.value = "none";
|
|
|
+ console.log('[popup] 向下展开,空间充足');
|
|
|
+ } else if (spaceAbove >= estimatedPopupHeight) {
|
|
|
+ // 上方空间足够,向上展开,不限制高度
|
|
|
+ popupDirection.value = "top";
|
|
|
+ popupMaxHeight.value = "none";
|
|
|
+ console.log('[popup] 向上展开,空间充足');
|
|
|
+ } else {
|
|
|
+ // 上下空间都不足,选择空间大的方向,并限制高度出滚动条
|
|
|
+ if (spaceBelow >= spaceAbove) {
|
|
|
+ popupDirection.value = "bottom";
|
|
|
+ popupMaxHeight.value = Math.max(spaceBelow, minPopupHeight) + "px";
|
|
|
+ console.log('[popup] 向下展开,空间不足,限制高度:', popupMaxHeight.value);
|
|
|
+ } else {
|
|
|
+ popupDirection.value = "top";
|
|
|
+ popupMaxHeight.value = Math.max(spaceAbove, minPopupHeight) + "px";
|
|
|
+ console.log('[popup] 向上展开,空间不足,限制高度:', popupMaxHeight.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
//点击下拉菜单的文本区域时,会触发的方法
|
|
|
@@ -1052,14 +1125,21 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
};
|
|
|
|
|
|
//点击下拉菜单的三角形时,会触发的方法
|
|
|
+ // 添加toggle逻辑,点击时切换显示/隐藏 by xu 20251212
|
|
|
const suffixClick = () => {
|
|
|
+ // 如果popup已显示,则关闭 by xu 20251212
|
|
|
+ if (popupWinVisible.value) {
|
|
|
+ hidePopup();
|
|
|
+ console.log("[objp] 点三角关闭popup");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
//可录入的objPicker,更新下拉菜单选项
|
|
|
updateOptionBYInputText("");
|
|
|
- // popupWinVisible.value = !popupWinVisible.value;
|
|
|
Vue.nextTick(() => {
|
|
|
calculatePopupDirection();
|
|
|
});
|
|
|
- console.log("点三角");
|
|
|
+ console.log("[objp] 点三角打开popup");
|
|
|
};
|
|
|
|
|
|
//可录入的objPicker,录入项变化时,会触发
|
|
|
@@ -1095,6 +1175,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
filteredOptions,
|
|
|
popupWinVisible,
|
|
|
popupDirection,
|
|
|
+ popupMaxHeight, // 添加popup最大高度 by xu 20251212
|
|
|
suffixClick,
|
|
|
togglePopup,
|
|
|
hidePopup,
|
|
|
@@ -1137,7 +1218,8 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
</div>
|
|
|
|
|
|
|
|
|
- <div v-show="popupWinVisible" class="popup-win" :class="popupDirection">
|
|
|
+ <!-- popup弹出层,添加maxHeight和overflowY支持空间不足时滚动 by xu 20251212 -->
|
|
|
+ <div v-show="popupWinVisible" class="popup-win" :class="popupDirection" :style="{ maxHeight: popupMaxHeight, overflowY: popupMaxHeight !== 'none' ? 'auto' : 'visible' }">
|
|
|
<div v-if="opt && opt.length && filteredOptions.length > 0" class="popup-content">
|
|
|
<div class="content-area">
|
|
|
<div v-for="(item, index) in filteredOptions" :key="index" @click="doSelectItem(item)" :class="{ active: item.value === selectItem.value }">
|
|
|
@@ -1369,6 +1451,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const isAutoEcho = Vue.ref(false); // 用于标记是否是自动回显
|
|
|
const upperValue = Vue.ref(""); //上级下拉菜单当前值,在初始化下拉菜单默认值时,和上级下拉菜单的值变化时,修改此upperValue变量
|
|
|
const popupDirection = Vue.ref("bottom");
|
|
|
+ const popupMaxHeight = Vue.ref("none"); // popup最大高度,用于空间不足时限制高度并出滚动条 by xu 20251212
|
|
|
|
|
|
//有隐藏字段的下拉菜单,加载菜单项并展开事件
|
|
|
// 被上级下拉菜单选中值后,触发本下拉菜单刷新菜单项并弹出显示
|
|
|
@@ -1853,6 +1936,8 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ // 计算弹出方向和最大高度的方法 by xu 20251212
|
|
|
+ // 当空间不足时限制popup高度并显示滚动条
|
|
|
const calculatePopupDirection = () => {
|
|
|
// 1. 获取select容器元素
|
|
|
const selectEl = document.querySelector(
|
|
|
@@ -1865,20 +1950,39 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const selectRect = selectEl.getBoundingClientRect();
|
|
|
const viewportHeight = window.innerHeight;
|
|
|
|
|
|
- // 3. 简单判断:如果下方剩余空间小于300px就向上弹出
|
|
|
- const spaceBelow = viewportHeight - selectRect.bottom;
|
|
|
-
|
|
|
- // 调试信息
|
|
|
- console.log("空间判断:", {
|
|
|
- elementBottom: selectRect.bottom,
|
|
|
- viewportHeight,
|
|
|
- spaceBelow,
|
|
|
- willPopUp: spaceBelow < 300,
|
|
|
- popupDirection: popupDirection.value,
|
|
|
- });
|
|
|
-
|
|
|
- // 4. 设置方向
|
|
|
- popupDirection.value = spaceBelow < 300 ? "top" : "bottom";
|
|
|
+ // 3. 计算上下可用空间 by xu 20251212
|
|
|
+ const spaceBelow = viewportHeight - selectRect.bottom - 10; // 减10px留边距
|
|
|
+ const spaceAbove = selectRect.top - 10; // 减10px留边距
|
|
|
+
|
|
|
+ // 4. popup预估高度(假设每项36px,最多显示8项 + padding)
|
|
|
+ const estimatedPopupHeight = 300;
|
|
|
+ const minPopupHeight = 100; // 最小高度
|
|
|
+
|
|
|
+ console.log('[popup] 空间计算 - spaceAbove:', spaceAbove, 'spaceBelow:', spaceBelow, 'estimatedHeight:', estimatedPopupHeight);
|
|
|
+
|
|
|
+ // 5. 判断方向和最大高度 by xu 20251212
|
|
|
+ if (spaceBelow >= estimatedPopupHeight) {
|
|
|
+ // 下方空间足够,向下展开,不限制高度
|
|
|
+ popupDirection.value = "bottom";
|
|
|
+ popupMaxHeight.value = "none";
|
|
|
+ console.log('[popup] 向下展开,空间充足');
|
|
|
+ } else if (spaceAbove >= estimatedPopupHeight) {
|
|
|
+ // 上方空间足够,向上展开,不限制高度
|
|
|
+ popupDirection.value = "top";
|
|
|
+ popupMaxHeight.value = "none";
|
|
|
+ console.log('[popup] 向上展开,空间充足');
|
|
|
+ } else {
|
|
|
+ // 上下空间都不足,选择空间大的方向,并限制高度出滚动条
|
|
|
+ if (spaceBelow >= spaceAbove) {
|
|
|
+ popupDirection.value = "bottom";
|
|
|
+ popupMaxHeight.value = Math.max(spaceBelow, minPopupHeight) + "px";
|
|
|
+ console.log('[popup] 向下展开,空间不足,限制高度:', popupMaxHeight.value);
|
|
|
+ } else {
|
|
|
+ popupDirection.value = "top";
|
|
|
+ popupMaxHeight.value = Math.max(spaceAbove, minPopupHeight) + "px";
|
|
|
+ console.log('[popup] 向上展开,空间不足,限制高度:', popupMaxHeight.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
//级联菜单点击事件
|
|
|
const togglePopup = () => {
|
|
|
@@ -1980,12 +2084,19 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- if (!popupWinVisible.value) {
|
|
|
- popupWinVisible.value = true; // 确保下拉框打开
|
|
|
- }
|
|
|
-
|
|
|
console.log("props.opt11:" + JSON.stringify(props.opt));
|
|
|
+ } else {
|
|
|
+ // 没有数据时打印日志 by xu 20251212
|
|
|
+ console.log("[ccp mode1] 接口返回空数据");
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // result不存在时打印日志 by xu 20251212
|
|
|
+ console.log("[ccp mode1] 接口返回无result");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无论是否有数据,都显示popup by xu 20251212
|
|
|
+ if (!popupWinVisible.value) {
|
|
|
+ popupWinVisible.value = true;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -2070,12 +2181,19 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- if (!popupWinVisible.value) {
|
|
|
- popupWinVisible.value = true; // 确保下拉框打开
|
|
|
- }
|
|
|
-
|
|
|
console.log("props.opt11:" + JSON.stringify(props.opt));
|
|
|
+ } else {
|
|
|
+ // 没有数据时打印日志 by xu 20251212
|
|
|
+ console.log("[ccp mode2] 接口返回空数据");
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // result不存在时打印日志 by xu 20251212
|
|
|
+ console.log("[ccp mode2] 接口返回无result");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无论是否有数据,都显示popup by xu 20251212
|
|
|
+ if (!popupWinVisible.value) {
|
|
|
+ popupWinVisible.value = true;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -2172,6 +2290,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
selectItem,
|
|
|
popupWinVisible,
|
|
|
popupDirection,
|
|
|
+ popupMaxHeight, // 添加popup最大高度 by xu 20251212
|
|
|
togglePopup,
|
|
|
hidePopup,
|
|
|
doSelectItem,
|
|
|
@@ -2199,7 +2318,8 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div v-show="popupWinVisible" class="popup-win " :class="popupDirection">
|
|
|
+ <!-- popup弹出层,添加maxHeight和overflowY支持空间不足时滚动 by xu 20251212 -->
|
|
|
+ <div v-show="popupWinVisible" class="popup-win " :class="popupDirection" :style="{ maxHeight: popupMaxHeight, overflowY: popupMaxHeight !== 'none' ? 'auto' : 'visible' }">
|
|
|
<div v-if="opt && opt.length > 0" class="popup-content">
|
|
|
<div class="content-area">
|
|
|
<div
|
|
|
@@ -2363,10 +2483,16 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
},
|
|
|
};
|
|
|
// ss-icon 图标
|
|
|
+ // v3.0 增加 class 属性分支:有 class 走新逻辑,否则走 v1.0 逻辑 by xu 20251212
|
|
|
+ // v3.0 用法: <ss-icon class="icon-obj-ry menu-icon" />
|
|
|
+ // v1.0 用法: <ss-icon name="setting" size="20px" />
|
|
|
const SsIcon = {
|
|
|
name: "SsIcon",
|
|
|
props: {
|
|
|
- name: { type: String, required: true },
|
|
|
+ // v3.0: class 属性(图标类 + 组类)
|
|
|
+ class: { type: String },
|
|
|
+ // v1.0: 以下为旧属性
|
|
|
+ name: { type: String },
|
|
|
size: { type: [Number, String], default: 16 },
|
|
|
unit: { type: String, default: "px" },
|
|
|
color: String,
|
|
|
@@ -2380,6 +2506,12 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
},
|
|
|
emits: ["update:modelValue", "input", "blur", "change"],
|
|
|
setup(props, { emit }) {
|
|
|
+ // v3.0 分支:有 class 属性时直接渲染 by xu 20251212
|
|
|
+ if (props.class) {
|
|
|
+ return () => h("i", { class: props.class });
|
|
|
+ }
|
|
|
+
|
|
|
+ // v1.0 分支:原有逻辑
|
|
|
const useIconType = computed(() => {
|
|
|
return [ssIcon, commonIcon].find(
|
|
|
(iconConfig) => iconConfig.name === props.type
|
|
|
@@ -2505,6 +2637,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
});
|
|
|
},
|
|
|
};
|
|
|
+
|
|
|
// 全局菜单图标组件
|
|
|
const SsGolbalMenuIcon = {
|
|
|
name: "SsGolbalMenuIcon",
|
|
|
@@ -2634,6 +2767,11 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
},
|
|
|
+ // 是否允许一项都不选,默认true允许 by xu 20251212
|
|
|
+ null: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true,
|
|
|
+ },
|
|
|
},
|
|
|
emits: ["update:modelValue"], // 允许更新 v-model 绑定的值
|
|
|
setup(props, { emit }) {
|
|
|
@@ -2667,11 +2805,25 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
if (index === -1) {
|
|
|
checkedValue.value = [...checkedValue.value, value];
|
|
|
} else {
|
|
|
- checkedValue.value = checkedValue.value.filter((v) => v !== value);
|
|
|
+ // 取消选中当前项
|
|
|
+ const newValue = checkedValue.value.filter((v) => v !== value);
|
|
|
+ // 如果不允许为空且取消后为空,则阻止取消操作 by xu 20251212
|
|
|
+ if (!props.null && newValue.length === 0) {
|
|
|
+ return; // 阻止取消最后一项
|
|
|
+ }
|
|
|
+ checkedValue.value = newValue;
|
|
|
}
|
|
|
} else {
|
|
|
// 单选模式
|
|
|
- checkedValue.value = value;
|
|
|
+ // 如果点击的是当前已选中的项,判断是否允许取消 by xu 20251212
|
|
|
+ if (checkedValue.value === value) {
|
|
|
+ if (!props.null) {
|
|
|
+ return; // 不允许为空时,阻止取消
|
|
|
+ }
|
|
|
+ checkedValue.value = ""; // 允许为空时,取消选中
|
|
|
+ } else {
|
|
|
+ checkedValue.value = value;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
emit("update:modelValue", checkedValue.value);
|
|
|
@@ -3634,13 +3786,13 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
},
|
|
|
};
|
|
|
// ss-bottom-button 底部按钮
|
|
|
-
|
|
|
+ // 修改支持更多按钮 by xu 20251211
|
|
|
const SsBottomButton = {
|
|
|
name: "SsBottomButton",
|
|
|
props: {
|
|
|
text: {
|
|
|
type: String,
|
|
|
- required: false,// 修改支持更多按钮 by xu 20251211
|
|
|
+ required: false,
|
|
|
},
|
|
|
type: {
|
|
|
type: String,
|
|
|
@@ -3757,7 +3909,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
class: props.iconClass,
|
|
|
}),
|
|
|
]),
|
|
|
- h("span", null, buttonText.value),// 修改支持更多按钮 by xu 20251211
|
|
|
+ h("span", null, buttonText.value),
|
|
|
]
|
|
|
),
|
|
|
// 渲染下拉菜单
|