UNPKG

@ithinkdt/cloud

Version:

iThinkDT Cloud

130 lines (115 loc) 3.54 kB
import { ref, readonly, h, reactive } from 'vue' import { $fetch } from '@ithinkdt/core' export function icon(CTX) { const iconMap = new Map() let _clean function clean() { if (_clean === undefined) { setTimeout(() => { requestIdleCallback(() => { for (const k of iconMap.keys()) { if (iconMap.get(k).value !== undefined) { iconMap.delete(k) } } _clean = undefined }) }, 60_000) _clean = true } } function _getIcon(id) { return fetch(`${CTX._BASE + CTX.SYS}pub/logo/${id}`, { method: 'get', credentials: 'omit', }) .then((resp) => resp.blob()) .then((blob) => blob.text()) .then((text) => { try { const e = JSON.parse(text) console.debug(`获取图标失败,id: ${id}`, e) return '' } catch { return text } finally { clean() } }) } const t = 'data:image/svg+xml;base64,' function getIconUri(id) { if (iconMap.has(id)) { return iconMap.get(id) } const icon = ref() const _icon = readonly(icon) iconMap.set(id, _icon) _getIcon(id).then((text) => { icon.value = text }) return _icon } return { async saveIcon(icon) { icon = { type: 'other', ...icon } if (icon.body instanceof File) { const file = icon.body if (!icon.name) { icon.name = file.name } icon.body = await new Promise((resolve) => { const fr = new FileReader() fr.addEventListener('load', () => { resolve(fr.result) }) fr.readAsDataURL(file) }) } return $fetch .post(`${CTX.SYS}cer/logo/save`, { id: icon.id, name: icon.name, logo: icon.body, type: icon.type, remark: icon.remark, }) .then((res) => { icon.id = res.id return icon }) }, getIconUri, getIcon(id) { const uri = getIconUri(id) return readonly( reactive({ id, body: uri, }), ) }, getIconRender(id) { return () => { let text = getIconUri(id).value if (!text) return if (text.startsWith(t)) { text = window.atob(text.slice(t.length)) return h('span', { innerHTML: text, style: { lineHeight: '0', }, }) } else { return h('img', { src: text, style: { height: '1em', }, }) } } }, } }