feat: 场景联动添加ParamsDropdown组件
This commit is contained in:
parent
c5018e631a
commit
75eca7d0dc
|
@ -100,7 +100,7 @@ const matchComponents: IMatcher[] = [
|
|||
},
|
||||
{
|
||||
pattern: /^TimePicker|^TimeRangePicker/,
|
||||
styleDir: 'TimeTicker'
|
||||
styleDir: 'TimePicker'
|
||||
},
|
||||
{
|
||||
pattern: /^Radio/,
|
||||
|
|
|
@ -7,6 +7,15 @@
|
|||
:options="options"
|
||||
allowClear
|
||||
style="width: 100%"
|
||||
@change='selectChange'
|
||||
/>
|
||||
<j-time-picker
|
||||
v-else-if="typeMap.get(itemType) === 'time'"
|
||||
v-model:value="myValue"
|
||||
allowClear
|
||||
format="HH:mm:ss"
|
||||
style="width: 100%"
|
||||
@change='timeChange'
|
||||
/>
|
||||
<j-date-picker
|
||||
v-else-if="typeMap.get(itemType) === 'date'"
|
||||
|
@ -16,17 +25,20 @@
|
|||
lang="cn"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
@change='dateChange'
|
||||
/>
|
||||
<j-input-number
|
||||
v-else-if="typeMap.get(itemType) === 'inputNumber'"
|
||||
v-model:value="myValue"
|
||||
allowClear
|
||||
style="width: 100%"
|
||||
@change='inputChange'
|
||||
/>
|
||||
<j-input
|
||||
allowClear
|
||||
v-else-if="typeMap.get(itemType) === 'object'"
|
||||
v-model:value="myValue"
|
||||
@change='inputChange'
|
||||
>
|
||||
<template #addonAfter>
|
||||
<AIcon type="FormOutlined" @click="modalVis = true" />
|
||||
|
@ -60,6 +72,7 @@
|
|||
type="text"
|
||||
v-model:value="myValue"
|
||||
style="width: 100%"
|
||||
@change='inputChange'
|
||||
/>
|
||||
|
||||
<!-- 代码编辑器弹窗 -->
|
||||
|
@ -92,6 +105,7 @@ import { FILE_UPLOAD } from '@/api/comm';
|
|||
|
||||
type Emits = {
|
||||
(e: 'update:modelValue', data: string | number | boolean): void;
|
||||
(e: 'change', data: any, item?: any): void;
|
||||
};
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
|
@ -169,6 +183,23 @@ const handleFileChange = (info: UploadChangeParam<UploadFile<any>>) => {
|
|||
emit('update:modelValue', url);
|
||||
}
|
||||
};
|
||||
|
||||
const selectChange = (e: string, option: any) => {
|
||||
emit('change', e, option)
|
||||
}
|
||||
|
||||
const timeChange = (e: any) => {
|
||||
emit('change', e)
|
||||
}
|
||||
|
||||
const inputChange = (e: any) => {
|
||||
emit('change', e.target.value)
|
||||
}
|
||||
|
||||
const dateChange = (e: any) => {
|
||||
emit('change', e)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { App } from 'vue'
|
||||
import AIcon from './AIcon'
|
||||
// import AIcon from './AIcon'
|
||||
import PermissionButton from './PermissionButton/index.vue'
|
||||
import JTable from './Table/index'
|
||||
import TitleComponent from "./TitleComponent/index.vue";
|
||||
|
@ -10,7 +10,7 @@ import NormalUpload from './NormalUpload/index.vue'
|
|||
import FileFormat from './FileFormat/index.vue'
|
||||
import JProUpload from './JUpload/index.vue'
|
||||
import { BasicLayoutPage, BlankLayoutPage } from './Layout'
|
||||
import { PageContainer } from 'jetlinks-ui-components'
|
||||
import { PageContainer, AIcon } from 'jetlinks-ui-components'
|
||||
import Ellipsis from './Ellipsis/index.vue'
|
||||
import JEmpty from './Empty/index.vue'
|
||||
import AMapComponent from './AMapComponent/index.vue'
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
<template>
|
||||
<j-dropdown class='scene-select' trigger='click'>
|
||||
<div :class='dropdownButtonClass'>
|
||||
<span :style='LabelStyle'>
|
||||
{{ label }}
|
||||
</span>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<template v-if='options.length'>
|
||||
<j-menu v-if='component === "select"' @click='menuSelect'>
|
||||
<j-menu-item v-for='item in options' :key='item.value'>{{ item.label }}</j-menu-item>
|
||||
</j-menu>
|
||||
<j-tree
|
||||
:selectedKeys='selectValue ? [selectValue] : []'
|
||||
:treeData='options'
|
||||
@select='treeSelect'
|
||||
/>
|
||||
</template>
|
||||
<div class='scene-select-empty' v-else>
|
||||
<j-empty />
|
||||
</div>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='DropdownButton'>
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
type LabelType = string | number | undefined
|
||||
|
||||
type DropdownButtonOptions = {
|
||||
label: string;
|
||||
value: string;
|
||||
children?: DropdownButtonOptions[];
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: string | number): void
|
||||
(e: 'select', data: DropdownButtonOptions | undefined ): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: undefined
|
||||
},
|
||||
options: {
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'column' // 'column' | 'termType' | 'value' | 'type'
|
||||
},
|
||||
component: {
|
||||
type: String,
|
||||
default: 'select' // 'select' | 'treeSelect'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const label = ref<LabelType>(props.placeholder)
|
||||
const selectValue = ref(props.value)
|
||||
const flatMapTree = new Map()
|
||||
|
||||
const LabelStyle = computed(() => {
|
||||
return {
|
||||
color: selectValue.value ? '#' : '#'
|
||||
}
|
||||
})
|
||||
|
||||
const dropdownButtonClass = computed(() => ({
|
||||
'dropdown-button': true,
|
||||
'column': props.type === 'column',
|
||||
'termType': props.type === 'termType',
|
||||
'value': props.type === 'value',
|
||||
'type': props.type === 'type',
|
||||
}))
|
||||
|
||||
const getOption = (key?: string | number): DropdownButtonOptions | undefined => {
|
||||
let option
|
||||
for(let i = props.options.length - 1; i >= 0; i --) {
|
||||
const cacheOption = props.options[i]
|
||||
if (cacheOption.value === key) {
|
||||
option = {
|
||||
...cacheOption
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return option
|
||||
}
|
||||
|
||||
const treeSelect = () => {
|
||||
|
||||
}
|
||||
|
||||
const menuSelect = (v: any) => {
|
||||
const option = getOption(props.value)
|
||||
emit('update:value', v.key)
|
||||
emit('select', option)
|
||||
}
|
||||
|
||||
watch([props.options, props.value], () => {
|
||||
const option = getOption(props.value)
|
||||
console.log(props.value)
|
||||
if (option) {
|
||||
label.value = option.label
|
||||
} else {
|
||||
label.value = props.value || props.placeholder
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
.dropdown-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.column {
|
||||
color: #00a4fe;
|
||||
background-color: rgba(154, 219, 255, 0.3);
|
||||
border-color: rgba(0, 164, 254, 0.3);
|
||||
}
|
||||
|
||||
.termType {
|
||||
color: #2f54eb;
|
||||
background-color: rgba(163, 202, 255, 0.3);
|
||||
border-color: rgba(47, 84, 235, 0.3);
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #692ca7;
|
||||
background-color: rgba(188, 125, 238, 0.1);
|
||||
border-color: rgba(188, 125, 238, 0.5);
|
||||
}
|
||||
|
||||
.type {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<j-dropdown class='scene-select' trigger='click'>
|
||||
<div :class='dropdownButtonClass'>
|
||||
<AIcon v-if='!!icon' :type='icon' />
|
||||
{{ label }}
|
||||
</div>
|
||||
<template #overlay>
|
||||
<div class='scene-select-content'>
|
||||
<template v-if='options.length'>
|
||||
<drop-menus
|
||||
v-if='component === "select"'
|
||||
:value='selectValue'
|
||||
:options='options'
|
||||
@click='menuSelect'
|
||||
/>
|
||||
<DropdownTimePicker
|
||||
v-else-if='["date","time"].includes(component)'
|
||||
:type='component'
|
||||
@change='timeSelect'
|
||||
/>
|
||||
<div v-else>
|
||||
<j-tree
|
||||
:selectedKeys='selectValue ? [selectValue] : []'
|
||||
:treeData='options'
|
||||
@select='treeSelect'
|
||||
:height='450'
|
||||
:virtual='true'
|
||||
>
|
||||
<template #title="{ name, description }">
|
||||
<j-space>
|
||||
{{ name }}
|
||||
<span v-if='description' class='tree-title-description'>{{ description }}</span>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-tree>
|
||||
</div>
|
||||
</template>
|
||||
<div class='scene-select-empty' v-else>
|
||||
<j-empty />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='DropdownButton'>
|
||||
import type { PropType } from 'vue'
|
||||
import DropMenus from './Menus.vue'
|
||||
import DropdownTimePicker from './Time.vue'
|
||||
import { getOption } from './util'
|
||||
import type { DropdownButtonOptions } from './util'
|
||||
|
||||
type LabelType = string | number | boolean | undefined
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: string | number): void
|
||||
(e: 'select', data: DropdownButtonOptions | string | undefined ): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Boolean],
|
||||
default: undefined
|
||||
},
|
||||
valueName: {
|
||||
type: String,
|
||||
default: 'value'
|
||||
},
|
||||
labelName: {
|
||||
type: String,
|
||||
default: 'label'
|
||||
},
|
||||
options: {
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'column' // 'column' | 'termType' | 'value' | 'type'
|
||||
},
|
||||
component: {
|
||||
type: String,
|
||||
default: 'select' // 'select' | 'treeSelect'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const label = ref<LabelType>(props.placeholder)
|
||||
const selectValue = ref(props.value)
|
||||
const flatMapTree = new Map()
|
||||
|
||||
const LabelStyle = computed(() => {
|
||||
return {
|
||||
color: selectValue.value ? '#' : '#'
|
||||
}
|
||||
})
|
||||
|
||||
const dropdownButtonClass = computed(() => ({
|
||||
'dropdown-button': true,
|
||||
'column': props.type === 'column',
|
||||
'termType': props.type === 'termType',
|
||||
'value': props.type === 'value',
|
||||
'type': props.type === 'type',
|
||||
}))
|
||||
|
||||
const treeSelect = (v: any) => {
|
||||
|
||||
}
|
||||
|
||||
const timeSelect = (v: string) => {
|
||||
emit('update:value', v)
|
||||
emit('select', v)
|
||||
}
|
||||
|
||||
const menuSelect = (v: any) => {
|
||||
const option = getOption(props.options, props.value, props.valueName)
|
||||
emit('update:value', v.key)
|
||||
emit('select', option)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
const option = getOption(props.options, props.value, props.valueName)
|
||||
if (option && Object.keys(option).length) {
|
||||
label.value = option[props.labelName] || option.name
|
||||
} else {
|
||||
label.value = props.value || props.placeholder
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
@import './index.less';
|
||||
</style>
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<j-menu class='scene-dropdown-menus' @click='click' :selectedKeys='[myValue]'>
|
||||
<j-menu-item v-for='item in myOptions' :key='item.value' :title='item.label'>
|
||||
{{ item.label }}
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='DropdownMenus'>
|
||||
import { isBoolean } from 'lodash-es'
|
||||
import { getOption } from '../DropdownButton/util'
|
||||
|
||||
type ValueType = string| number | boolean
|
||||
type Emits = {
|
||||
(e: 'update:value', value: ValueType): void
|
||||
(e: 'click', data: any): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: [String, Number, Boolean],
|
||||
default: undefined
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const myOptions = computed(() => {
|
||||
return props.options.map((item: any) => {
|
||||
let _label = item.label || item.name
|
||||
if (isBoolean(item.value)) {
|
||||
_label = item.value === true ? '是' : '否'
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
label: _label,
|
||||
value: item.value || item.id,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const myValue = ref(props.value)
|
||||
|
||||
const click = (e: any) => {
|
||||
const option = getOption(myOptions.value, e.key)
|
||||
myValue.value = e.key
|
||||
emit('update:value', e.key)
|
||||
emit('click', {
|
||||
key: e.key,
|
||||
...option
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
.scene-dropdown-menus {
|
||||
border: 0px;
|
||||
|
||||
:deep(.ant-menu-item){
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 4px;
|
||||
margin: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: @item-hover-bg;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
&.ant-menu-item-selected {
|
||||
background-color: @primary-1;
|
||||
color: @text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div class='dropdown-time-picker'>
|
||||
<j-time-picker
|
||||
v-if='type === "time"'
|
||||
open
|
||||
class='manual-time-picker'
|
||||
v-model:value='myValue'
|
||||
:format='myFormat'
|
||||
:valueFormat='myFormat'
|
||||
:getPopupContainer='getPopupContainer'
|
||||
popupClassName='manual-time-picker-popup'
|
||||
@change='change'
|
||||
/>
|
||||
<j-date-picker
|
||||
v-else
|
||||
open
|
||||
class='manual-time-picker'
|
||||
v-model:value='myValue'
|
||||
:format='myFormat'
|
||||
:valueFormat='myFormat'
|
||||
:getPopupContainer='getPopupContainer'
|
||||
@change='change'
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='DropdownTime'>
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', value: string) : void
|
||||
(e: 'change', value: string) : void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'time' // time | date
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
const myFormat = props.format || ( props.type === 'time' ? 'HH:mm:ss' : 'YYYY-MM-DD HH:mm:ss')
|
||||
const myValue = ref(props.value || dayjs(new Date()).format(myFormat))
|
||||
|
||||
const getPopupContainer = (trigger: HTMLElement) => {
|
||||
return trigger?.parentNode || document.body
|
||||
}
|
||||
|
||||
const change = (e: string) => {
|
||||
myValue.value = e
|
||||
emit('update:value', e)
|
||||
emit('change', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less'>
|
||||
.dropdown-time-picker {
|
||||
>div{
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.manual-time-picker{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-picker-dropdown {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
.ant-picker-panel {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
|
||||
.ant-picker-panel-container {
|
||||
box-shadow: unset;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,44 @@
|
|||
.dropdown-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.scene-select-content {
|
||||
position: relative;
|
||||
min-width: 220px;
|
||||
padding: 4px;
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;
|
||||
}
|
||||
|
||||
.column {
|
||||
color: #00a4fe;
|
||||
background-color: rgba(154, 219, 255, 0.3);
|
||||
border-color: rgba(0, 164, 254, 0.3);
|
||||
}
|
||||
|
||||
.termType {
|
||||
color: #2f54eb;
|
||||
background-color: rgba(163, 202, 255, 0.3);
|
||||
border-color: rgba(47, 84, 235, 0.3);
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #692ca7;
|
||||
background-color: rgba(188, 125, 238, 0.1);
|
||||
border-color: rgba(188, 125, 238, 0.5);
|
||||
}
|
||||
|
||||
.type {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.tree-title-description {
|
||||
padding-left: 5px;
|
||||
color: grey;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import Dropdown from './DropdownButton.vue'
|
||||
import DropdownMenus from './Menus.vue'
|
||||
import DropdownTimePicker from './Time.vue'
|
||||
|
||||
export default Dropdown
|
||||
|
||||
export {
|
||||
DropdownMenus, DropdownTimePicker
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
export type DropdownButtonOptions = {
|
||||
label: string;
|
||||
value: string;
|
||||
children?: DropdownButtonOptions[];
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export const getComponent = (type: string): string => {
|
||||
switch (type) {
|
||||
case 'int':
|
||||
case 'long':
|
||||
case 'float':
|
||||
case 'double':
|
||||
return 'number'
|
||||
case 'metric':
|
||||
case 'enum':
|
||||
case 'boolean':
|
||||
return 'menu'
|
||||
case 'date':
|
||||
return 'date'
|
||||
case 'tree':
|
||||
return 'tree'
|
||||
default:
|
||||
return 'input'
|
||||
}
|
||||
}
|
||||
|
||||
export const getOption = (data: any[], value?: string | number | boolean, key: string = 'name'): DropdownButtonOptions | any => {
|
||||
let option = {}
|
||||
if (!value) return option
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i]
|
||||
if (item[key] === value) {
|
||||
option = data[i]
|
||||
break
|
||||
} else if (item.children && item.children.length){
|
||||
option = getOption(item.children, value, key)
|
||||
if (option) break
|
||||
}
|
||||
}
|
||||
return option
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ParamsDropdown'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<ParamsDropdown
|
||||
v-model:value='myValue[0]'
|
||||
v-model:source='mySource'
|
||||
:options='options'
|
||||
:icon='icon'
|
||||
:placeholder='placeholder'
|
||||
:tabs-options='tabsOptions'
|
||||
@select='onSelect'
|
||||
/>
|
||||
<ParamsDropdown
|
||||
v-model:value='myValue[1]'
|
||||
v-model:source='mySource'
|
||||
:icon='icon'
|
||||
:placeholder='placeholder'
|
||||
:tabs-options='tabsOptions'
|
||||
:options='options'
|
||||
@select='onSelect'
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='DoubleParamsDropdown'>
|
||||
import ParamsDropdown from './index.vue'
|
||||
import { defaultSetting, ValueType } from './typings'
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: ValueType): void
|
||||
(e: 'update:source', data: string): void
|
||||
(e: 'select', data: any): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
...defaultSetting
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const myValue = ref<ValueType>(props.value)
|
||||
const mySource = ref<string>(props.source)
|
||||
|
||||
const onSelect = () => {
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,8 @@
|
|||
import ParamsDropdown from './index.vue'
|
||||
import DoubleParamsDropdown from './Double.vue'
|
||||
|
||||
export default ParamsDropdown
|
||||
|
||||
export {
|
||||
DoubleParamsDropdown
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<j-dropdown
|
||||
class='scene-select-value'
|
||||
trigger='click'
|
||||
v-model:visible='visible'
|
||||
@visibleChange='visibleChange'
|
||||
>
|
||||
<div class='dropdown-button value' @click.prevent='visible = true'>
|
||||
<AIcon v-if='!!icon' :type='icon' />
|
||||
{{ label }}
|
||||
</div>
|
||||
<template #overlay>
|
||||
<div class='scene-select-content'>
|
||||
<j-tabs
|
||||
@change='tabsChange'
|
||||
v-model:activeKey='mySource'
|
||||
>
|
||||
<j-tab-pane v-for='item in tabsOptions' :tab='item.label' :key='item.key'>
|
||||
<div class='select-box-content'>
|
||||
<DropdownTimePicker
|
||||
v-if='["time","date"].includes(item.component)'
|
||||
:type='item.component'
|
||||
v-model:value='myValue'
|
||||
@change='timeChange'
|
||||
/>
|
||||
<DropdownMenus
|
||||
v-if='["metric","enum", "boolean"].includes(item.component)'
|
||||
:options='options'
|
||||
@change='onSelect'
|
||||
/>
|
||||
<ValueItem
|
||||
v-else-if='valueItemKey.includes(item.component)'
|
||||
v-model:modelValue='myValue'
|
||||
:itemType='getComponent(item.component)'
|
||||
:options='options'
|
||||
@change='valueItemChange'
|
||||
/>
|
||||
<j-tree
|
||||
v-else
|
||||
:selectedKeys='myValue ? [myValue] : []'
|
||||
:treeData='options'
|
||||
@select='treeSelect'
|
||||
:height='450'
|
||||
:virtual='true'
|
||||
>
|
||||
<template #title="{ name, description }">
|
||||
<j-space>
|
||||
{{ name }}
|
||||
<span v-if='description' class='tree-title-description'>{{ description }}</span>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-tree>
|
||||
</div>
|
||||
</j-tab-pane>
|
||||
</j-tabs>
|
||||
</div>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup name='ParamsDropdown'>
|
||||
import ValueItem from '@/components/ValueItem/index.vue'
|
||||
import type { ValueType } from './typings'
|
||||
import { defaultSetting } from './typings'
|
||||
import { DropdownMenus, DropdownTimePicker} from '../DropdownButton'
|
||||
import { getComponent, getOption } from '../DropdownButton/util'
|
||||
|
||||
const valueItemKey = ['int', 'int','long','float','double','string', 'password']
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: ValueType): void
|
||||
(e: 'update:source', data: string): void
|
||||
(e: 'select', data: any): void
|
||||
(e: 'tabChange', data: any): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
...defaultSetting
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const myValue = ref<ValueType>(props.value)
|
||||
const mySource = ref<string>(props.source)
|
||||
const label = ref<any>(props.placeholder)
|
||||
const visible = ref(false)
|
||||
|
||||
nextTick(() => {
|
||||
mySource.value = props.source
|
||||
myValue.value = props.value
|
||||
})
|
||||
|
||||
const tabsChange = (e: string) => {
|
||||
mySource.value = e
|
||||
myValue.value = undefined
|
||||
}
|
||||
|
||||
const updateValue = () => {
|
||||
emit('update:source', mySource.value)
|
||||
emit('update:value', myValue.value)
|
||||
}
|
||||
|
||||
const treeSelect = (e: any) => {
|
||||
console.log('treeSelect', e)
|
||||
visible.value = false
|
||||
label.value = e.fullname || e.name
|
||||
emit('update:value', e.id)
|
||||
emit('select', e)
|
||||
}
|
||||
|
||||
const valueItemChange = (e: string) => {
|
||||
console.log('valueItemSelect', e)
|
||||
label.value = e
|
||||
emit('update:value', e)
|
||||
emit('select', e)
|
||||
}
|
||||
|
||||
const sonSelect = (e: string, option: any) => {
|
||||
visible.value = false
|
||||
label.value = option.label
|
||||
emit('update:value', e)
|
||||
emit('select', e)
|
||||
}
|
||||
|
||||
const timeChange = (e: any) => {
|
||||
label.value = e
|
||||
visible.value = false
|
||||
emit('update:value', e)
|
||||
emit('select', e)
|
||||
}
|
||||
|
||||
const visibleChange = (v: boolean) => {
|
||||
visible.value = v
|
||||
}
|
||||
|
||||
watch([props.options, props.value], () => {
|
||||
const option = getOption(props.options, props.value as string, props.valueName) // 回显label值
|
||||
if (option && Object.keys(option).length) {
|
||||
label.value = option[props.labelName] || option.name
|
||||
} else {
|
||||
label.value = props.value || props.placeholder
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
@import '../DropdownButton/index.less';
|
||||
.manual-time-picker {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: 0;
|
||||
border: none;
|
||||
visibility: hidden;
|
||||
:deep(.ant-picker-input) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,58 @@
|
|||
import type { PropType } from 'vue'
|
||||
|
||||
export type LabelType = string | number | undefined
|
||||
|
||||
export type DropdownButtonOptions = {
|
||||
label: string;
|
||||
value: string;
|
||||
children?: DropdownButtonOptions[];
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export type TabsOption = {
|
||||
label: string;
|
||||
key: string;
|
||||
component: string,
|
||||
options: DropdownButtonOptions[]
|
||||
}
|
||||
type ValueArrayType = [string, number]
|
||||
export type ValueType = string | number | undefined | ValueArrayType
|
||||
|
||||
export const defaultSetting = {
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Array] as PropType<ValueType>,
|
||||
default: undefined
|
||||
},
|
||||
valueName: {
|
||||
type: String,
|
||||
default: 'value'
|
||||
},
|
||||
labelName: {
|
||||
type: String,
|
||||
default: 'label'
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
default: 'fixed'
|
||||
},
|
||||
options: {
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
metricOptions: { // 指标值
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
tabsOptions: {
|
||||
type: Array as PropType<Array<TabsOption>>,
|
||||
default: () => []
|
||||
}
|
||||
}
|
|
@ -16,8 +16,11 @@
|
|||
@mouseout='mouseout'
|
||||
>
|
||||
<DropdownButton
|
||||
:options='options'
|
||||
:options='columnOptions'
|
||||
icon='icon-zhihangdongzuoxie-1'
|
||||
type='column'
|
||||
value-name='column'
|
||||
label-name='fullName'
|
||||
placeholder='请选择参数'
|
||||
v-model:value='paramsValue.column'
|
||||
component='treeSelect'
|
||||
|
@ -26,18 +29,41 @@
|
|||
<DropdownButton
|
||||
:options='termTypeOptions'
|
||||
type="termType"
|
||||
value-name='id'
|
||||
label-name='name'
|
||||
placeholder="操作符"
|
||||
v-model:value='paramsValue.termsType'
|
||||
v-model:value='paramsValue.termType'
|
||||
@select='termsTypeSelect'
|
||||
/>
|
||||
<termplate v-if='showDouble'>
|
||||
|
||||
</termplate>
|
||||
<DoubleParamsDropdown
|
||||
v-if='showDouble'
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:tabsOptions='[
|
||||
{ label: "手动输入", component: "input", key: "fixed" },
|
||||
{ label: "指标值", component: "time", key: "manual" }
|
||||
]'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
/>
|
||||
<ParamsDropdown
|
||||
v-else
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:tabsOptions='[
|
||||
{ label: "手动输入", component: "time", key: "fixed" },
|
||||
{ label: "指标值", component: "input", key: "manual" },
|
||||
]'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
/>
|
||||
<j-popconfirm title='确认删除?' @confirm='onDelete'>
|
||||
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
|
||||
</j-popconfirm>
|
||||
</div>
|
||||
<div class='term-add' @click.stop='termAdd'>
|
||||
<div class='term-add' @click.stop='termAdd' v-if='isLast'>
|
||||
<div class='terms-content'>
|
||||
<AIcon type='PlusOutlined' style='font-size: 12px' />
|
||||
</div>
|
||||
|
@ -48,7 +74,9 @@
|
|||
<script setup lang='ts' name='ParamsItem'>
|
||||
import type { PropType } from 'vue'
|
||||
import type { TermsType } from '@/views/rule-engine/Scene/typings'
|
||||
import DropdownButton from '../DropdownButton.vue'
|
||||
import DropdownButton from '../DropdownButton'
|
||||
import { getOption } from '../DropdownButton/util'
|
||||
import ParamsDropdown, { DoubleParamsDropdown } from '../ParamsDropdown'
|
||||
import { inject } from 'vue'
|
||||
import { ContextKey } from './util'
|
||||
|
||||
|
@ -70,32 +98,33 @@ const props = defineProps({
|
|||
default: () => ({
|
||||
column: '',
|
||||
type: '',
|
||||
termsType: undefined,
|
||||
value: undefined
|
||||
termType: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const paramsValue = reactive<TermsType>({
|
||||
column: '',
|
||||
type: '',
|
||||
termType: undefined,
|
||||
value: undefined
|
||||
column: props.value.column,
|
||||
type: props.value.type,
|
||||
termType: props.value.termType,
|
||||
value: props.value.value
|
||||
})
|
||||
|
||||
const showDelete = ref(false)
|
||||
const columnOptions = inject(ContextKey)
|
||||
|
||||
const options = computed(() => {
|
||||
function handleOptions() {
|
||||
|
||||
}
|
||||
|
||||
return []
|
||||
})
|
||||
const columnOptions: any = inject(ContextKey)
|
||||
const options = ref<any>([])
|
||||
|
||||
const termTypeOptions = computed(() => {
|
||||
const option = getOption(columnOptions.value, paramsValue.column, 'column')
|
||||
return option && Object.keys(option).length ? option.termTypes : []
|
||||
})
|
||||
|
||||
const tabsOptions = computed(() => {
|
||||
// 获取当前value对应的option
|
||||
return []
|
||||
})
|
||||
|
||||
|
@ -131,7 +160,11 @@ const onDelete = () => {
|
|||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const valueOptions = computed(() => {
|
||||
return []
|
||||
})
|
||||
|
||||
nextTick(() => {
|
||||
Object.assign(paramsValue, props.value)
|
||||
})
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ const sceneStore = useSceneStore()
|
|||
const { data } = storeToRefs(sceneStore)
|
||||
|
||||
const open = ref(false)
|
||||
const columnOptions = ref<any[]>([])
|
||||
const columnOptions = ref<any>([])
|
||||
|
||||
|
||||
provide(ContextKey, columnOptions)
|
||||
|
||||
|
@ -80,7 +81,7 @@ const queryColumn = (dataModel: FormModelType) => {
|
|||
const cloneDevice = cloneDeep(dataModel)
|
||||
cloneDevice.branches = cloneDevice.branches?.filter(item => !!item)
|
||||
getParseTerm(cloneDevice).then(res => {
|
||||
columnOptions.value = res as any
|
||||
columnOptions.value = res.result
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -89,12 +90,12 @@ const addBranches = () => {
|
|||
}
|
||||
|
||||
const branchesDelete = (index: number) => {
|
||||
if ((data as FormModelType).branches?.length === 2) {
|
||||
(data as FormModelType).branches?.splice(index, 1, null as any)
|
||||
if (data.value.branches?.length === 2) {
|
||||
data.value.branches?.splice(index, 1, null as any)
|
||||
} else {
|
||||
(data as FormModelType).branches?.splice(index, 1)
|
||||
data.value.branches?.splice(index, 1)
|
||||
}
|
||||
(data as FormModelType).options?.when?.splice(index, 1)
|
||||
data.value.options?.when?.splice(index, 1)
|
||||
}
|
||||
|
||||
const branchesDeleteAll = () => {
|
||||
|
@ -102,15 +103,16 @@ const branchesDeleteAll = () => {
|
|||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if ((data as FormModelType).trigger?.device) {
|
||||
queryColumn((data as FormModelType))
|
||||
console.log(data.value.trigger, data.value.trigger?.device)
|
||||
if (data.value.trigger?.device) {
|
||||
queryColumn(data.value)
|
||||
}
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
open.value = !(
|
||||
(data as FormModelType).branches &&
|
||||
(data as FormModelType).branches?.length === 1
|
||||
data.value.branches &&
|
||||
data.value.branches?.length === 1
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<script setup lang='ts' name='TermsItem'>
|
||||
import type { PropType } from 'vue'
|
||||
import type { TermsType } from '@/views/rule-engine/Scene/typings'
|
||||
import DropdownButton from '../DropdownButton.vue'
|
||||
import DropdownButton from '../DropdownButton'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from 'store/scene'
|
||||
import ParamsItem from './ParamsItem.vue'
|
||||
|
@ -86,14 +86,12 @@ const props = defineProps({
|
|||
const showDelete = ref(false)
|
||||
|
||||
const mouseover = () => {
|
||||
console.log(props.whenName)
|
||||
if (props.whenName !== 0){
|
||||
showDelete.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const mouseout = () => {
|
||||
console.log(props.whenName)
|
||||
if (props.whenName !== 0){
|
||||
showDelete.value = false
|
||||
}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
export const ContextKey = 'columnOptions'
|
||||
|
||||
export const ContextKey = 'columnOptions'
|
|
@ -50,7 +50,6 @@ export default defineConfig(({ mode}) => {
|
|||
},
|
||||
},
|
||||
plugins: [
|
||||
|
||||
vue(),
|
||||
monacoEditorPlugin({}),
|
||||
vueJsx(),
|
||||
|
|
Loading…
Reference in New Issue