|
|
@@ -7,7 +7,23 @@
|
|
|
<div style="font-size: 16px; font-weight: 500;">{{ title }}</div>
|
|
|
<van-icon name="cross" @click="close" />
|
|
|
</div>
|
|
|
- <van-search v-model="searchKey" :placeholder="searchPlaceholder" @search="onSearch" @input="onInputChange" />
|
|
|
+ <div style="padding: 8px 12px;">
|
|
|
+ <div style="position: relative;">
|
|
|
+ <input
|
|
|
+ v-model="searchKey"
|
|
|
+ type="text"
|
|
|
+ :placeholder="searchPlaceholder"
|
|
|
+ style="width: 100%; padding: 8px 12px; border: 1px solid #ebedf0; border-radius: 4px; font-size: 14px;"
|
|
|
+ readonly
|
|
|
+ @click="showKeyboard = true"
|
|
|
+ />
|
|
|
+ <van-icon
|
|
|
+ name="search"
|
|
|
+ style="position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: #969799;"
|
|
|
+ @click="onSearch"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<div style="flex: 1; overflow-y: auto;">
|
|
|
<van-radio-group v-model="selectedId">
|
|
|
<van-cell-group>
|
|
|
@@ -28,6 +44,122 @@
|
|
|
<van-button type="primary" block @click="confirm">确认</van-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- 自定义键盘 -->
|
|
|
+ <van-popup v-model:show="showKeyboard" position="top" style="height: 300px;">
|
|
|
+ <div style="display: flex; flex-direction: column; height: 100%;">
|
|
|
+ <div style="display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; border-bottom: 1px solid #ebedf0;">
|
|
|
+ <div style="font-size: 16px; font-weight: 500;">输入货位编号</div>
|
|
|
+ <van-icon name="cross" @click="showKeyboard = false" />
|
|
|
+ </div>
|
|
|
+ <div style="flex: 1; display: flex; flex-direction: column; padding: 10px; overflow: hidden;">
|
|
|
+ <!-- 字母键盘 -->
|
|
|
+ <!-- 标准手机键盘布局 -->
|
|
|
+ <div v-if="keyboardMode === 'letters'" style="display: flex; flex-direction: column; gap: 6px; height: 100%;">
|
|
|
+ <!-- 第1行:10个字母 -->
|
|
|
+ <div style="display: flex; gap: 2px; flex: 1;">
|
|
|
+ <button
|
|
|
+ v-for="char in letters[0]"
|
|
|
+ :key="char"
|
|
|
+ style="flex: 1; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #fff; font-size: 14px; text-align: center; min-width: 0;"
|
|
|
+ @click="addChar(char)"
|
|
|
+ >
|
|
|
+ {{ char }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 第2行:9个字母 -->
|
|
|
+ <div style="display: flex; gap: 2px; flex: 1; padding-left: 5%; padding-right: 5%;">
|
|
|
+ <button
|
|
|
+ v-for="char in letters[1]"
|
|
|
+ :key="char"
|
|
|
+ style="flex: 1; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #fff; font-size: 14px; text-align: center; min-width: 0;"
|
|
|
+ @click="addChar(char)"
|
|
|
+ >
|
|
|
+ {{ char }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 第3行:7个字母 + 删除键 -->
|
|
|
+ <div style="display: flex; gap: 2px; flex: 1;">
|
|
|
+ <button
|
|
|
+ v-for="char in letters[2]"
|
|
|
+ :key="char"
|
|
|
+ style="flex: 1; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #fff; font-size: 14px; text-align: center; min-width: 0;"
|
|
|
+ @click="addChar(char)"
|
|
|
+ >
|
|
|
+ {{ char }}
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ style="flex: 2; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #f5f5f5; font-size: 12px; text-align: center;"
|
|
|
+ @click="deleteChar"
|
|
|
+ >
|
|
|
+ 删除
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 功能键区 -->
|
|
|
+ <div style="display: flex; gap: 2px; flex: 1;">
|
|
|
+ <button
|
|
|
+ style="flex: 2; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #f5f5f5; font-size: 12px;"
|
|
|
+ @click="clearInput"
|
|
|
+ >
|
|
|
+ 清空
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ style="flex: 3; padding: 8px 4px; border: 1px solid #1989fa; border-radius: 4px; background: #1989fa; color: #fff; font-size: 12px;"
|
|
|
+ @click="keyboardMode = 'numbers'"
|
|
|
+ >
|
|
|
+ 123
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ style="flex: 3; padding: 8px 4px; border: 1px solid #1989fa; border-radius: 4px; background: #1989fa; color: #fff; font-size: 12px;"
|
|
|
+ @click="confirmInput"
|
|
|
+ >
|
|
|
+ 确认
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 数字键盘 -->
|
|
|
+ <div v-else style="display: flex; gap: 6px; height: 100%;">
|
|
|
+ <!-- 数字区域 - 添加 flex: 1 确保与右侧等高 -->
|
|
|
+ <div style="flex: 4 1 0; display: flex; flex-direction: column; gap: 6px;">
|
|
|
+ <!-- 每行数字也需要填满高度 -->
|
|
|
+ <div
|
|
|
+ v-for="(row, rowIndex) in numbers" :key="rowIndex"
|
|
|
+ style="display: flex; gap: 4px; flex: 1;"
|
|
|
+ >
|
|
|
+ <button
|
|
|
+ v-for="num in row"
|
|
|
+ :key="num"
|
|
|
+ style="flex: 1; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #fff; font-size: 14px; text-align: center;"
|
|
|
+ @click="addChar(num)"
|
|
|
+ >
|
|
|
+ {{ num }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 功能键区域 -->
|
|
|
+ <div style="flex: 1; display: flex; flex-direction: column; gap: 6px;">
|
|
|
+ <button
|
|
|
+ v-for="(btn, index) in ['删除', '清空', 'ABC', '确认']"
|
|
|
+ :key="index"
|
|
|
+ style="flex: 1; padding: 8px 4px; border: 1px solid #ebedf0; border-radius: 4px; background: #fff; font-size: 12px; text-align: center;"
|
|
|
+ :style="{
|
|
|
+ backgroundColor: index >= 2 ? '#1989fa' : '#f5f5f5',
|
|
|
+ borderColor: index >= 2 ? '#1989fa' : '#ebedf0',
|
|
|
+ color: index >= 2 ? '#fff' : '#333'
|
|
|
+ }"
|
|
|
+ @click="index === 0 ? deleteChar() : index === 1 ? clearInput() : index === 2 ? keyboardMode = 'letters' : confirmInput()"
|
|
|
+ >
|
|
|
+ {{ btn }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
</van-popup>
|
|
|
</template>
|
|
|
|
|
|
@@ -97,6 +229,21 @@ const selectedItem = ref(null);
|
|
|
const defaultApplied = ref(false);
|
|
|
const route = useRoute();
|
|
|
const warehouseId = ref(route.query.warehouseId || '');
|
|
|
+const showKeyboard = ref(false);
|
|
|
+
|
|
|
+// 自定义键盘数据
|
|
|
+const keyboardMode = ref('letters'); // 'letters' 或 'numbers'
|
|
|
+const letters = ref([
|
|
|
+ ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
|
|
|
+ ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
|
|
|
+ ['Z', 'X', 'C', 'V', 'B', 'N', 'M'],
|
|
|
+]);
|
|
|
+const numbers = ref([
|
|
|
+ ['1', '2', '3'],
|
|
|
+ ['4', '5', '6'],
|
|
|
+ ['7', '8', '9'],
|
|
|
+ ['-', '0'],
|
|
|
+]);
|
|
|
|
|
|
// 计算属性
|
|
|
const title = computed(() => {
|
|
|
@@ -266,6 +413,7 @@ const confirm = () => {
|
|
|
// 关闭弹窗
|
|
|
const close = () => {
|
|
|
visible.value = false;
|
|
|
+ showKeyboard.value = false;
|
|
|
emit('close');
|
|
|
};
|
|
|
|
|
|
@@ -275,6 +423,36 @@ const clearSelected = () => {
|
|
|
selectedItem.value = null;
|
|
|
};
|
|
|
|
|
|
+// 自定义键盘方法
|
|
|
+let keyboardTimer = null;
|
|
|
+
|
|
|
+const addChar = char => {
|
|
|
+ searchKey.value += char;
|
|
|
+ // 添加防抖自动查询
|
|
|
+ clearTimeout(keyboardTimer);
|
|
|
+ keyboardTimer = setTimeout(() => {
|
|
|
+ onSearch();
|
|
|
+ }, 500);
|
|
|
+};
|
|
|
+
|
|
|
+const deleteChar = () => {
|
|
|
+ searchKey.value = searchKey.value.slice(0, -1);
|
|
|
+ // 添加防抖自动查询
|
|
|
+ clearTimeout(keyboardTimer);
|
|
|
+ keyboardTimer = setTimeout(() => {
|
|
|
+ onSearch();
|
|
|
+ }, 500);
|
|
|
+};
|
|
|
+
|
|
|
+const clearInput = () => {
|
|
|
+ searchKey.value = '';
|
|
|
+};
|
|
|
+
|
|
|
+const confirmInput = () => {
|
|
|
+ showKeyboard.value = false;
|
|
|
+ onSearch();
|
|
|
+};
|
|
|
+
|
|
|
// 组件挂载时:当 type 为 stockInPhoto 时,直接加载并应用默认逻辑
|
|
|
onMounted(() => {
|
|
|
if (props.type === 'stockInPhoto') {
|
|
|
@@ -285,6 +463,7 @@ onMounted(() => {
|
|
|
// 在组件卸载时清除定时器(避免内存泄漏)
|
|
|
onUnmounted(() => {
|
|
|
clearTimeout(timer);
|
|
|
+ clearTimeout(keyboardTimer);
|
|
|
});
|
|
|
|
|
|
defineExpose({
|