格式化代码,websocket功能完善

This commit is contained in:
2026-02-18 21:50:05 +08:00
parent 6543e2ccdd
commit b6c133952b
101 changed files with 15829 additions and 10739 deletions
@@ -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">