From 3987c9e876caecc0208ed61bed553ed09ad9f1da Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Thu, 12 Sep 2024 08:43:56 +0800 Subject: [PATCH] feat: render util --- apps/web-antd/src/utils/render.tsx | 213 ++++++++++++++++++ .../src/views/system/config/index.vue | 10 + 2 files changed, 223 insertions(+) create mode 100644 apps/web-antd/src/utils/render.tsx diff --git a/apps/web-antd/src/utils/render.tsx b/apps/web-antd/src/utils/render.tsx new file mode 100644 index 00000000..8dc95cad --- /dev/null +++ b/apps/web-antd/src/utils/render.tsx @@ -0,0 +1,213 @@ +import type { DictData } from '#/api/system/dict/dict-data-model'; + +import { JsonPreview } from '@vben/common-ui'; +import { Icon } from '@vben/icons'; + +import { Tag } from 'ant-design-vue'; + +import { DictTag } from '#/components/dict'; + +import { getDict } from './dict'; + +/** + * 渲染标签 + * @param text 文字 + * @param color 颜色 + * @returns render + */ +function renderTag(text: string, color?: string) { + return {text}; +} + +/** + * + * @param tags 标签list + * @param wrap 是否换行显示 + * @param [gap] 间隔 + * @returns render + */ +export function renderTags(tags: string[], wrap = false, gap = 1) { + return ( +
+ {tags.map((tag, index) => { + return
{renderTag(tag)}
; + })} +
+ ); +} + +/** + * + * @param json json对象 接受object/string类型 + * @returns json预览 + */ +export function renderJsonPreview(json: any) { + if (typeof json !== 'object' && typeof json !== 'string') { + return {json}; + } + if (typeof json === 'object') { + return ; + } + try { + const obj = JSON.parse(json); + // 基本数据类型可以被转为json + if (typeof obj !== 'object') { + return {obj}; + } + return ; + } catch { + return {json}; + } +} + +/** + * iconify图标 + * @param icon icon名称 + * @returns render + */ +export function renderIcon(icon: string) { + return ; +} + +// httpMethod +export function renderHttpMethodTag(type: string) { + const method = type.toUpperCase(); + let color = 'default'; + const title = `${method}请求`; + switch (method) { + case 'DELETE': { + color = 'red'; + break; + } + case 'GET': { + color = 'green'; + break; + } + case 'POST': { + color = 'blue'; + break; + } + case 'PUT': { + color = 'orange'; + break; + } + } + return {title}; +} + +export function renderDictTag(value: string, dicts: DictData[]) { + return ; +} + +/** + * render多个dictTag + * @param value key数组 string[]类型 + * @param dicts 字典数组 + * @param wrap 是否需要换行显示 + * @param [gap] 间隔 + * @returns render + */ +export function renderDictTags( + value: string[], + dicts: DictData[], + wrap = true, + gap = 1, +) { + if (!Array.isArray(value)) { + return
{value}
; + } + return ( +
+ {value.map((item, index) => { + return
{renderDictTag(item, dicts)}
; + })} +
+ ); +} + +/** + * 显示字典标签 一般是table使用 + * @param value 值 + * @param dictName dictName + * @returns tag + */ +export function renderDict(value: string, dictName: string) { + const dictInfo = getDict(dictName); + return renderDictTag(value, dictInfo); +} + +export function renderIconSpan( + icon: string, + value: string, + center = false, + marginLeft = '2px', +) { + const justifyCenter = center ? 'justify-center' : ''; + return ( + + {renderIcon(icon)} + {value} + + ); +} + +const osOptions = [ + { icon: 'devicon:windows8', value: 'windows' }, + { icon: 'devicon:linux', value: 'linux' }, + { icon: 'wpf:macos', value: 'osx' }, + { icon: 'flat-color-icons:android-os', value: 'android' }, + { icon: 'majesticons:iphone-x-apps-line', value: 'iphone' }, +]; + +/** + * 浏览器图标 + * cn.hutool.http.useragent -> browers + */ +const browserOptions = [ + { icon: 'logos:chrome', value: 'chrome' }, + { icon: 'logos:microsoft-edge', value: 'edge' }, + { icon: 'logos:firefox', value: 'firefox' }, + { icon: 'logos:opera', value: 'opera' }, + { icon: 'logos:safari', value: 'safari' }, + { icon: 'mdi:wechat', value: 'micromessenger' }, + { icon: 'logos:quarkus-icon', value: 'quark' }, + { icon: 'mdi:wechat', value: 'wxwork' }, + { icon: 'simple-icons:tencentqq', value: 'qq' }, + { icon: 'ri:dingding-line', value: 'dingtalk' }, + { icon: 'arcticons:uc-browser', value: 'uc' }, + { icon: 'ri:baidu-fill', value: 'baidu' }, +]; + +export function renderOsIcon(os: string, center = false) { + if (!os) { + return; + } + let current = osOptions.find((item) => + os.toLocaleLowerCase().includes(item.value), + ); + // windows要特殊处理 + if (os.toLocaleLowerCase().includes('windows')) { + current = osOptions[0]; + } + if (current) { + return renderIconSpan(current.icon, os, center, '5px'); + } + // 返回默认 + const defaultIcon = 'ic:outline-computer'; + return renderIconSpan(defaultIcon, os, center, '5px'); +} + +export function renderBrowserIcon(browser: string, center = false) { + if (!browser) { + return; + } + const current = browserOptions.find((item) => + browser.toLocaleLowerCase().includes(item.value), + ); + if (current) { + return renderIconSpan(current.icon, browser, center, '5px'); + } + // 返回默认 + const defaultIcon = 'ph:browser-duotone'; + return renderIconSpan(defaultIcon, browser, center, '5px'); +} diff --git a/apps/web-antd/src/views/system/config/index.vue b/apps/web-antd/src/views/system/config/index.vue index c45588bc..0750a5da 100644 --- a/apps/web-antd/src/views/system/config/index.vue +++ b/apps/web-antd/src/views/system/config/index.vue @@ -7,10 +7,12 @@ import type { Config } from '#/api/system/config/model'; import { onMounted, ref } from 'vue'; import { Page, useVbenModal } from '@vben/common-ui'; +import { DictEnum } from '@vben/constants'; import { Space, Table } from 'ant-design-vue'; import { configList } from '#/api/system/config'; +import { renderDict } from '#/utils/render'; import configModal from './config-modal.vue'; @@ -52,6 +54,14 @@ const columns: ColumnsType = [ dataIndex: 'configValue', title: '参数Value', }, + { + align: 'center', + customRender: ({ value }) => { + return renderDict(value, DictEnum.SYS_YES_NO); + }, + dataIndex: 'configType', + title: '系统内置', + }, { align: 'center', dataIndex: 'remark',