Files
klp-oa/klp-ui/src/components/MemoInput/index.vue
王文昊 eef375cc2a feat(wms/move): 新增调拨单记忆输入并优化权限与功能
1. 新增MemoInput组件的maxSuggestions配置,限制下拉提示条数
2. 为调拨单相关页面替换输入框为带记忆功能的MemoInput
3. 移除冗余的regrade_quality_type字典依赖
4. 给删除按钮增加glc角色权限控制
5. 简化删除操作的Promise链式调用逻辑
6. 新增调拨单号、名称的枚举存储key
2026-07-08 10:34:10 +08:00

199 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-autocomplete class="inline-input" v-model="inputValue" :fetch-suggestions="querySearch" :placeholder="placeholder"
:trigger-on-focus="triggerMode === 'focus'" @select="handleSelect" @change="handleInputChange"
clearable :disabled="disabled"></el-autocomplete>
</template>
<script>
import { MemoInputStorageKey } from '@/utils/enum';
export default {
name: 'LocalStorageAutocomplete',
props: {
// localStorage 存储键名,必填
value: {
type: String,
default: ''
},
storageKey: {
type: String,
required: true,
validator: (value) => {
// 校验storageKey是否在MemoInputStorageKey中
if (!MemoInputStorageKey[value]) {
throw new Error(`storageKey ${value} is not valid`);
}
return value.trim() !== ''
} // 校验非空
},
// 输入框占位符,默认“请输入内容”
placeholder: {
type: String,
default: '请输入内容'
},
// // 当localstorage中不存在缓存时自动创建一个数组作为默认值
// autoCreateDefault: {
// type: Array,
// default: () => []
// },
// 最大缓存数量默认100条
maxCacheCount: {
type: Number,
default: 100,
validator: (value) => value > 0 // 校验正整数
},
// 匹配规则start-前缀匹配contain-包含匹配,默认前缀匹配
matchRule: {
type: String,
default: 'start',
validator: (value) => ['start', 'contain'].includes(value)
},
// 触发模式focus-激活即列出input-输入后匹配默认focus
triggerMode: {
type: String,
default: 'focus',
validator: (value) => ['focus', 'input'].includes(value)
},
// 是否禁用输入框默认false
disabled: {
type: Boolean,
default: false
},
// 下拉最多展示条数默认6条
maxSuggestions: {
type: Number,
default: 6,
validator: (value) => value > 0
}
},
data() {
return {
inputValue: '',
// 缓存历史列表(格式:[{value: 'xxx'}, ...]
historyList: []
};
},
computed: {
innerKey() {
if (!this.storageKey) {
throw new Error('storageKey is required');
}
return 'mono-' + this.storageKey;
}
},
watch: {
value: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.inputValue = newVal;
}
},
immediate: true
}
},
mounted() {
// 初始化时从localStorage读取历史记录
this.initHistoryList();
},
methods: {
/**
* 从localStorage初始化历史列表
*/
initHistoryList() {
const storedData = localStorage.getItem(this.innerKey);
this.historyList = storedData ? JSON.parse(storedData) : [];
},
/**
* 搜索查询方法Element UI autocomplete 要求的格式)
* @param {string} queryString - 输入的查询字符串
* @param {function} cb - 回调函数,返回匹配结果
*/
querySearch(queryString, cb) {
let results = [...this.historyList]; // 深拷贝避免修改原数组
// 根据查询字符串过滤结果
if (queryString) {
const lowerQuery = queryString.toLowerCase();
results = results.filter(item => {
const lowerValue = item.value.toLowerCase();
// 前缀匹配或包含匹配
return this.matchRule === 'start'
? lowerValue.indexOf(lowerQuery) === 0
: lowerValue.includes(lowerQuery);
});
}
cb(results.slice(0, this.maxSuggestions)); // 回调返回匹配结果(限制条数)
},
/**
* 选中建议项时的处理
* @param {object} item - 选中的项 {value: 'xxx'}
*/
handleSelect(item) {
this.cacheInputValue(item.value);
this.inputValue = item.value;
// 触发自定义事件,通知父组件选中结果
this.$emit('input', item.value);
},
/**
* 输入框内容变化时的处理(比如手动输入后回车/失焦)
* @param {string} value - 输入框的值
*/
handleInputChange(value) {
if (value && value.trim() !== '') {
this.cacheInputValue(value.trim());
// 触发自定义事件,通知父组件输入结果
this.$emit('input', value.trim());
} else {
this.$emit('input', '');
}
},
/**
* 缓存输入值到localStorage
* @param {string} value - 要缓存的值
*/
cacheInputValue(value) {
// 去重:如果已存在则移除原记录(保证最新输入在最前面)
this.historyList = this.historyList.filter(item => item.value !== value);
// 添加新记录到头部
this.historyList.unshift({ value });
// 限制最大缓存数量
if (this.historyList.length > this.maxCacheCount) {
this.historyList = this.historyList.slice(0, this.maxCacheCount);
}
// 保存到localStorage
localStorage.setItem(this.innerKey, JSON.stringify(this.historyList));
},
/**
* 清空历史记录(提供给父组件调用的方法)
*/
clearHistory() {
this.historyList = [];
localStorage.removeItem(this.innerKey);
this.inputValue = '';
this.$emit('clear');
}
}
};
</script>
<style scoped>
.demo-autocomplete {
margin-bottom: 20px;
}
.sub-title {
margin-bottom: 10px;
color: #666;
font-size: 14px;
}
.inline-input {
width: 100%;
}
</style>