mirror of
https://github.com/bufanyun/hotgo.git
synced 2026-02-19 04:44:29 +08:00
发布v2.15.1版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Ref, UnwrapRef } from '@vue/reactivity';
|
||||
import onerrorImg from '@/assets/images/onerror.png';
|
||||
import { NTag, SelectRenderTag } from 'naive-ui';
|
||||
import { h } from 'vue';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { ActionItem } from '@/components/Table';
|
||||
import { isBoolean, isFunction } from '@/utils/is';
|
||||
import { PermissionsEnum } from '@/enums/permissionsEnum';
|
||||
|
||||
export interface Option {
|
||||
label: string;
|
||||
@@ -44,15 +45,50 @@ export function getOptionTag(options: Option[], value) {
|
||||
}
|
||||
|
||||
// 自适应模板宽度
|
||||
export function adaModalWidth(dialogWidth: Ref<UnwrapRef<string>>, def = 840) {
|
||||
export function adaModalWidth(def = 840) {
|
||||
const val = document.body.clientWidth;
|
||||
|
||||
if (val <= def) {
|
||||
dialogWidth.value = '100%';
|
||||
return '100%';
|
||||
} else {
|
||||
dialogWidth.value = def + 'px';
|
||||
return def + 'px';
|
||||
}
|
||||
return dialogWidth.value;
|
||||
}
|
||||
|
||||
interface TableColumn {
|
||||
width?: number | string;
|
||||
auth?: PermissionsEnum | PermissionsEnum[] | string | string[];
|
||||
ifShow?: boolean | ((action: ActionItem) => boolean);
|
||||
}
|
||||
|
||||
// 自适应表格组件横向滑动可见宽度
|
||||
export function adaTableScrollX(columns: TableColumn[] = [], actionWidth: number) {
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
let x = 50; // 勾选列宽度
|
||||
columns = columns.filter((column) => {
|
||||
return hasPermission(column.auth as string[]) && isIfShow(column);
|
||||
});
|
||||
for (const column of columns) {
|
||||
if (column.width && Number(column.width) >= 1) {
|
||||
x += Number(column.width);
|
||||
} else {
|
||||
x += 100; // 默认列宽度
|
||||
}
|
||||
}
|
||||
x += actionWidth;
|
||||
return x;
|
||||
}
|
||||
|
||||
export function isIfShow(action: ActionItem): boolean {
|
||||
let isIfShow = true;
|
||||
const ifShow = action.ifShow;
|
||||
if (isBoolean(ifShow)) {
|
||||
isIfShow = ifShow;
|
||||
}
|
||||
if (isFunction(ifShow)) {
|
||||
isIfShow = ifShow(action);
|
||||
}
|
||||
return isIfShow;
|
||||
}
|
||||
|
||||
// 图片加载失败显示自定义默认图片(缺省图)
|
||||
@@ -61,16 +97,6 @@ export function errorImg(e: any): void {
|
||||
e.target.onerror = null;
|
||||
}
|
||||
|
||||
export const renderTag: SelectRenderTag = ({ option }) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: option.listClass as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
},
|
||||
{ default: () => option.label }
|
||||
);
|
||||
};
|
||||
|
||||
export function timeFix() {
|
||||
const time = new Date();
|
||||
const hour = time.getHours();
|
||||
@@ -98,3 +124,32 @@ export function rdmLightRgbColor(): string {
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
// 将列表数据转为树形数据
|
||||
export function convertListToTree(list: any[], idField = 'id', pidField = 'pid') {
|
||||
const min = list.reduce((prev, current) => (prev[pidField] < current[pidField] ? prev : current));
|
||||
|
||||
const map = list.reduce((acc, item) => {
|
||||
acc[item[idField]] = { ...item, children: [] };
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
list.forEach((item) => {
|
||||
if (item[pidField] !== min[pidField]) {
|
||||
map[item[pidField]].children.push(map[item[idField]]);
|
||||
}
|
||||
});
|
||||
return list.filter((item) => item[pidField] === min[pidField]).map((item) => map[item[idField]]);
|
||||
}
|
||||
|
||||
// 从树选项中获取所有key
|
||||
export function getTreeKeys(data: any[], idField = 'id') {
|
||||
const keys = [];
|
||||
data.map((item) => {
|
||||
keys.push(item[idField]);
|
||||
if (item.children && item.children.length) {
|
||||
keys.push(...getTreeKeys(item.children));
|
||||
}
|
||||
});
|
||||
return keys;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function checkStatus(status: number, msg: string): void {
|
||||
$message.error('网络请求超时');
|
||||
break;
|
||||
case 500:
|
||||
$message.error('服务器错误,请联系管理员!');
|
||||
$message.error('服务器错误,请稍候重试!');
|
||||
break;
|
||||
case 501:
|
||||
$message.error('网络未实现');
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import { h, unref } from 'vue';
|
||||
import type { App, Plugin } from 'vue';
|
||||
import { NIcon, NTag, NTooltip } from 'naive-ui';
|
||||
import {
|
||||
NAvatar,
|
||||
NBadge,
|
||||
NButton,
|
||||
NIcon,
|
||||
NPopover,
|
||||
NTable,
|
||||
NTag,
|
||||
NTooltip,
|
||||
SelectRenderTag,
|
||||
} from 'naive-ui';
|
||||
import { EllipsisHorizontalCircleOutline } from '@vicons/ionicons5';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { isObject } from './is/index';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { VNode } from '@vue/runtime-core';
|
||||
|
||||
export const renderTooltip = (trigger, content) => {
|
||||
return h(NTooltip, null, {
|
||||
@@ -38,6 +50,100 @@ export function renderNew(type = 'warning', text = 'New', color: object = newTag
|
||||
);
|
||||
}
|
||||
|
||||
// render 标记
|
||||
export function renderBadge(node: VNode) {
|
||||
return h(
|
||||
NBadge,
|
||||
{
|
||||
dot: true,
|
||||
type: 'info',
|
||||
},
|
||||
{ default: () => node }
|
||||
);
|
||||
}
|
||||
|
||||
// render 标签
|
||||
export const renderTag: SelectRenderTag = ({ option }) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: option.listClass as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
},
|
||||
{ default: () => option.label }
|
||||
);
|
||||
};
|
||||
|
||||
export interface MemberSumma {
|
||||
id: number; // 用户ID
|
||||
realName: string; // 真实姓名
|
||||
username: string; // 用户名
|
||||
avatar: string; // 头像
|
||||
}
|
||||
|
||||
// render 操作人摘要
|
||||
export const renderPopoverMemberSumma = (member?: MemberSumma) => {
|
||||
if (!member) {
|
||||
return '';
|
||||
}
|
||||
return h(
|
||||
NPopover,
|
||||
{ trigger: 'hover' },
|
||||
{
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
strong: true,
|
||||
size: 'small',
|
||||
text: true,
|
||||
iconPlacement: 'right',
|
||||
},
|
||||
{ default: () => member.realName, icon: renderIcon(EllipsisHorizontalCircleOutline) }
|
||||
),
|
||||
default: () =>
|
||||
h(
|
||||
NTable,
|
||||
{
|
||||
props: {
|
||||
bordered: false,
|
||||
'single-line': false,
|
||||
size: 'small',
|
||||
},
|
||||
},
|
||||
[
|
||||
h('thead', [
|
||||
h('tr', { align: 'center' }, [
|
||||
h('th', '用户ID'),
|
||||
h('th', '头像'),
|
||||
h('th', '姓名'),
|
||||
h('th', '用户名'),
|
||||
]),
|
||||
]),
|
||||
h('tbody', [
|
||||
h('tr', { align: 'center' }, [
|
||||
h('td', member.id),
|
||||
h('td', h(NAvatar, { src: member.avatar, round: true, size: 'small' })),
|
||||
h('td', member.realName),
|
||||
h('td', member.username),
|
||||
]),
|
||||
]),
|
||||
]
|
||||
),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// render html
|
||||
export function renderHtmlTooltip(content: string) {
|
||||
content = content.replace(/\n/g, '<br>');
|
||||
const html = h('p', { id: 'app' }, [
|
||||
h('div', {
|
||||
innerHTML: content,
|
||||
}),
|
||||
]);
|
||||
return renderTooltip(html, html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归组装菜单格式
|
||||
*/
|
||||
@@ -174,35 +280,6 @@ export const withInstall = <T>(component: T, alias?: string) => {
|
||||
return component as T & Plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* 找到对应的节点
|
||||
* */
|
||||
let result = null;
|
||||
|
||||
export function getTreeItem(data: any[], key?: string | number): any {
|
||||
data.map((item) => {
|
||||
if (item.key === key) {
|
||||
result = item;
|
||||
} else {
|
||||
if (item.children && item.children.length) {
|
||||
getTreeItem(item.children, key);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getTreeAll(data: any[]): any[] {
|
||||
const treeAll: any[] = [];
|
||||
data.map((item) => {
|
||||
treeAll.push(item.key);
|
||||
if (item.children && item.children.length) {
|
||||
treeAll.push(...getTreeAll(item.children));
|
||||
}
|
||||
});
|
||||
return treeAll;
|
||||
}
|
||||
|
||||
// dynamic use hook props
|
||||
export function getDynamicProps<T, U>(props: T): Partial<U> {
|
||||
const ret: Recordable = {};
|
||||
@@ -269,15 +346,18 @@ export function getAllExpandKeys(treeData: any): any[] {
|
||||
return expandedKeys;
|
||||
}
|
||||
|
||||
// 从树中查找指定ID
|
||||
export function findTreeDataById(data: any[], id: number | string) {
|
||||
// 从树中查找指定节点
|
||||
export function findTreeNode(data: any[], key?: string | number, keyField = 'key'): any {
|
||||
for (const item of data) {
|
||||
if (item.id === id) {
|
||||
if (item[keyField] == key) {
|
||||
return item;
|
||||
}
|
||||
if (item.children) {
|
||||
const found = findTreeDataById(item.children, id);
|
||||
if (found) return found;
|
||||
} else {
|
||||
if (item.children && item.children.length) {
|
||||
const foundItem = findTreeNode(item.children, key);
|
||||
if (foundItem) {
|
||||
return foundItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user