UNPKG

@ithinkdt/core

Version:

iThinkDT Core

160 lines (144 loc) 4.59 kB
import { computed, shallowRef, isRef, shallowReactive, watch, nextTick, unref } from 'vue' import { tryOnUnmounted } from '@vueuse/core' import { useI18n } from '../i18n' export let init export function setInit(init0) { init = init0 } const layzePool = [] function batchFetchDicts() { const _layzePool = [...layzePool] layzePool.length = 0 init.fetchDicts(_layzePool.map(([dictType]) => dictType)).then( (res) => { for (const [dictType, cb] of _layzePool) { cb(res?.[dictType] ?? []) } }, (error) => { console.error('[dict]: 请求字典项数据失败:', error) for (const [_dictType, cb] of _layzePool) { cb([]) } }, ) } export async function _getDict(dictType, forceCache) { if (forceCache || !hasDictType(dictType)) { if (typeof dictType !== 'string' || !dictType?.trim()) { console.error('[dict]: 字典类型错误:', dictType) return [] } removeDict(dictType) const $fetch = new Promise((resolve) => { layzePool.push([dictType, resolve]) }) if (layzePool.length === 1) { nextTick(batchFetchDicts) } registerDict(dictType, $fetch, { label: init.labelGetter, value: init.valueGetter, disabled: init.disabledGetter, }) await $fetch } await dictMap[dictType]?.$ return unref(dictMap[dictType]?.data) ?? [] } export const dictMap = {} export const dictValueMap = {} export function registerDict(dictType, dicts, { autoClean = false, cleanUseless = true, label, value, disabled } = {}) { let _dicts let $ if (typeof dicts === 'function') { dicts = Promise.resolve(dicts(_getDict)) } if (dicts instanceof Promise) { _dicts = shallowRef([]) $ = dicts.then((dicts) => { _dicts.value = dicts }) } else { _dicts = isRef(dicts) ? dicts : shallowRef(dicts) } const _label = typeof label === 'function' ? label : (d) => d[label ?? 'label'] const _value = typeof value === 'function' ? value : (d) => d[value ?? 'value'] const _disabled = typeof disabled === 'function' ? disabled : (d) => d[disabled ?? 'disabled'] const { locale } = useI18n() const $dicts = computed(() => { return _dicts.value?.map((dict) => { return { label: _label(dict, locale.value), value: _value(dict), disabled: _disabled(dict), orign: dict, } }) }) dictMap[dictType] = { date: cleanUseless ? Date.now() : undefined, data: $dicts, $, } const unregister = () => removeDict(dictType) if (autoClean) { tryOnUnmounted(unregister) } return { dictType, dicts: getDicts(dictType), unregister, } } export function getDicts(dictType, hideDisabled = true, valueType = 'string') { const cache = dictMap[dictType] cache.date = Date.now() const dicts = shallowReactive([]) watch( cache.data, (data = []) => { dicts.length = 0 let array = valueType === 'number' ? data.map((it) => ({ ...it, value: Number(it.value) })) : data if (hideDisabled) { array = array.filter((it) => it.disabled !== true) } dicts.push(...array) }, { immediate: true }, ) return dicts } export function getDictMap(dictType, hideDisabled = false, valueType = 'string') { if (!dictValueMap[dictType + hideDisabled]) { const map = shallowReactive(new Map()) watch( getDicts(dictType, hideDisabled, valueType), (dicts) => { map.clear() for (const dict of dicts) { map.set(dict.value, dict) } }, { immediate: true }, ) dictValueMap[dictType + hideDisabled] = map } return dictValueMap[dictType + hideDisabled] } export function hasDictType(dictType) { return !!dictMap[dictType] } export function removeDict(dictType) { delete dictMap[dictType] delete dictValueMap[dictType] } export function cleanUseless(delay = 1 * 60 * 1000) { const now = Date.now() for (const key of Object.keys(dictMap)) { const date = dictMap[key]?.date if (date && now - date > delay) { removeDict(key) } } }