格式化代码,websocket功能完善
This commit is contained in:
@@ -13,21 +13,21 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useDictionaryStore } from '@/stores/modules/dictionary'
|
||||
import request from '@/utils/request'
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { useDictionaryStore } from "@/stores/modules/dictionary";
|
||||
import request from "@/utils/request";
|
||||
|
||||
defineOptions({
|
||||
name: 'ScSelect',
|
||||
name: "ScSelect",
|
||||
inheritAttrs: false,
|
||||
})
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
// 数据源类型:data(直接数据)、api(接口数据)、dictionary(字典数据)
|
||||
sourceType: {
|
||||
type: String,
|
||||
default: 'data',
|
||||
validator: (value) => ['data', 'api', 'dictionary'].includes(value),
|
||||
default: "data",
|
||||
validator: (value) => ["data", "api", "dictionary"].includes(value),
|
||||
},
|
||||
// 直接数据(当 sourceType 为 data 时使用)
|
||||
data: {
|
||||
@@ -37,7 +37,7 @@ const props = defineProps({
|
||||
// API 接口地址(当 sourceType 为 api 时使用)
|
||||
api: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: "",
|
||||
},
|
||||
// API 请求参数(当 sourceType 为 api 时使用)
|
||||
apiParams: {
|
||||
@@ -47,7 +47,7 @@ const props = defineProps({
|
||||
// 字典编码(当 sourceType 为 dictionary 时使用)
|
||||
dictionaryCode: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: "",
|
||||
},
|
||||
// 是否启用 API 数据缓存(当 sourceType 为 api 时使用)
|
||||
enableApiCache: {
|
||||
@@ -63,8 +63,8 @@ const props = defineProps({
|
||||
fieldNames: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
label: "label",
|
||||
value: "value",
|
||||
}),
|
||||
},
|
||||
// 是否在组件挂载时立即加载数据
|
||||
@@ -77,62 +77,62 @@ const props = defineProps({
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
const dictionaryStore = useDictionaryStore()
|
||||
const loading = ref(false)
|
||||
const apiData = ref(null)
|
||||
const apiCacheTime = ref(null)
|
||||
const dictionaryStore = useDictionaryStore();
|
||||
const loading = ref(false);
|
||||
const apiData = ref(null);
|
||||
const apiCacheTime = ref(null);
|
||||
const options = computed(() => {
|
||||
switch (props.sourceType) {
|
||||
case 'data':
|
||||
return processData(props.data)
|
||||
case 'api':
|
||||
return processData(apiData.value || [])
|
||||
case 'dictionary':
|
||||
return processData(getDictionaryData())
|
||||
case "data":
|
||||
return processData(props.data);
|
||||
case "api":
|
||||
return processData(apiData.value || []);
|
||||
case "dictionary":
|
||||
return processData(getDictionaryData());
|
||||
default:
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// API 数据缓存
|
||||
const apiCache = new Map()
|
||||
const apiCache = new Map();
|
||||
|
||||
/**
|
||||
* 处理数据格式
|
||||
*/
|
||||
function processData(data) {
|
||||
if (!data || !Array.isArray(data)) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
// 如果有自定义处理函数,使用自定义处理
|
||||
if (props.dataProcessor && typeof props.dataProcessor === 'function') {
|
||||
return props.dataProcessor(data)
|
||||
if (props.dataProcessor && typeof props.dataProcessor === "function") {
|
||||
return props.dataProcessor(data);
|
||||
}
|
||||
|
||||
// 默认处理:确保数据有 label 和 value 字段
|
||||
return data.map((item) => {
|
||||
if (typeof item === 'string' || typeof item === 'number') {
|
||||
if (typeof item === "string" || typeof item === "number") {
|
||||
return {
|
||||
label: item,
|
||||
value: item,
|
||||
}
|
||||
};
|
||||
}
|
||||
// 如果已经有 label 和 value 字段,直接返回
|
||||
if (item.label !== undefined && item.value !== undefined) {
|
||||
return item
|
||||
return item;
|
||||
}
|
||||
// 尝试使用 fieldNames 映射
|
||||
const labelKey = props.fieldNames.label || 'label'
|
||||
const valueKey = props.fieldNames.value || 'value'
|
||||
const labelKey = props.fieldNames.label || "label";
|
||||
const valueKey = props.fieldNames.value || "value";
|
||||
return {
|
||||
label: item[labelKey] || item.name || item.title || item.id,
|
||||
value: item[valueKey] !== undefined ? item[valueKey] : item.id,
|
||||
...item,
|
||||
}
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,9 +140,9 @@ function processData(data) {
|
||||
*/
|
||||
function getDictionaryData() {
|
||||
if (!props.dictionaryCode) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
return dictionaryStore.dictionaries[props.dictionaryCode] || []
|
||||
return dictionaryStore.dictionaries[props.dictionaryCode] || [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,42 +150,42 @@ function getDictionaryData() {
|
||||
*/
|
||||
async function loadApiData() {
|
||||
if (!props.api) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查缓存
|
||||
if (props.enableApiCache) {
|
||||
const cacheKey = props.api + JSON.stringify(props.apiParams)
|
||||
const cached = apiCache.get(cacheKey)
|
||||
const cacheKey = props.api + JSON.stringify(props.apiParams);
|
||||
const cached = apiCache.get(cacheKey);
|
||||
|
||||
if (cached && Date.now() - cached.time < props.apiCacheTime) {
|
||||
apiData.value = cached.data
|
||||
return
|
||||
apiData.value = cached.data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await request.get(props.api, { params: props.apiParams })
|
||||
const res = await request.get(props.api, { params: props.apiParams });
|
||||
|
||||
if (res.code === 200) {
|
||||
const data = res.data || res.list || []
|
||||
apiData.value = data
|
||||
const data = res.data || res.list || [];
|
||||
apiData.value = data;
|
||||
|
||||
// 缓存数据
|
||||
if (props.enableApiCache) {
|
||||
const cacheKey = props.api + JSON.stringify(props.apiParams)
|
||||
const cacheKey = props.api + JSON.stringify(props.apiParams);
|
||||
apiCache.set(cacheKey, {
|
||||
data,
|
||||
time: Date.now(),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载 API 数据失败:', error)
|
||||
apiData.value = []
|
||||
console.error("加载 API 数据失败:", error);
|
||||
apiData.value = [];
|
||||
} finally {
|
||||
loading.value = false
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,21 +194,21 @@ async function loadApiData() {
|
||||
*/
|
||||
async function loadDictionaryData() {
|
||||
if (!props.dictionaryCode) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查缓存
|
||||
if (dictionaryStore.dictionaries[props.dictionaryCode]) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
loading.value = true;
|
||||
try {
|
||||
await dictionaryStore.getDictionary(props.dictionaryCode)
|
||||
await dictionaryStore.getDictionary(props.dictionaryCode);
|
||||
} catch (error) {
|
||||
console.error('加载字典数据失败:', error)
|
||||
console.error("加载字典数据失败:", error);
|
||||
} finally {
|
||||
loading.value = false
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,16 +217,16 @@ async function loadDictionaryData() {
|
||||
*/
|
||||
async function handleFocus() {
|
||||
switch (props.sourceType) {
|
||||
case 'api':
|
||||
case "api":
|
||||
if (!apiData.value || apiData.value.length === 0) {
|
||||
await loadApiData()
|
||||
await loadApiData();
|
||||
}
|
||||
break
|
||||
case 'dictionary':
|
||||
break;
|
||||
case "dictionary":
|
||||
if (!dictionaryStore.dictionaries[props.dictionaryCode]) {
|
||||
await loadDictionaryData()
|
||||
await loadDictionaryData();
|
||||
}
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,12 +235,12 @@ async function handleFocus() {
|
||||
*/
|
||||
async function refresh() {
|
||||
switch (props.sourceType) {
|
||||
case 'api':
|
||||
await loadApiData()
|
||||
break
|
||||
case 'dictionary':
|
||||
await dictionaryStore.getDictionary(props.dictionaryCode, true)
|
||||
break
|
||||
case "api":
|
||||
await loadApiData();
|
||||
break;
|
||||
case "dictionary":
|
||||
await dictionaryStore.getDictionary(props.dictionaryCode, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,50 +248,50 @@ async function refresh() {
|
||||
watch(
|
||||
() => props.data,
|
||||
(newVal) => {
|
||||
if (props.sourceType === 'data') {
|
||||
if (props.sourceType === "data") {
|
||||
// data 类型不需要特殊处理,计算属性会自动更新
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.api,
|
||||
() => {
|
||||
if (props.sourceType === 'api') {
|
||||
apiData.value = null
|
||||
if (props.sourceType === "api") {
|
||||
apiData.value = null;
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.apiParams,
|
||||
() => {
|
||||
if (props.sourceType === 'api') {
|
||||
apiData.value = null
|
||||
if (props.sourceType === "api") {
|
||||
apiData.value = null;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.dictionaryCode,
|
||||
() => {
|
||||
if (props.sourceType === 'dictionary') {
|
||||
if (props.sourceType === "dictionary") {
|
||||
// dictionary 变化时,数据会自动从 store 获取
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
// 组件挂载时立即加载数据
|
||||
if (props.immediate) {
|
||||
switch (props.sourceType) {
|
||||
case 'api':
|
||||
loadApiData()
|
||||
break
|
||||
case 'dictionary':
|
||||
loadDictionaryData()
|
||||
break
|
||||
case "api":
|
||||
loadApiData();
|
||||
break;
|
||||
case "dictionary":
|
||||
loadDictionaryData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ defineExpose({
|
||||
refresh,
|
||||
loadApiData,
|
||||
loadDictionaryData,
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user