refactor(web-ele): 移除未使用的工具函数
- 删除了 utils/index.ts 中未使用的树处理和类型判断函数 - 更新了相关文件中的导入路径 - 优化了代码结构,提高了代码的可读性和维护性pull/171/head
parent
2464bf8e8f
commit
8f8f3481ff
|
@ -5,6 +5,4 @@ export * from './formCreate';
|
||||||
export * from './rangePickerProps';
|
export * from './rangePickerProps';
|
||||||
export * from './routerHelper';
|
export * from './routerHelper';
|
||||||
export * from './validator';
|
export * from './validator';
|
||||||
export * from './tree';
|
|
||||||
export * from './is';
|
|
||||||
export * from './bean';
|
export * from './bean';
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
// copy to vben-admin
|
|
||||||
|
|
||||||
const toString = Object.prototype.toString
|
|
||||||
|
|
||||||
export const is = (val: unknown, type: string) => {
|
|
||||||
return toString.call(val) === `[object ${type}]`
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isDef = <T = unknown>(val?: T): val is T => {
|
|
||||||
return typeof val !== 'undefined'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isUnDef = <T = unknown>(val?: T): val is T => {
|
|
||||||
return !isDef(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isObject = (val: any): val is Record<any, any> => {
|
|
||||||
return val !== null && is(val, 'Object')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isEmpty = (val: any): boolean => {
|
|
||||||
if (val === null || val === undefined || typeof val === 'undefined') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (isArray(val) || isString(val)) {
|
|
||||||
return val.length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val instanceof Map || val instanceof Set) {
|
|
||||||
return val.size === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isObject(val)) {
|
|
||||||
return Object.keys(val).length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isDate = (val: unknown): val is Date => {
|
|
||||||
return is(val, 'Date')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isNull = (val: unknown): val is null => {
|
|
||||||
return val === null
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isNullAndUnDef = (val: unknown): val is null | undefined => {
|
|
||||||
return isUnDef(val) && isNull(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isNullOrUnDef = (val: unknown): val is null | undefined => {
|
|
||||||
return isUnDef(val) || isNull(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isNumber = (val: unknown): val is number => {
|
|
||||||
return is(val, 'Number')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isPromise = <T = any>(val: unknown): val is Promise<T> => {
|
|
||||||
return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isString = (val: unknown): val is string => {
|
|
||||||
return is(val, 'String')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isFunction = (val: unknown): val is Function => {
|
|
||||||
return typeof val === 'function'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isBoolean = (val: unknown): val is boolean => {
|
|
||||||
return is(val, 'Boolean')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isRegExp = (val: unknown): val is RegExp => {
|
|
||||||
return is(val, 'RegExp')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isArray = (val: any): val is Array<any> => {
|
|
||||||
return val && Array.isArray(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isWindow = (val: any): val is Window => {
|
|
||||||
return typeof window !== 'undefined' && is(val, 'Window')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isElement = (val: unknown): val is Element => {
|
|
||||||
return isObject(val) && !!val.tagName
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isMap = (val: unknown): val is Map<any, any> => {
|
|
||||||
return is(val, 'Map')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isServer = typeof window === 'undefined'
|
|
||||||
|
|
||||||
export const isClient = !isServer
|
|
||||||
|
|
||||||
export const isUrl = (path: string): boolean => {
|
|
||||||
const reg =
|
|
||||||
/(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/
|
|
||||||
return reg.test(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isDark = (): boolean => {
|
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否是图片链接
|
|
||||||
export const isImgPath = (path: string): boolean => {
|
|
||||||
return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isEmptyVal = (val: any): boolean => {
|
|
||||||
return val === '' || val === null || val === undefined
|
|
||||||
}
|
|
|
@ -1,440 +0,0 @@
|
||||||
interface TreeHelperConfig {
|
|
||||||
id: string;
|
|
||||||
children: string;
|
|
||||||
pid: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_CONFIG: TreeHelperConfig = {
|
|
||||||
id: 'id',
|
|
||||||
children: 'children',
|
|
||||||
pid: 'pid',
|
|
||||||
};
|
|
||||||
export const defaultProps = {
|
|
||||||
children: 'children',
|
|
||||||
label: 'name',
|
|
||||||
value: 'id',
|
|
||||||
isLeaf: 'leaf',
|
|
||||||
emitPath: false, // 用于 cascader 组件:在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
|
|
||||||
};
|
|
||||||
interface Fn<T = any> {
|
|
||||||
(...arg: T[]): T;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getConfig = (config: Partial<TreeHelperConfig>) =>
|
|
||||||
Object.assign({}, DEFAULT_CONFIG, config);
|
|
||||||
|
|
||||||
// tree from list
|
|
||||||
export const listToTree = <T = any>(
|
|
||||||
list: any[],
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T[] => {
|
|
||||||
const conf = getConfig(config) as TreeHelperConfig;
|
|
||||||
const nodeMap = new Map();
|
|
||||||
const result: T[] = [];
|
|
||||||
const { id, children, pid } = conf;
|
|
||||||
|
|
||||||
for (const node of list) {
|
|
||||||
node[children] = node[children] || [];
|
|
||||||
nodeMap.set(node[id], node);
|
|
||||||
}
|
|
||||||
for (const node of list) {
|
|
||||||
const parent = nodeMap.get(node[pid]);
|
|
||||||
(parent ? parent.children : result).push(node);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const treeToList = <T = any>(
|
|
||||||
tree: any,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const { children } = config;
|
|
||||||
const result: any = [...tree];
|
|
||||||
for (let i = 0; i < result.length; i++) {
|
|
||||||
if (!result[i][children!]) continue;
|
|
||||||
result.splice(i + 1, 0, ...result[i][children!]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findNode = <T = any>(
|
|
||||||
tree: any,
|
|
||||||
func: Fn,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T | null => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const { children } = config;
|
|
||||||
const list = [...tree];
|
|
||||||
for (const node of list) {
|
|
||||||
if (func(node)) return node;
|
|
||||||
node[children!] && list.push(...node[children!]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findNodeAll = <T = any>(
|
|
||||||
tree: any,
|
|
||||||
func: Fn,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T[] => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const { children } = config;
|
|
||||||
const list = [...tree];
|
|
||||||
const result: T[] = [];
|
|
||||||
for (const node of list) {
|
|
||||||
func(node) && result.push(node);
|
|
||||||
node[children!] && list.push(...node[children!]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findPath = <T = any>(
|
|
||||||
tree: any,
|
|
||||||
func: Fn,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T | T[] | null => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const path: T[] = [];
|
|
||||||
const list = [...tree];
|
|
||||||
const visitedSet = new Set();
|
|
||||||
const { children } = config;
|
|
||||||
while (list.length) {
|
|
||||||
const node = list[0];
|
|
||||||
if (visitedSet.has(node)) {
|
|
||||||
path.pop();
|
|
||||||
list.shift();
|
|
||||||
} else {
|
|
||||||
visitedSet.add(node);
|
|
||||||
node[children!] && list.unshift(...node[children!]);
|
|
||||||
path.push(node);
|
|
||||||
if (func(node)) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findPathAll = (
|
|
||||||
tree: any,
|
|
||||||
func: Fn,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
) => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const path: any[] = [];
|
|
||||||
const list = [...tree];
|
|
||||||
const result: any[] = [];
|
|
||||||
const visitedSet = new Set(),
|
|
||||||
{ children } = config;
|
|
||||||
while (list.length) {
|
|
||||||
const node = list[0];
|
|
||||||
if (visitedSet.has(node)) {
|
|
||||||
path.pop();
|
|
||||||
list.shift();
|
|
||||||
} else {
|
|
||||||
visitedSet.add(node);
|
|
||||||
node[children!] && list.unshift(...node[children!]);
|
|
||||||
path.push(node);
|
|
||||||
func(node) && result.push([...path]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const filter = <T = any>(
|
|
||||||
tree: T[],
|
|
||||||
func: (n: T) => boolean,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): T[] => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const children = config.children as string;
|
|
||||||
|
|
||||||
function listFilter(list: T[]) {
|
|
||||||
return list
|
|
||||||
.map((node: any) => ({ ...node }))
|
|
||||||
.filter((node) => {
|
|
||||||
node[children] = node[children] && listFilter(node[children]);
|
|
||||||
return func(node) || (node[children] && node[children].length);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return listFilter(tree);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const forEach = <T = any>(
|
|
||||||
tree: T[],
|
|
||||||
func: (n: T) => any,
|
|
||||||
config: Partial<TreeHelperConfig> = {},
|
|
||||||
): void => {
|
|
||||||
config = getConfig(config);
|
|
||||||
const list: any[] = [...tree];
|
|
||||||
const { children } = config;
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
// func 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿
|
|
||||||
if (func(list[i])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
children &&
|
|
||||||
list[i][children] &&
|
|
||||||
list.splice(i + 1, 0, ...list[i][children]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: Extract tree specified structure
|
|
||||||
*/
|
|
||||||
export const treeMap = <T = any>(
|
|
||||||
treeData: T[],
|
|
||||||
opt: { children?: string; conversion: Fn },
|
|
||||||
): T[] => {
|
|
||||||
return treeData.map((item) => treeMapEach(item, opt));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: Extract tree specified structure
|
|
||||||
*/
|
|
||||||
export const treeMapEach = (
|
|
||||||
data: any,
|
|
||||||
{ children = 'children', conversion }: { children?: string; conversion: Fn },
|
|
||||||
) => {
|
|
||||||
const haveChildren =
|
|
||||||
Array.isArray(data[children]) && data[children].length > 0;
|
|
||||||
const conversionData = conversion(data) || {};
|
|
||||||
if (haveChildren) {
|
|
||||||
return {
|
|
||||||
...conversionData,
|
|
||||||
[children]: data[children].map((i: number) =>
|
|
||||||
treeMapEach(i, {
|
|
||||||
children,
|
|
||||||
conversion,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...conversionData,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 递归遍历树结构
|
|
||||||
* @param treeDatas 树
|
|
||||||
* @param callBack 回调
|
|
||||||
* @param parentNode 父节点
|
|
||||||
*/
|
|
||||||
export const eachTree = (treeDatas: any[], callBack: Fn, parentNode = {}) => {
|
|
||||||
treeDatas.forEach((element) => {
|
|
||||||
const newNode = callBack(element, parentNode) || element;
|
|
||||||
if (element.children) {
|
|
||||||
eachTree(element.children, callBack, newNode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造树型结构数据
|
|
||||||
* @param {*} data 数据源
|
|
||||||
* @param {*} id id字段 默认 'id'
|
|
||||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
|
||||||
* @param {*} children 孩子节点字段 默认 'children'
|
|
||||||
*/
|
|
||||||
export const handleTree = (
|
|
||||||
data: any[],
|
|
||||||
id?: string,
|
|
||||||
parentId?: string,
|
|
||||||
children?: string,
|
|
||||||
) => {
|
|
||||||
if (!Array.isArray(data)) {
|
|
||||||
console.warn('data must be an array');
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const config = {
|
|
||||||
id: id || 'id',
|
|
||||||
parentId: parentId || 'parentId',
|
|
||||||
childrenList: children || 'children',
|
|
||||||
};
|
|
||||||
|
|
||||||
const childrenListMap: Record<string, any[]> = {};
|
|
||||||
const nodeIds: Record<string, any> = {};
|
|
||||||
const tree: any[] = [];
|
|
||||||
|
|
||||||
for (const d of data) {
|
|
||||||
const parentId = d[config.parentId];
|
|
||||||
if (childrenListMap[parentId] == null) {
|
|
||||||
childrenListMap[parentId] = [];
|
|
||||||
}
|
|
||||||
nodeIds[d[config.id]] = d;
|
|
||||||
childrenListMap[parentId].push(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const d of data) {
|
|
||||||
const parentId = d[config.parentId];
|
|
||||||
if (nodeIds[parentId] == null) {
|
|
||||||
tree.push(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const t of tree) {
|
|
||||||
adaptToChildrenList(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
function adaptToChildrenList(o: any) {
|
|
||||||
if (childrenListMap[o[config.id]] !== null) {
|
|
||||||
o[config.childrenList] = childrenListMap[o[config.id]];
|
|
||||||
}
|
|
||||||
if (o[config.childrenList]) {
|
|
||||||
for (const c of o[config.childrenList]) {
|
|
||||||
adaptToChildrenList(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tree;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造树型结构数据
|
|
||||||
* @param {*} data 数据源
|
|
||||||
* @param {*} id id字段 默认 'id'
|
|
||||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
|
||||||
* @param {*} children 孩子节点字段 默认 'children'
|
|
||||||
* @param {*} rootId 根Id 默认 0
|
|
||||||
*/
|
|
||||||
// @ts-ignore
|
|
||||||
export const handleTree2 = (data, id, parentId, children, rootId) => {
|
|
||||||
id = id || 'id';
|
|
||||||
parentId = parentId || 'parentId';
|
|
||||||
// children = children || 'children'
|
|
||||||
rootId =
|
|
||||||
rootId ||
|
|
||||||
Math.min(
|
|
||||||
...data.map((item: any) => {
|
|
||||||
return item[parentId];
|
|
||||||
}),
|
|
||||||
) ||
|
|
||||||
0;
|
|
||||||
// 对源数据深度克隆
|
|
||||||
const cloneData = JSON.parse(JSON.stringify(data));
|
|
||||||
// 循环所有项
|
|
||||||
const treeData = cloneData.filter((father: any) => {
|
|
||||||
const branchArr = cloneData.filter((child: any) => {
|
|
||||||
// 返回每一项的子级数组
|
|
||||||
return father[id] === child[parentId];
|
|
||||||
});
|
|
||||||
branchArr.length > 0 ? (father.children = branchArr) : '';
|
|
||||||
// 返回第一层
|
|
||||||
return father[parentId] === rootId;
|
|
||||||
});
|
|
||||||
return treeData !== '' ? treeData : data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验选中的节点,是否为指定 level
|
|
||||||
*
|
|
||||||
* @param tree 要操作的树结构数据
|
|
||||||
* @param nodeId 需要判断在什么层级的数据
|
|
||||||
* @param level 检查的级别, 默认检查到二级
|
|
||||||
* @return true 是;false 否
|
|
||||||
*/
|
|
||||||
export const checkSelectedNode = (
|
|
||||||
tree: any[],
|
|
||||||
nodeId: any,
|
|
||||||
level = 2,
|
|
||||||
): boolean => {
|
|
||||||
if (
|
|
||||||
typeof tree === 'undefined' ||
|
|
||||||
!Array.isArray(tree) ||
|
|
||||||
tree.length === 0
|
|
||||||
) {
|
|
||||||
console.warn('tree must be an array');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验是否是一级节点
|
|
||||||
if (tree.some((item) => item.id === nodeId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 递归计数
|
|
||||||
let count = 1;
|
|
||||||
|
|
||||||
// 深层次校验
|
|
||||||
function performAThoroughValidation(arr: any[]): boolean {
|
|
||||||
count += 1;
|
|
||||||
for (const item of arr) {
|
|
||||||
if (item.id === nodeId) {
|
|
||||||
return true;
|
|
||||||
} else if (
|
|
||||||
typeof item.children !== 'undefined' &&
|
|
||||||
item.children.length !== 0
|
|
||||||
) {
|
|
||||||
if (performAThoroughValidation(item.children)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of tree) {
|
|
||||||
count = 1;
|
|
||||||
if (performAThoroughValidation(item.children)) {
|
|
||||||
// 找到后对比是否是期望的层级
|
|
||||||
if (count >= level) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取节点的完整结构
|
|
||||||
* @param tree 树数据
|
|
||||||
* @param nodeId 节点 id
|
|
||||||
*/
|
|
||||||
export const treeToString = (tree: any[], nodeId: any) => {
|
|
||||||
if (
|
|
||||||
typeof tree === 'undefined' ||
|
|
||||||
!Array.isArray(tree) ||
|
|
||||||
tree.length === 0
|
|
||||||
) {
|
|
||||||
console.warn('tree must be an array');
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
// 校验是否是一级节点
|
|
||||||
const node = tree.find((item) => item.id === nodeId);
|
|
||||||
if (typeof node !== 'undefined') {
|
|
||||||
return node.name;
|
|
||||||
}
|
|
||||||
let str = '';
|
|
||||||
|
|
||||||
function performAThoroughValidation(arr: any[]) {
|
|
||||||
for (const item of arr) {
|
|
||||||
if (item.id === nodeId) {
|
|
||||||
str += ` / ${item.name}`;
|
|
||||||
return true;
|
|
||||||
} else if (
|
|
||||||
typeof item.children !== 'undefined' &&
|
|
||||||
item.children.length !== 0
|
|
||||||
) {
|
|
||||||
str += ` / ${item.name}`;
|
|
||||||
if (performAThoroughValidation(item.children)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of tree) {
|
|
||||||
str = `${item.name}`;
|
|
||||||
if (performAThoroughValidation(item.children)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { handleTree } from '#/utils';
|
import { handleTree } from '@vben/utils';
|
||||||
import * as ProductCategoryApi from '#/api/mall/product/category';
|
import * as ProductCategoryApi from '#/api/mall/product/category';
|
||||||
import * as ProductBrandApi from '#/api/mall/product/brand';
|
import * as ProductBrandApi from '#/api/mall/product/brand';
|
||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
|
|
|
@ -226,11 +226,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { copyValueToTarget } from '#/utils';
|
import { copyValueToTarget } from '#/utils';
|
||||||
import { formatToFraction } from '@vben/utils';
|
import { formatToFraction, isEmpty } from '@vben/utils';
|
||||||
import type { PropertyAndValues, RuleConfig } from './model';
|
import type { PropertyAndValues, RuleConfig } from './model';
|
||||||
import UploadImg from '#/components/upload/image-upload.vue';
|
import UploadImg from '#/components/upload/image-upload.vue';
|
||||||
import { ElTable, ElInput, ElMessage } from 'element-plus';
|
import { ElTable, ElInput, ElMessage } from 'element-plus';
|
||||||
import { isEmpty } from '#/utils/is';
|
|
||||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
padding: 0 4px 2px;
|
padding: 0 4px 2px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
line-height: 0.9;
|
line-height: 0.9;
|
||||||
vertical-align: 2px;
|
|
||||||
color: hsl(var(--secondary-foreground));
|
color: hsl(var(--secondary-foreground));
|
||||||
|
vertical-align: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
background-color: hsl(var(--secondary));
|
background-color: hsl(var(--secondary));
|
||||||
|
|
|
@ -1072,8 +1072,8 @@ watch(
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
outline: 1px dashed #d6d6d6;
|
|
||||||
content: '';
|
content: '';
|
||||||
|
outline: 1px dashed #d6d6d6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resize-stick {
|
.resize-stick {
|
||||||
|
|
|
@ -132,8 +132,8 @@ function toggleTheme(event: MouseEvent) {
|
||||||
&__sun {
|
&__sun {
|
||||||
@apply fill-foreground/90 stroke-none;
|
@apply fill-foreground/90 stroke-none;
|
||||||
|
|
||||||
transform-origin: center center;
|
|
||||||
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
|
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
|
||||||
|
transform-origin: center center;
|
||||||
|
|
||||||
&:hover > svg > & {
|
&:hover > svg > & {
|
||||||
@apply fill-foreground/90;
|
@apply fill-foreground/90;
|
||||||
|
@ -143,10 +143,10 @@ function toggleTheme(event: MouseEvent) {
|
||||||
&__sun-beams {
|
&__sun-beams {
|
||||||
@apply stroke-foreground/90 stroke-[2px];
|
@apply stroke-foreground/90 stroke-[2px];
|
||||||
|
|
||||||
transform-origin: center center;
|
|
||||||
transition:
|
transition:
|
||||||
transform 1.6s cubic-bezier(0.5, 1.5, 0.75, 1.25),
|
transform 1.6s cubic-bezier(0.5, 1.5, 0.75, 1.25),
|
||||||
opacity 0.6s cubic-bezier(0.25, 0, 0.3, 1);
|
opacity 0.6s cubic-bezier(0.25, 0, 0.3, 1);
|
||||||
|
transform-origin: center center;
|
||||||
|
|
||||||
&:hover > svg > & {
|
&:hover > svg > & {
|
||||||
@apply stroke-foreground;
|
@apply stroke-foreground;
|
||||||
|
|
Loading…
Reference in New Issue