update: 优化查询组件性能问题
This commit is contained in:
parent
754fe63fc1
commit
c48ea97962
|
|
@ -110,12 +110,19 @@ import { PropType } from 'vue'
|
||||||
import type { SearchItemData, SearchProps, Terms } from './types'
|
import type { SearchItemData, SearchProps, Terms } from './types'
|
||||||
import { cloneDeep, get, isArray, isFunction } from 'lodash-es'
|
import { cloneDeep, get, isArray, isFunction } from 'lodash-es'
|
||||||
import { filterTreeSelectNode, filterSelectNode } from '@/utils/comm'
|
import { filterTreeSelectNode, filterSelectNode } from '@/utils/comm'
|
||||||
|
import { useUrlSearchParams } from '@vueuse/core'
|
||||||
|
|
||||||
type ItemType = SearchProps['type']
|
type ItemType = SearchProps['type']
|
||||||
|
|
||||||
interface Emit {
|
interface Emit {
|
||||||
(e: 'change', data: SearchItemData): void
|
(e: 'change', data: SearchItemData): void
|
||||||
}
|
}
|
||||||
|
type UrlParam = {
|
||||||
|
q: string | null
|
||||||
|
target: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlParams = useUrlSearchParams<UrlParam>('hash')
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
columns: {
|
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()
|
handleItem()
|
||||||
|
|
||||||
watch( props.termsItem, (newValue) => {
|
nextTick(() => {
|
||||||
|
handleQuery(urlParams)
|
||||||
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 })
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,8 @@ const searchParams = reactive({
|
||||||
const handleItems = () => {
|
const handleItems = () => {
|
||||||
searchItems.value = []
|
searchItems.value = []
|
||||||
columnOptionMap.clear()
|
columnOptionMap.clear()
|
||||||
props.columns!.forEach((item, index) => {
|
const cloneColumns = cloneDeep(props.columns)
|
||||||
|
cloneColumns!.forEach((item, index) => {
|
||||||
if (item.search && Object.keys(item.search).length) {
|
if (item.search && Object.keys(item.search).length) {
|
||||||
columnOptionMap.set(item.dataIndex, item.search)
|
columnOptionMap.set(item.dataIndex, item.search)
|
||||||
searchItems.value.push({
|
searchItems.value.push({
|
||||||
|
|
@ -231,6 +232,7 @@ const reset = () => {
|
||||||
urlParams.q = null
|
urlParams.q = null
|
||||||
urlParams.target = null
|
urlParams.target = null
|
||||||
}
|
}
|
||||||
|
emit('search', terms)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(width, (value) => {
|
watch(width, (value) => {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,57 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<search
|
<search
|
||||||
|
:columns='columns'
|
||||||
/>
|
/>
|
||||||
<j-table
|
<j-table
|
||||||
|
:columns='columns'
|
||||||
/>
|
/>
|
||||||
</page-container>
|
</page-container>
|
||||||
</template>
|
</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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue