update: 优化查询组件性能问题

This commit is contained in:
xieyonghong 2023-02-22 16:44:34 +08:00
parent 754fe63fc1
commit c48ea97962
4 changed files with 384 additions and 23 deletions

View File

@ -110,12 +110,19 @@ import { PropType } from 'vue'
import type { SearchItemData, SearchProps, Terms } from './types'
import { cloneDeep, get, isArray, isFunction } from 'lodash-es'
import { filterTreeSelectNode, filterSelectNode } from '@/utils/comm'
import { useUrlSearchParams } from '@vueuse/core'
type ItemType = SearchProps['type']
interface Emit {
(e: 'change', data: SearchItemData): void
}
type UrlParam = {
q: string | null
target: string | null
}
const urlParams = useUrlSearchParams<UrlParam>('hash')
const props = defineProps({
columns: {
@ -278,28 +285,31 @@ const valueChange = () => {
})
}
const handleQuery = (_params: UrlParam) => {
if (_params.q) {
const path = props.index < 4 ? [0, 'terms', props.index - 1] : [1, 'terms', props.index - 4]
const itemData: SearchItemData = get(props.termsItem.terms, path)
if (itemData) {
termsModel.type = itemData.type
termsModel.column = itemData.column
termsModel.termType = itemData.termType
termsModel.value = itemData.value
const item = columnOptionMap.get(itemData.column)
getComponent(item.type) // Item
// options request
if ('options' in item) {
handleItemOptions(item.options)
}
}
}
}
handleItem()
watch( props.termsItem, (newValue) => {
const path = props.index < 4 ? [0, 'terms', props.index - 1] : [1, 'terms', props.index - 4]
const itemData: SearchItemData = get(newValue.terms, path)
if (itemData) {
termsModel.type = itemData.type
termsModel.column = itemData.column
termsModel.termType = itemData.termType
termsModel.value = itemData.value
const item = columnOptionMap.get(itemData.column)
getComponent(item.type) // Item
// options request
if ('options' in item) {
handleItemOptions(item.options)
}
} else {
handleItem()
}
}, { immediate: true, deep: true })
nextTick(() => {
handleQuery(urlParams)
})
</script>

View File

@ -134,7 +134,8 @@ const searchParams = reactive({
const handleItems = () => {
searchItems.value = []
columnOptionMap.clear()
props.columns!.forEach((item, index) => {
const cloneColumns = cloneDeep(props.columns)
cloneColumns!.forEach((item, index) => {
if (item.search && Object.keys(item.search).length) {
columnOptionMap.set(item.dataIndex, item.search)
searchItems.value.push({
@ -231,6 +232,7 @@ const reset = () => {
urlParams.q = null
urlParams.target = null
}
emit('search', terms)
}
watch(width, (value) => {

View File

@ -1,15 +1,57 @@
<template>
<page-container>
<search
:columns='columns'
/>
<j-table
:columns='columns'
/>
</page-container>
</template>
<script setup>
<script setup lang='ts'>
import type { SceneItem } from './typings'
const columns = [
{
dataIndex: 'name',
fixed: 'left',
ellipsis: true,
width: 300,
title: '名称',
search: {
type: 'string'
}
},
{
dataIndex: 'triggerType',
title: '触发方式',
search: {
type: 'select',
options: [
{ label: '手动触发', value: 'manual'},
{ label: '定时触发', value: 'timer'},
{ label: '设备触发', value: 'device'}
]
}
},
{
dataIndex: 'description',
title: '说明',
},
{
dataIndex: 'state',
title: '状态',
search: {
type: 'select',
options: [
{ label: '正常', value: 'started'},
{ label: '禁用', value: 'disable'},
]
}
}
]
</script>
<style scoped>

View File

@ -0,0 +1,307 @@
type State = {
value: string;
text: string;
};
type Action = {
executor: string;
configuration: Record<string, unknown>;
};
type Trigger = {
type: string;
device: Record<string, any>;
};
export enum ParallelEnum {
'parallel' = 'parallel',
'serial' = 'serial',
}
export type ParallelType = keyof typeof ParallelEnum;
export enum Source {
'manual' = 'manual',
'metric' = 'metric',
'fixed' = 'fixed',
}
export enum ActionDeviceSelector {
'all' = 'all',
'fixed' = 'fixed',
'tag' = 'tag',
'relation' = 'relation',
}
export enum ActionDeviceSource {
'fixed' = 'fixed',
'upper' = 'upper',
'relation' = 'relation',
}
export enum OperatorType {
'online' = 'online',
'offline' = 'offline',
'reportEvent' = 'reportEvent',
'reportProperty' = 'reportProperty',
'readProperty' = 'readProperty',
'writeProperty' = 'writeProperty',
'invokeFunction' = 'invokeFunction',
}
export enum TimerTrigger {
'week' = 'week',
'month' = 'month',
'cron' = 'cron',
}
export enum TimeUnit {
'seconds' = 'seconds',
'minutes' = 'minutes',
'hours' = 'hours',
}
export enum Executor {
'notify' = 'notify',
'delay' = 'delay',
'device' = 'device',
'alarm' = 'alarm',
}
export enum DeviceMessageType {
'INVOKE_FUNCTION' = 'INVOKE_FUNCTION',
'READ_PROPERTY' = 'READ_PROPERTY',
'WRITE_PROPERTY' = 'WRITE_PROPERTY',
}
export enum ActionAlarmMode {
'trigger' = 'trigger',
'relieve' = 'relieve',
}
export interface OperationTimerPeriod {
from: string;
to: string;
every: string[];
unit: keyof typeof TimeUnit;
}
export interface OperationTimer {
trigger: keyof typeof TimerTrigger;
mod: string;
cron?: string;
when?: string[];
period?: OperationTimerPeriod;
once?: Record<string, any>;
}
export interface TriggerDeviceOptions {
operator: keyof typeof OperatorType;
/** 触发类型为readProperty,writeProperty,invokeFunction时不能为空 */
timer?: OperationTimer;
/** 触发类型为reportEvent时不能为空 */
eventId?: string;
/** 触发类型为readProperty时不能为空 */
readProperties?: string[];
/** 触发类型为writeProperty时不能为空 */
writeProperties?: Record<string, any>;
/** 触发类型为invokeFunction时不能为空 */
functionId?: string;
/** 触发类型为invokeFunction时不能为空 */
functionParameters?: Record<string, any>[];
}
/**
*
*/
export interface TriggerDevice {
productId: string;
selector: string;
selectorValues?: Record<string, any>[];
operation?: TriggerDeviceOptions;
}
export interface ShakeLimitType {
enabled: boolean;
groupType?: string; // 执行动作没有该参数
time: number;
threshold: number;
alarmFirst: boolean;
}
export interface BranchesType {
enabled: boolean;
groupType?: string; // 执行动作没有该参数
time: number;
threshold: number;
alarmFirst: boolean;
}
export interface SceneItem {
parallel: boolean;
state: State;
actions: Action[];
trigger: Trigger;
id: string;
name: string;
description: string;
branches: BranchesType[];
options: any;
triggerType: string;
}
export type TriggerType = {
type: string;
/**
*
*/
shakeLimit?: ShakeLimitType;
/**
*
*/
options?: Record<string, any>;
/**
*
*/
device?: TriggerDevice;
/**
*
*/
timer?: OperationTimer;
};
export interface TermsVale {
source: keyof typeof Source;
/** 手动输入值,source为 manual 时不能为空 */
value?: Record<string, any> | any[];
/** 指标值,source为 metric 时不能为空 */
metric?: Record<string, any>;
}
export type TermsType = {
column?: string;
value?: TermsVale;
type?: string;
termType?: string;
options?: any[];
terms?: TermsType[];
key?: string;
};
export type PlatformRelation = {
objectType: string;
objectId: string;
};
export type Relationship = {
objectType: string;
objectSource: {
source: string;
upperKey: string;
};
related: {
objectType: string;
relation: string;
};
};
export interface NotifyVariablesType {
source: string;
value?: Record<string, any>;
upperKey?: string;
relation?: PlatformRelation | Relationship;
}
export interface NotifyProps {
notifyType: string;
notifierId: string;
templateId: string;
variables: Record<string, NotifyVariablesType>;
options?: Record<string, any>;
}
export type SelectorValuesType =
| { value: string; name: string }
| { value: { column: string; value: any }[]; name: string }
| { value: { objectType: string; relation: any }[] };
export type ActionDeviceMessageType = {
deviceId: string;
messageType: keyof typeof DeviceMessageType;
/** 功能调用时使用 */
functionId?: string;
/** 功能调用时使用 */
inputs?: Record<string, any>[];
/** 读取属性时使用, 读取属性时为String数组设置属性时为 Object */
properties?: string[] | Record<string, any>;
};
export interface ActionsDeviceProps {
selector: keyof typeof ActionDeviceSelector;
source: keyof typeof ActionDeviceSource;
productId?: string;
message?: ActionDeviceMessageType;
selectorValues?: SelectorValuesType[];
/** 来源为upper时不能为空 */
upperKey?: string;
/** 来源为relation时不能为空 */
relation?: any;
}
export interface BranchesThen {
parallel: boolean;
actions: ActionsType[];
key?: string;
}
export interface ActionBranchesProps {
when: TermsType[];
shakeLimit: ShakeLimitType;
then: BranchesThen[];
key?: string;
}
export interface ActionsType {
executor: keyof typeof Executor;
/** 执行器类型为notify时不能为空 */
notify?: NotifyProps;
/** 执行器类型为delay时不能为空 */
delay?: {
time?: number;
unit?: keyof typeof TimeUnit;
};
device?: ActionsDeviceProps;
alarm?: {
mode: keyof typeof ActionAlarmMode;
};
terms?: TermsType[];
/** map中的key用于删除 */
key?: string;
options?: Record<string, any>;
}
export interface FormModelType {
id?: string;
name?: string;
/**
*
*/
trigger?: TriggerType;
/**
* ,
*/
terms?: TermsType[];
/**
*
*/
actions?: ActionsType[];
/**
*
*/
branches?: ActionBranchesProps[];
/**
* ,
*/
options?: Record<string, any>;
description?: string;
}