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',