UNPKG

@ithinkdt/core

Version:

iThinkDT Core

287 lines (253 loc) 10.4 kB
import { h, isRef, unref, reactive } from 'vue' import { getDict, registerDict } from '../../dict' import { i18n } from '../../i18n' import { pageInit } from '../plugin' import { datetime, number } from './helper' export function getRender(format, field) { const [t, p] = (format || (field.name === 'createUser' || field.name === 'updateUser' ? 'user' : 'string')).split( '|', ) let factory = pageInit.dataFormatters?.[t] if (factory?.factory) { factory = factory.factory } if (!factory) factory = defaultFormatter[t] let _render = factory?.(field, p) if (!_render) { console.warn('数据格式化,未注册的 format:', t) _render = RenderFactory.string() } if (field.render) { return (v, options) => field.render(v, { ...options, render: () => _render(v, options) }) } return _render } export const RenderFactory = { string: () => (v) => v, text: (whiteSpace) => (v) => h('div', { innerText: v, style: { whiteSpace, }, }), url: () => (url) => h('a', { href: url }, [url]), email: () => (email) => h('a', { href: `mailto:${email}` }, [email]), color: () => (color) => h('span', [ h('span', { style: { display: 'inline-block', width: '1em', height: '1em', background: color } }), color, ]), datetime: (fmt) => (v) => datetime(v, fmt), number: (digits, trim) => (v) => number(v, digits, ',', !!trim), percent: (digits, trim) => (v) => { const s = number(v ? v * 100 : v, digits, ',', !!trim) return typeof s === 'string' ? `${s}%` : s }, yesno: () => (v) => { return ['1', 1, true].includes(v) ? i18n.t('sys.yes') : i18n.t('sys.no') }, file: () => (v) => { let ids = Array.isArray(v) ? v : v?.trim() ? v.trim().split(',') : [] return ids.length > 0 ? pageInit.renderFiles(ids) : '' }, image: () => (v) => { let ids = Array.isArray(v) ? v : v?.trim() ? v.trim().split(',') : [] return ids.length > 0 ? pageInit.renderImages(ids) : '' }, icon: () => (v) => { v = pageInit.getIconRender(v) return v ? h(v, { style: { fontSize: '48px', }, }) : '' }, user: ({ multiple, max, size, placement } = {}) => { const map = {} return (v) => { const usernames = v ? (multiple ? (Array.isArray(v) ? v : v.trim() ? v.trim().split(',') : []) : [v]) : [] const users = reactive([]) const usernames1 = [] for (const [i, name] of usernames.entries()) { if (!map[name]) { const u = reactive({ username: name, nickname: name }) map[name] = u usernames1.push(name) } users[i] = map[name] } if (usernames1.length > 0) { pageInit.getUsers(usernames1).then((data) => { for (const it of data) { Object.assign(map[it.username], it) } }) } return pageInit.renderUsers(users, { max, size, placement }) } }, dept: ({ multiple } = {}) => { const map = {} return (v) => { const deptcodes = v ? (multiple ? (Array.isArray(v) ? v : v.trim() ? v.trim().split(',') : []) : [v]) : [] const depts = reactive([]) const deptcodes1 = [] for (const [i, code] of deptcodes.entries()) { if (!map[code]) { const d = reactive({ code, name: code }) map[code] = d deptcodes1.push(code) } depts[i] = map[code] } if (deptcodes1.length > 0) { pageInit.getDepts(deptcodes1).then((data) => { for (const it of data) { Object.assign(map[it.code], it) } }) } return pageInit.renderDepts(depts) } }, dict: (dictKey, { multiple } = {}) => { let getDictMap if (typeof dictKey === 'string' || isRef(dictKey)) { const dictMap = getDict(dictKey, 'map', 'string', false, false) getDictMap = () => dictMap } else { getDictMap = (value, model) => getDict(dictKey({ model, value }), 'map', 'string', false, false) } let it = (v, { model }) => { const dictMap = getDictMap(v, model) return dictMap.get(v?.toString())?.label ?? v } return multiple ? (v, data) => { return (Array.isArray(v) ? v : v?.trim() ? v.trim().split(',') : []) .map((s) => it(s, data)) .join(i18n.t('sys.joinSeparator')) } : it }, state: (dictKey, state) => { let getDictMap if (typeof dictKey === 'string' || isRef(dictKey)) { const dictMap = getDict(dictKey, 'map', 'string', false, false) getDictMap = () => dictMap } else { getDictMap = (value, model) => getDict(dictKey({ model, value }), 'map', 'string', false, false) } const _state = state state = _state ? typeof _state === 'object' ? (v) => _state[v] : (value, model, dict) => _state({ model, value, dict }) : () => 'primary' return (v, { model }) => { const dict = getDictMap?.(v, model).get(v?.toString()) return pageInit.renderState({ text: dict?.label ?? v, type: state(v, model, dict) }) } }, tag: (tag, { dictKey, multiple } = {}) => { let getDictMap if (dictKey) { if (typeof dictKey === 'string' || isRef(dictKey)) { const dictMap = getDict(dictKey, 'map', 'string', false, false) getDictMap = () => dictMap } else { getDictMap = (value, model) => getDict(dictKey({ model, value }), 'map', 'string', false, false) } } const _tag = tag tag = _tag ? typeof _tag === 'string' ? () => ({ type: _tag }) : typeof _tag === 'object' ? (v) => ({ type: _tag[v] }) : (value, model, index, dict) => { const ret = _tag({ model, value, index, dict }) ?? {} if (typeof ret !== 'object') { return { type: ret, } } return ret } : () => ({ type: 'primary' }) const it = (v, { model = {} } = {}, index, isLast = true) => { const dict = getDictMap?.(v, model)?.get(v?.toString()) return pageInit.renderTag({ ...tag(v, model, index, dict), text: dict?.label ?? v, style: { margin: `4.5px ${isLast ? '0' : '10px'} 4.5px 0`, }, }) } return multiple ? (v, data) => { return (Array.isArray(v) ? v : v?.trim() ? v.trim().split(',') : []).map((s, i, arr) => it(s, data, i, i === arr.length - 1), ) } : it }, operation: (btns, { width } = {}) => { return (_v, { model, index }) => { return pageInit.renderTableBtns({ model, index, btns: unref(btns), width: unref(width) }) } }, } export const defaultFormatter = { string: () => RenderFactory.string(), text: (_, param = '') => RenderFactory.text(param || 'pre-wrap'), email: () => RenderFactory.email(), url: () => RenderFactory.url(), color: () => RenderFactory.color(), date: (_, param = '') => RenderFactory.datetime(param || 'yyyy-MM-dd'), datetime: (_, param = '') => RenderFactory.datetime(param || 'yyyy-MM-dd HH:mm:ss'), yesno: () => RenderFactory.yesno(), number: (_, param = '') => { let [digits, trim] = param.split('!') digits = Number.parseInt(digits) return RenderFactory.number(digits, ',', typeof trim !== 'string') }, percent: (_, param = '') => { let [digits, trim] = param.split('!') digits = Number.parseInt(digits) return RenderFactory.percent(digits, ',', typeof trim !== 'string') }, file: () => RenderFactory.file(), image: () => RenderFactory.image(), icon: () => RenderFactory.icon(), dict: ({ dictKey }, param = '') => RenderFactory.dict(param || dictKey, { multiple: false }), dicts: ({ dictKey }, param = '') => RenderFactory.dict(param || dictKey, { multiple: true }), state: ({ dictKey, state }, param = '') => RenderFactory.state(param || dictKey, state), tag: ({ dictKey, tag }, param = '') => RenderFactory.tag(tag, { dictKey: param || dictKey, multiple: false }), tags: ({ dictKey, tag }, param = '') => RenderFactory.tag(tag, { dictKey: param || dictKey, multiple: true }), operation: ({ btns, max, width }) => RenderFactory.operation(btns, { max, width }), user: () => RenderFactory.user({ multiple: false }), users: (_, param = '') => RenderFactory.user({ multiple: true, max: (param && Number.parseInt(param)) || 4 }), dept: () => RenderFactory.dept({ multiple: false }), depts: () => RenderFactory.dept({ multiple: true }), } export function getDictKey(format, { dictKey, dicts = [], multiple }) { if (dictKey) return { dictKey, multiple } if (format === 'yesno') return { dictKey: 'yes-no' } if (format?.startsWith('dict') || format?.startsWith('tag') || format?.startsWith('state')) { dictKey = format.split('|')[1] if (!dictKey) { dictKey = Date.now() + '-' + Math.floor(Math.random() * 1_000_000) registerDict(dictKey, dicts) } return { dictKey, multiple: format.startsWith('dicts') || format.startsWith('tags') ? true : undefined, } } return {} }