fix: 场景联动消息通知动作只有微信通知需要校验收信人、收信人部门、收信人标签必填其中一个;用户没有任何菜单跳转问题

* fix: 场景联动条件修改

* fix: 用户没有任何菜单跳转问题

* fix: 新增分组名为空问题

* fix: 场景联动消息通知动作只有微信通知需要校验收信人、收信人部门、收信人标签必填其中一个

* fix: 隐藏运行状态向前翻多页按钮
This commit is contained in:
XieYongHong 2024-03-12 18:57:05 +08:00 committed by GitHub
parent fd37264925
commit 4600fcb4d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 919 additions and 715 deletions

View File

@ -607,7 +607,7 @@ export const metadataMapById = (type: 'device' | 'product', productId: string, d
export const getMetadataMapById = (type: 'device' | 'product', productId: string) => server.get(`/device/metadata/mapping/${type}/${productId}`)
export const getInkingDevices = (data: string[]) => server.post('/plugin/mapping/device/_all', data)
export const getInkingDevices = (data: string[],pluginId:any) => server.post(`/plugin/mapping/device/${pluginId}/_all`, data)
export const getProtocolMetadata = (id: string, transport: string) => server.get(`/protocol/${id}/${transport}/metadata`)

View File

@ -123,6 +123,10 @@ export const useMenuStore = defineStore({
const silderMenus = handleSiderMenu(cloneDeep(resultData))
// const { menusData, silderMenus } = filterAsyncRouter(resultData)
handleMenusMap(cloneDeep(menusData), this.handleMenusMapById)
if(!menusData.length){
menusData.push(AccountMenu)
this.handleMenusMapById(AccountMenu)
}
menusData.push({
path: '/',
redirect: menusData[0]?.path,
@ -130,6 +134,7 @@ export const useMenuStore = defineStore({
hideInMenu: true
}
})
// console.log(menusData)
// menusData.push(AccountMenu)
this.siderMenus = silderMenus

View File

@ -11,6 +11,7 @@
<InklingDevice
v-model:value='checkKey'
:accessId='accessId'
:pluginId="pluginId"
/>
</j-modal>
</template>

View File

@ -10,6 +10,7 @@
current: (dataSource?.pageIndex || 0) + 1,
pageSize: dataSource?.pageSize || 12,
showSizeChanger: true,
showLessItems:true,
total: dataSource?.total || 0,
pageSizeOptions: ['12', '24', '48', '96']
}"
@ -196,4 +197,10 @@ const _download = (record: any) => {
:deep(.ant-pagination-item) {
display: none !important;
}
:deep(.ant-pagination-jump-next){
display: none !important;
}
:deep(.ant-pagination-jump-prev){
display: none !important;
}
</style>

View File

@ -32,7 +32,7 @@
</div>
<div v-else>
<File v-if='importData.type ==="file"' :product='importData.productId' />
<Plugin v-else :accessId='productDetail.accessId' @change='pluginChange'/>
<Plugin v-else :accessId='productDetail.accessId' @change='pluginChange'/>
</div>
</div>
<template #footer>

View File

@ -19,7 +19,7 @@
selectedRowKeys: _selectedRowKeys,
onSelect: onSelectChange,
onSelectAll: selectAll,
onSelectNone: ()=>_selectedRowKeys = []
onSelectNone: () => (_selectedRowKeys = []),
}
: false
"
@ -175,7 +175,12 @@
/>
</template>
<template #content>
<Ellipsis style="width: calc(100% - 100px); margin-bottom: 18px;">
<Ellipsis
style="
width: calc(100% - 100px);
margin-bottom: 18px;
"
>
<span style="font-size: 16px; font-weight: 600">
{{ slotProps.name }}
</span>
@ -526,13 +531,13 @@ const columns = [
_list.push({
...item,
id: JSON.stringify({
assetType: 'device',
targets: [
{
type: 'org',
id: item.id,
},
],
assetType: 'device',
targets: [
{
type: 'org',
id: item.id,
},
],
}),
});
});
@ -608,7 +613,7 @@ const handleParams = (config: Record<string, any>) => {
if (Object.keys(_terms).length) {
const url = new URLSearchParams();
Object.keys(_terms).forEach((key) => {
console.log(_terms[key])
console.log(_terms[key]);
url.append(key, _terms[key]);
});
return url.toString();
@ -721,7 +726,7 @@ const getActions = (
return actions;
};
const onSelectChange = (item: any,state: boolean) => {
const onSelectChange = (item: any, state: boolean) => {
const arr = new Set(_selectedRowKeys.value);
// console.log(item, state);
if (state) {
@ -732,25 +737,24 @@ const onSelectChange = (item: any,state: boolean) => {
_selectedRowKeys.value = [...arr.values()];
};
const selectAll = (selected: Boolean, selectedRows: any,changeRows:any) => {
const selectAll = (selected: Boolean, selectedRows: any, changeRows: any) => {
if (selected) {
changeRows.map((i: any) => {
if (!_selectedRowKeys.value.includes(i.id)) {
_selectedRowKeys.value.push(i.id)
}
})
} else {
const arr = changeRows.map((item: any) => item.id)
const _ids: string[] = [];
_selectedRowKeys.value.map((i: any) => {
if (!arr.includes(i)) {
_ids.push(i)
}
})
_selectedRowKeys.value = _ids
}
}
changeRows.map((i: any) => {
if (!_selectedRowKeys.value.includes(i.id)) {
_selectedRowKeys.value.push(i.id);
}
});
} else {
const arr = changeRows.map((item: any) => item.id);
const _ids: string[] = [];
_selectedRowKeys.value.map((i: any) => {
if (!arr.includes(i)) {
_ids.push(i);
}
});
_selectedRowKeys.value = _ids;
}
};
const handleClick = (dt: any) => {
if (isCheck.value) {
@ -770,17 +774,17 @@ const onCheckChange = () => {
};
const handleGetParams = (p: any) => {
p?.terms.map((a: any) => {
return a.terms.map((b: any) => {
if (b.column.includes('$product-info')) {
b.column = 'productId'
b.termType = 'product-info'
}
return b
})
})
return p
}
p?.terms.map((a: any) => {
return a.terms.map((b: any) => {
if (b.column.includes('$product-info')) {
b.column = 'productId';
b.termType = 'product-info';
}
return b;
});
});
return p;
};
const activeAllDevice = () => {
type.value = 'active';
@ -925,30 +929,47 @@ const saveBtn = () => {
instanceRef.value?.reload();
};
const dealSearchValue = (item: any) => {
let value: any = '';
console.log(item);
item.value.forEach((i: any, index: number) => {
console.log(i);
if (index > 0) {
value += ',' + i.slice((item.column + ' is ').length);
} else {
value +=
item.column + ' in ' + i.slice((item.column + ' is ').length);
}
});
return value;
};
const handleSearch = (_params: any) => {
// params.value = _params;
const newParams = (_params?.terms as any[])?.map((item1) => {
item1.terms = item1.terms.map((item2: any) => {
if (item2.column === 'id$dim-assets') {
if (item2.termType === 'not') {
const oldValue = JSON.parse(item2.value)
oldValue.not = true
item2.value = JSON.stringify(oldValue)
if (item2.column === 'id$dim-assets') {
if (item2.termType === 'not') {
const oldValue = JSON.parse(item2.value);
oldValue.not = true;
item2.value = JSON.stringify(oldValue);
}
delete item2.termType;
}
delete item2.termType
}
if (
if (
item2.column &&
['classifiedId', 'accessId', 'accessProvider'].includes(
item2.column,
)
) {
const oldTermType = item2.termType
delete item2.termType
const oldTermType = item2.termType;
delete item2.termType;
return {
...item2,
column: `productId$product-info$${oldTermType}`,
value: Array.isArray(item2.value)
? dealSearchValue(item2)
: item2.value,
};
}
return item2;

View File

@ -1,361 +1,395 @@
<template>
<div class='inkling-device'>
<j-spin :spinning='spinning'>
<div class='search-box'>
<div class='search-warp'>
<j-advanced-search
v-if='!spinning'
:columns='columns'
type='simple'
@search='handleSearch'
class='device-inkling'
target='device-inkling'
/>
</div>
<div class='multiple' v-if='multiple'>
<j-checkbox @change='checkChange'>全选</j-checkbox>
</div>
</div>
<div class='device-list-warp'>
<j-scrollbar v-if='deviceList.length'>
<j-spin :spinning='deviceSpinning'>
<div class='device-list-items'>
<template v-for='item in deviceList'>
<template v-if='disabledKeys.includes(item.id)'>
<j-tooltip
title='该设备已绑定平台设备'
>
<div
:class='{
"device-list-item": true,
"active": checkKeys.includes(item.id),
"disabled": disabledKeys.includes(item.id)
}'
@click='() => deviceClick(item.id, item)'
>
<div class='item-title'>
<span class="title-name no-tooltip">
{{item.name}}
</span>
<span class="title-id">
({{ item.id }})
</span>
</div>
</div>
</j-tooltip>
</template>
<div
v-else
:class='{
"device-list-item": true,
"active": checkKeys.includes(item.id),
"disabled": disabledKeys.includes(item.id)
}'
@click='() => deviceClick(item.id, item)'
>
<div class='item-title'>
<span class="title-name">
<j-ellipsis>
{{item.name}}
</j-ellipsis>
</span>
<span class="title-id">
<j-ellipsis>
({{ item.id }})
</j-ellipsis>
</span>
</div>
<a-icon
v-if='checkKeys.includes(item.id)'
type='CheckOutlined'
/>
<div class="inkling-device">
<j-spin :spinning="spinning">
<div class="search-box">
<div class="search-warp">
<j-advanced-search
v-if="!spinning"
:columns="columns"
type="simple"
@search="handleSearch"
class="device-inkling"
target="device-inkling"
/>
</div>
<div class="multiple" v-if="multiple">
<j-checkbox @change="checkChange">全选</j-checkbox>
</div>
</template>
</div>
</j-spin>
</j-scrollbar>
<j-empty
v-else
description='暂无数据'
style='padding-top: 24px'
/>
<div class='device-list-pagination'>
<j-pagination
v-if='showPage'
:total='pageData.total'
:current='pageData.pageIndex + 1'
:pageSize='pageData.pageSize'
:show-total='() => {
const minSize = pageData.pageIndex * pageData.pageSize + 1;
const MaxSize = (pageData.pageIndex + 1) * pageData.pageSize;
return `${minSize} - ${MaxSize > pageData.total ? pageData.total : MaxSize } 条/总共 ${pageData.total}`;
}'
@change='pageChange'
/>
</div>
</div>
</j-spin>
</div>
<div class="device-list-warp">
<j-scrollbar v-if="deviceList.length">
<j-spin :spinning="deviceSpinning">
<div class="device-list-items">
<template v-for="item in deviceList">
<template v-if="disabledKeys.includes(item.id)">
<j-tooltip title="该设备已绑定平台设备">
<div
:class="{
'device-list-item': true,
active: checkKeys.includes(
item.id,
),
disabled: disabledKeys.includes(
item.id,
),
}"
@click="
() => deviceClick(item.id, item)
"
>
<div class="item-title">
<span
class="title-name no-tooltip"
>
{{ item.name }}
</span>
<span class="title-id">
({{ item.id }})
</span>
</div>
</div>
</j-tooltip>
</template>
<div
v-else
:class="{
'device-list-item': true,
active: checkKeys.includes(item.id),
disabled: disabledKeys.includes(
item.id,
),
}"
@click="() => deviceClick(item.id, item)"
>
<div class="item-title">
<span class="title-name">
<j-ellipsis>
{{ item.name }}
</j-ellipsis>
</span>
<span class="title-id">
<j-ellipsis>
({{ item.id }})
</j-ellipsis>
</span>
</div>
<a-icon
v-if="checkKeys.includes(item.id)"
type="CheckOutlined"
/>
</div>
</template>
</div>
</j-spin>
</j-scrollbar>
<j-empty
v-else
description="暂无数据"
style="padding-top: 24px"
/>
<div class="device-list-pagination">
<j-pagination
v-if="showPage"
:total="pageData.total"
:current="pageData.pageIndex + 1"
:pageSize="pageData.pageSize"
:show-total="
() => {
const minSize =
pageData.pageIndex * pageData.pageSize + 1;
const MaxSize =
(pageData.pageIndex + 1) *
pageData.pageSize;
return `${minSize} - ${
MaxSize > pageData.total
? pageData.total
: MaxSize
} /总共 ${pageData.total} `;
}
"
@change="pageChange"
/>
</div>
</div>
</j-spin>
</div>
</template>
<script setup lang='ts' name='InklingDevice'>
import { getCommandsByAccess, getCommandsDevicesByAccessId } from '@/api/link/accessConfig'
import { getInkingDevices } from '@/api/device/instance'
import { isArray } from 'lodash-es'
<script setup lang="ts" name="InklingDevice">
import {
getCommandsByAccess,
getCommandsDevicesByAccessId,
} from '@/api/link/accessConfig';
import { getInkingDevices } from '@/api/device/instance';
import { isArray } from 'lodash-es';
type Emit = {
(e: 'update:value', data: string | string[]): void
(e: 'change', data: any | any[]): void
}
(e: 'update:value', data: string | string[]): void;
(e: 'change', data: any | any[]): void;
};
const props = defineProps({
value: {
type: [String, Array],
default: undefined
},
accessId: {
type: String,
default: undefined
},
multiple: {
type: Boolean,
default: false
}
})
value: {
type: [String, Array],
default: undefined,
},
accessId: {
type: String,
default: undefined,
},
multiple: {
type: Boolean,
default: false,
},
pluginId: {
type: String,
default: undefined,
},
});
const emit = defineEmits<Emit>()
const emit = defineEmits<Emit>();
const spinning = ref(true)
const deviceSpinning = ref(false)
const deviceList = ref([])
const disabledKeys = ref<string[]>([])
const checkKeys = ref<string[]>([])
const checkCache = ref<Map<string, any>>(new Map())
const showPage = ref(false)
const spinning = ref(true);
const deviceSpinning = ref(false);
const deviceList = ref([]);
const disabledKeys = ref<string[]>([]);
const checkKeys = ref<string[]>([]);
const checkCache = ref<Map<string, any>>(new Map());
const showPage = ref(false);
const pageData = reactive({
pageSize: 10,
pageIndex: 0,
total: 0
})
pageSize: 10,
pageIndex: 0,
total: 0,
});
const params = ref({
terms: []
})
terms: [],
});
const columns = ref([])
const columns = ref([]);
const queryInkingDevices = (data: string[]) => {
return new Promise(async (resolve) => {
if (!data.length) {
resolve(true)
return
}
return new Promise(async (resolve) => {
if (!data.length) {
resolve(true);
return;
}
const res = await getInkingDevices(data)
if (res) {
disabledKeys.value = res.result?.map(item => item.externalId)
}
resolve(true)
})
}
const res = await getInkingDevices(data,props.pluginId);
if (res) {
disabledKeys.value = res.result?.map((item) => item.externalId);
}
resolve(true);
});
};
const getDeviceList = async () => {
const resp = await getCommandsDevicesByAccessId(props.accessId!, {
pageIndex: pageData.pageIndex,
pageSize: pageData.pageSize,
terms: params.value.terms
}).catch(() => ({ success: false }))
if (resp.success) {
await queryInkingDevices(resp.result?.data.map(item => item.id) || [])
deviceList.value = resp.result?.data || []
pageData.total = resp.result?.total || 0
}
}
const resp = await getCommandsDevicesByAccessId(props.accessId!, {
pageIndex: pageData.pageIndex,
pageSize: pageData.pageSize,
terms: params.value.terms,
}).catch(() => ({ success: false }));
if (resp.success) {
await queryInkingDevices(
resp.result?.data.map((item) => item.id) || [],
);
deviceList.value = resp.result?.data || [];
pageData.total = resp.result?.total || 0;
}
};
const checkChange = (e: any) => { //
if (e.target.checked) {
const keys = deviceList.value.filter(item => {
//
const type = !checkKeys.value.includes(item.id) && !disabledKeys.value.includes(item.id)
if (type && !checkCache.value.has(item.id)) {
checkCache.value.set(item.id, item)
}
return type
}).map(item => item.id)
checkKeys.value = [...checkKeys.value, ...keys]
emit('update:value', checkKeys.value)
emit('change', [...checkCache.value.values()])
} else {
checkCache.value.clear()
checkKeys.value = []
emit('update:value', [])
emit('change', [])
}
}
const checkChange = (e: any) => {
//
if (e.target.checked) {
const keys = deviceList.value
.filter((item) => {
//
const type =
!checkKeys.value.includes(item.id) &&
!disabledKeys.value.includes(item.id);
if (type && !checkCache.value.has(item.id)) {
checkCache.value.set(item.id, item);
}
return type;
})
.map((item) => item.id);
checkKeys.value = [...checkKeys.value, ...keys];
emit('update:value', checkKeys.value);
emit('change', [...checkCache.value.values()]);
} else {
checkCache.value.clear();
checkKeys.value = [];
emit('update:value', []);
emit('change', []);
}
};
const handleSearch = (p: any) => { //
pageData.pageIndex = 0
params.value = p
getDeviceList()
}
const handleSearch = (p: any) => {
//
pageData.pageIndex = 0;
params.value = p;
getDeviceList();
};
const pageChange = (page: number, pageSize: number) => { //
pageData.pageSize = pageSize
pageData.pageIndex = page - 1
getDeviceList()
}
const pageChange = (page: number, pageSize: number) => {
//
pageData.pageSize = pageSize;
pageData.pageIndex = page - 1;
getDeviceList();
};
const init = async () => {
if (props.accessId) {
const resp = await getCommandsByAccess(props.accessId)
if (resp.success) {
const item = resp.result?.[0]
if (item) {
showPage.value = item.id === 'QueryDevicePage' //
columns.value = item.expands?.terms?.map(t => ({
title: t.name,
dataIndex: t.id,
search: {
type: t.valueType.type
}
}))
}
if (props.accessId) {
const resp = await getCommandsByAccess(props.accessId);
if (resp.success) {
const item = resp.result?.[0];
if (item) {
showPage.value = item.id === 'QueryDevicePage'; //
columns.value = item.expands?.terms?.map((t) => ({
title: t.name,
dataIndex: t.id,
search: {
type: t.valueType.type,
},
}));
}
}
spinning.value = false;
await getDeviceList();
}
spinning.value = false
await getDeviceList()
}
}
};
const deviceClick = (id: string, option: any) => {
if (option.disabled || disabledKeys.value.includes(id)) return
if (option.disabled || disabledKeys.value.includes(id)) return;
const _check = new Set(checkKeys.value)
const _check = new Set(checkKeys.value);
if (props.multiple) { //
if (_check.has(id)) {
_check.delete(id)
checkCache.value.delete(id)
if (props.multiple) {
//
if (_check.has(id)) {
_check.delete(id);
checkCache.value.delete(id);
} else {
checkCache.value.set(id, option);
_check.add(id);
}
checkKeys.value = [..._check.values()];
emit('update:value', checkKeys.value);
emit('change', [...checkCache.value.values()]);
} else {
checkCache.value.set(id, option)
_check.add(id)
checkKeys.value = [id];
emit('update:value', id);
emit('change', option);
}
checkKeys.value = [..._check.values()]
emit('update:value', checkKeys.value)
emit('change', [...checkCache.value.values()])
} else {
checkKeys.value = [id]
emit('update:value', id)
emit('change', option)
}
}
};
watch(() => props.value, (newValue) => {
if (!newValue) {
checkKeys.value = []
return
}
if (isArray(newValue)) {
checkKeys.value = newValue
} else {
checkKeys.value = [newValue as string]
}
}, { immediate: true, deep: true })
watch(
() => props.value,
(newValue) => {
if (!newValue) {
checkKeys.value = [];
return;
}
if (isArray(newValue)) {
checkKeys.value = newValue;
} else {
checkKeys.value = [newValue as string];
}
},
{ immediate: true, deep: true },
);
onMounted(() => {
init()
})
init();
});
</script>
<style scoped lang='less'>
<style scoped lang="less">
.inkling-device {
min-height: 200px;
min-height: 200px;
}
.search-box {
padding-bottom: 24px;
border-bottom: 1px solid #f0f0f0;
display: flex;
margin-bottom: 12px;
gap: 24px;
align-items: center;
padding-bottom: 24px;
border-bottom: 1px solid #f0f0f0;
display: flex;
margin-bottom: 12px;
gap: 24px;
align-items: center;
:deep(.device-inkling) {
padding: 0;
margin: 0;
padding-bottom: 0;
}
:deep(.device-inkling) {
padding: 0;
margin: 0;
padding-bottom: 0;
}
.search-warp {
flex: 1 1 auto;
}
.search-warp {
flex: 1 1 auto;
}
.multiple {
width: 60px;
}
.multiple {
width: 60px;
}
}
.device-list-warp {
.device-list-items {
.device-list-item {
padding: 10px 16px;
color: #4F4F4F;
border-bottom: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
.device-list-items {
.device-list-item {
padding: 10px 16px;
color: #4f4f4f;
border-bottom: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
> .item-title {
display: flex;
min-width: 0;
flex-grow: 1;
gap: 8px;
> .item-title {
display: flex;
min-width: 0;
flex-grow: 1;
gap: 8px;
.title-name {
max-width: 70%;
.title-name {
max-width: 70%;
}
.no-tooltip {
overflow: hidden;
vertical-align: bottom;
cursor: pointer;
display: -webkit-box;
-webkit-box-orient: vertical;
word-break: break-all;
max-height: 380px;
-webkit-line-clamp: 1;
text-overflow: ellipsis;
}
.title-id {
flex: 1 1 auto;
color: #a3a3a3;
}
}
&:hover {
background-color: rgba(47, 84, 235, 0.06);
}
&.active {
background-color: rgba(153, 153, 153, 0.06);
color: @primary-color;
.title-id {
color: @primary-color;
opacity: 0.8;
}
}
&.disabled {
cursor: not-allowed;
background-color: rgba(153, 153, 153, 0.06);
}
}
.no-tooltip {
overflow: hidden;
vertical-align: bottom;
cursor: pointer;
display: -webkit-box;
-webkit-box-orient: vertical;
word-break: break-all;
max-height: 380px;
-webkit-line-clamp: 1;
text-overflow: ellipsis;
}
.title-id {
flex: 1 1 auto;
color: #a3a3a3;
}
}
&:hover {
background-color: rgba(47, 84, 235, 0.06);
}
&.active {
background-color: rgba(153, 153, 153, 0.06);
color: @primary-color;
.title-id {
color: @primary-color;
opacity: .8;
}
}
&.disabled {
cursor: not-allowed;
background-color: rgba(153, 153, 153, 0.06);
}
}
}
.device-list-pagination {
margin-top: 24px;
text-align: right;
}
.device-list-pagination {
margin-top: 24px;
text-align: right;
}
}
</style>

View File

@ -423,7 +423,7 @@ const handleAddClick = async (_data?: any, index?: number) => {
const _addData = await tableRef.value.addItem(newObject, index)
nextTick(()=>{
if(tableContainer.value.classList.value === 'tableContainer'){
if(tableContainer?.value?.classList?.value === 'tableContainer'){
tableContainer.value.classList.remove('tableContainer')
}
})

View File

@ -165,7 +165,7 @@
真实设备的PSK非必填
</j-descriptions-item>
</j-descriptions>
<div>
<div class="overLength">
5CTWing端配置产品/设备/分组级订阅订阅方URL地址请填写 {{
`${origin}/api/ctwing/${randomString()}/notify`
}}此处订阅地址可以在JetLinks平台中配置完成CTWing网关后再填写
@ -565,4 +565,7 @@ watch(
margin: 15px 0;
justify-content: space-between;
}
.overLength{
overflow-wrap: break-word;
}
</style>

View File

@ -213,7 +213,7 @@ const onSave = () =>
const pass = props.variableDefinitions.filter(item => ['user', 'org', 'tag'].includes(getType(item))).some(item => {
return modelRef[item.id]
})
if(!pass) {
if(!pass && props.notify.notifyType === 'weixin') {
onlyMessage('收信人,收信人部门,收信人标签至少填写一个', 'warning')
return reject(false)
}

View File

@ -1,6 +1,7 @@
<template>
<ParamsDropdown
v-model:value='myValue[0]'
v-for="(i,index) in myValue"
v-model:value='myValue[index]'
v-model:source='mySource'
:valueName='valueName'
:labelName='labelName'
@ -9,10 +10,10 @@
:placeholder='placeholder'
:tabs-options='tabsOptions'
:metricOptions='metricOptions'
@select='(v, l) => onSelect(v, l, 0)'
@select='(v, l) => onSelect(v, l, index)'
@tabChange='tabChange'
/>
<ParamsDropdown
<!-- <ParamsDropdown
v-model:value='myValue[1]'
v-model:source='mySource'
:valueName='valueName'
@ -24,7 +25,9 @@
:options='options'
@select='(v, l) => onSelect(v, l,1)'
@tabChange='tabChange'
/>
/> -->
<j-button @click="addDropdown" v-if="['contains_all', 'contains_any', 'not_contains'].includes(props.termType)" class="operation">+</j-button>
<j-button @click="deleteDropdown" v-if="['contains_all', 'contains_any', 'not_contains'].includes(props.termType) && myValue?.length > 2" class="operation">-</j-button>
</template>
<script lang='ts' setup name='DoubleParamsDropdown'>
@ -38,7 +41,10 @@ type Emit = {
}
const props = defineProps({
...defaultSetting
...defaultSetting,
termType:{
type: String,
}
})
const label: Record<number, any> = {
@ -57,6 +63,13 @@ const onSelect = (v: any, _label: string, index: number) => {
emit('select', myValue.value, _label, label)
}
const addDropdown = () =>{
myValue.value.push(undefined)
}
const deleteDropdown = () =>{
myValue.value.pop()
}
const tabChange = (e: string) => {
emit('update:source', e)
}

View File

@ -1,387 +1,505 @@
<template>
<div class='terms-params-item'>
<div v-if='!isFirst' class='term-type-warp'>
<DropdownButton
:options='[
{ label: "并且", value: "and" },
{ label: "或者", value: "or" },
]'
type='type'
v-model:value='paramsValue.type'
@select='typeSelect'
/>
<div class="terms-params-item">
<div v-if="!isFirst" class="term-type-warp">
<DropdownButton
:options="[
{ label: '并且', value: 'and' },
{ label: '或者', value: 'or' },
]"
type="type"
v-model:value="paramsValue.type"
@select="typeSelect"
/>
</div>
<div
class="params-item_button"
@mouseover="mouseover"
@mouseout="mouseout"
>
<DropdownButton
:options="columnOptions"
icon="icon-zhihangdongzuoxie-1"
type="column"
value-name="column"
label-name="fullName"
placeholder="请选择参数"
v-model:value="paramsValue.column"
component="treeSelect"
@select="columnSelect"
/>
<DropdownButton
:options="termTypeOptions"
type="termType"
value-name="id"
label-name="name"
placeholder="操作符"
v-model:value="paramsValue.termType"
@select="termsTypeSelect"
/>
<div v-if="!['notnull','isnull'].includes(paramsValue.termType)">
<DoubleParamsDropdown
v-if="showDouble"
icon="icon-canshu"
placeholder="参数值"
:options="valueOptions"
:metricOptions="metricOption"
:tabsOptions="tabsOptions"
v-model:value="paramsValue.value.value"
v-model:source="paramsValue.value.source"
@select="valueSelect"
/>
<ParamsDropdown
v-else
icon="icon-canshu"
placeholder="参数值"
:options="valueOptions"
:metricOptions="metricOption"
:tabsOptions="tabsOptions"
:metric="paramsValue.value?.metric"
v-model:value="paramsValue.value.value"
v-model:source="paramsValue.value.source"
@select="valueSelect"
/>
</div>
<j-popconfirm
title="确认删除?"
@confirm="onDelete"
:overlayStyle="{ minWidth: '180px' }"
>
<div v-show="showDelete" class="button-delete">
<AIcon type="CloseOutlined" />
</div>
</j-popconfirm>
</div>
<div class="term-add" @click.stop="termAdd" v-if="isLast">
<div class="terms-content">
<AIcon type="PlusOutlined" style="font-size: 12px" />
</div>
</div>
</div>
<div
class='params-item_button'
@mouseover='mouseover'
@mouseout='mouseout'
>
<DropdownButton
:options='columnOptions'
icon='icon-zhihangdongzuoxie-1'
type='column'
value-name='column'
label-name='fullName'
placeholder='请选择参数'
v-model:value='paramsValue.column'
component='treeSelect'
@select='columnSelect'
/>
<DropdownButton
:options='termTypeOptions'
type="termType"
value-name='id'
label-name='name'
placeholder="操作符"
v-model:value='paramsValue.termType'
@select='termsTypeSelect'
/>
<DoubleParamsDropdown
v-if='showDouble'
icon='icon-canshu'
placeholder='参数值'
:options='valueOptions'
:metricOptions='metricOption'
:tabsOptions='tabsOptions'
v-model:value='paramsValue.value.value'
v-model:source='paramsValue.value.source'
@select='valueSelect'
/>
<ParamsDropdown
v-else
icon='icon-canshu'
placeholder='参数值'
:options='valueOptions'
:metricOptions='metricOption'
:tabsOptions='tabsOptions'
:metric='paramsValue.value?.metric'
v-model:value='paramsValue.value.value'
v-model:source='paramsValue.value.source'
@select='valueSelect'
/>
<j-popconfirm title='确认删除?' @confirm='onDelete' :overlayStyle='{minWidth: "180px"}'>
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
</j-popconfirm>
</div>
<div class='term-add' @click.stop='termAdd' v-if='isLast'>
<div class='terms-content'>
<AIcon type='PlusOutlined' style='font-size: 12px' />
</div>
</div>
</div>
</template>
<script setup lang='ts' name='ParamsItem'>
import type { PropType } from 'vue'
import type { TermsType } from '@/views/rule-engine/Scene/typings'
import DropdownButton from '../DropdownButton'
import { getOption } from '../DropdownButton/util'
import ParamsDropdown, { DoubleParamsDropdown } from '../ParamsDropdown'
import {inject, watch} from 'vue'
import { ContextKey, arrayParamsKey, timeTypeKeys } from './util'
import { useSceneStore } from 'store/scene'
<script setup lang="ts" name="ParamsItem">
import type { PropType } from 'vue';
import type { TermsType } from '@/views/rule-engine/Scene/typings';
import DropdownButton from '../DropdownButton';
import { getOption } from '../DropdownButton/util';
import ParamsDropdown, { DoubleParamsDropdown } from '../ParamsDropdown';
import { inject, watch } from 'vue';
import { ContextKey, arrayParamsKey, timeTypeKeys } from './util';
import { useSceneStore } from 'store/scene';
import { storeToRefs } from 'pinia';
import { Form } from 'jetlinks-ui-components'
import {indexOf, isArray, isObject, isString, pick , cloneDeep } from 'lodash-es'
import { Form } from 'jetlinks-ui-components';
import {
indexOf,
isArray,
isObject,
isString,
pick,
cloneDeep,
} from 'lodash-es';
const sceneStore = useSceneStore()
const { data: formModel } = storeToRefs(sceneStore)
const sceneStore = useSceneStore();
const { data: formModel } = storeToRefs(sceneStore);
const formItemContext = Form.useInjectFormItemContext();
type Emit = {
(e: 'update:value', data: TermsType): void
}
(e: 'update:value', data: TermsType): void;
};
type TabsOption = {
label: string;
key: string;
component: string
}
label: string;
key: string;
component: string;
};
const props = defineProps({
isFirst: {
type: Boolean,
default: true
},
isLast: {
type: Boolean,
default: true
},
showDeleteBtn: {
type: Boolean,
default: true
},
name: {
type: Number,
default: 0
},
termsName: {
type: Number,
default: 0
},
branchName: {
type: Number,
default: 0
},
whenName: {
type: Number,
default: 0
},
value: {
type: Object as PropType<TermsType>,
default: () => ({
column: '',
type: '',
termType: 'eq',
value: {
source: 'manual',
value: undefined
}
})
}
})
isFirst: {
type: Boolean,
default: true,
},
isLast: {
type: Boolean,
default: true,
},
showDeleteBtn: {
type: Boolean,
default: true,
},
name: {
type: Number,
default: 0,
},
termsName: {
type: Number,
default: 0,
},
branchName: {
type: Number,
default: 0,
},
whenName: {
type: Number,
default: 0,
},
value: {
type: Object as PropType<TermsType>,
default: () => ({
column: '',
type: '',
termType: 'eq',
value: {
source: 'manual',
value: undefined,
},
}),
},
});
const emit = defineEmits<Emit>()
const emit = defineEmits<Emit>();
const paramsValue = reactive<TermsType>({
column: props.value?.column,
type: props.value?.type,
termType: props.value?.termType,
value: props.value?.value,
metric: undefined
})
column: props.value?.column,
type: props.value?.type,
termType: props.value?.termType,
value: props.value?.value,
metric: undefined,
});
const showDelete = ref(false)
const columnOptions: any = inject(ContextKey) //
const columnType = ref<string>()
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) //
const valueOptions = ref<any[]>([]) //
const metricOption = ref<any[]>([]) // termType
const isMetric = ref<boolean>(false) //
const tabsOptions = ref<Array<TabsOption>>([{ label: '手动输入', key: 'manual', component: 'string' }])
const metricsCacheOption = ref<any[]>([]) //
const showDelete = ref(false);
const columnOptions: any = inject(ContextKey); //
const columnType = ref<string>();
const termTypeOptions = ref<Array<{ id: string; name: string }>>([]); //
const valueOptions = ref<any[]>([]); //
const metricOption = ref<any[]>([]); // termType
const isMetric = ref<boolean>(false); //
const tabsOptions = ref<Array<TabsOption>>([
{ label: '手动输入', key: 'manual', component: 'string' },
]);
const metricsCacheOption = ref<any[]>([]); //
const handOptionByColumn = (option: any) => {
if (option) {
termTypeOptions.value = option.termTypes || []
metricsCacheOption.value = option.metrics?.map((item: any) => ({...item, label: item.name})) || []
tabsOptions.value.length = 1
tabsOptions.value[0].component = option.dataType
columnType.value = option.dataType
if (option.metrics && option.metrics.length) {
if (option) {
termTypeOptions.value = option.termTypes || [];
metricsCacheOption.value =
option.metrics?.map((item: any) => ({
...item,
label: item.name,
})) || [];
tabsOptions.value.length = 1;
tabsOptions.value[0].component = option.dataType;
columnType.value = option.dataType;
if (option.metrics && option.metrics.length) {
tabsOptions.value.push({
label: '指标值',
key: 'metric',
component: 'select',
});
isMetric.value = true;
} else {
isMetric.value = false;
}
tabsOptions.value.push(
{ label: '指标值', key: 'metric', component: 'select' }
)
isMetric.value = true
if (option.dataType === 'boolean') {
// _optionsObject
const _options = option.options || option.others;
if (isObject(_options)) {
const bool = (_options as any)?.bool;
valueOptions.value = [
{ label: bool.falseText, value: String(bool.falseValue) },
{ label: bool.trueText, value: String(bool.trueValue) },
];
} else {
valueOptions.value = option.options?.map((item: any) => ({
...item,
label: item.name,
value: item.id,
})) || [
{ label: '是', value: 'true' },
{ label: '否', value: 'false' },
];
}
} else if (option.dataType === 'enum') {
valueOptions.value =
option.options?.map((item: any) => ({
...item,
label: item.name,
value: item.id,
})) || [];
} else {
valueOptions.value = (option.options || []).map((item: any) => ({
...item,
label: item.name,
value: item.id,
}));
}
} else {
isMetric.value = false
termTypeOptions.value = [];
metricsCacheOption.value = [];
valueOptions.value = [];
}
};
if (option.dataType === 'boolean') {
// _optionsObject
const _options = option.options || option.others
if (isObject(_options)) {
const bool = (_options as any)?.bool
valueOptions.value = [
{ label: bool.falseText, value: String(bool.falseValue)},
{ label: bool.trueText, value: String(bool.trueValue)},
]
} else {
valueOptions.value = option.options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || [
{ label: '是', value: 'true' },
{ label: '否', value: 'false' },
]
}
} else if(option.dataType === 'enum') {
valueOptions.value = option.options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
} else{
valueOptions.value = (option.options || []).map((item: any) => ({ ...item, label: item.name, value: item.id}))
}
} else {
termTypeOptions.value = []
metricsCacheOption.value = []
valueOptions.value = []
}
}
watch(() => JSON.stringify(columnOptions.value), () => {
if (paramsValue.column) {
const option = getOption(columnOptions.value, paramsValue.column, 'column')
const copyValue = props.value
if (option && Object.keys(option).length) {
handOptionByColumn(option)
if (copyValue.error) {
copyValue.error = false
emit('update:value', copyValue)
formItemContext.onFieldChange()
}
} else {
copyValue.error = true
emit('update:value', copyValue)
formItemContext.onFieldChange()
}
}
}, { immediate: true })
watch(
() => JSON.stringify(columnOptions.value),
() => {
if (paramsValue.column) {
const option = getOption(
columnOptions.value,
paramsValue.column,
'column',
);
const copyValue = props.value;
if (option && Object.keys(option).length) {
handOptionByColumn(option);
if (copyValue.error) {
copyValue.error = false;
emit('update:value', copyValue);
formItemContext.onFieldChange();
}
} else {
copyValue.error = true;
emit('update:value', copyValue);
formItemContext.onFieldChange();
}
//date
if (option?.dataType === 'date') {
if (timeTypeKeys.includes(paramsValue.termType || '')) {
if (tabsOptions.value[0].component !== 'int') {
}
tabsOptions.value[0].component = 'int';
} else if (
!timeTypeKeys.includes(paramsValue.termType || '') &&
tabsOptions.value[0].component == 'int'
) {
tabsOptions.value[0].component = 'date';
}
}
}
},
{ immediate: true },
);
const showDouble = computed(() => {
const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false
const isSourceMetric = paramsValue.value?.source === 'metric'
if (metricsCacheOption.value.length) {
metricOption.value = metricsCacheOption.value.filter(item => isRange ? item.range : !item.range)
} else {
metricOption.value = []
}
if (isRange) {
if (isMetric.value) {
return !isSourceMetric
const isRange = paramsValue.termType
? arrayParamsKey.includes(paramsValue.termType)
: false;
const isSourceMetric = paramsValue.value?.source === 'metric';
if (metricsCacheOption.value.length) {
metricOption.value = metricsCacheOption.value.filter((item) =>
isRange ? item.range : !item.range,
);
} else {
metricOption.value = [];
}
return true
}
return false
})
if (isRange) {
if (isMetric.value) {
return !isSourceMetric;
}
return true;
}
return false;
});
const mouseover = () => {
if (props.showDeleteBtn){
showDelete.value = true
}
}
if (props.showDeleteBtn) {
showDelete.value = true;
}
};
const mouseout = () => {
if (props.showDeleteBtn){
showDelete.value = false
}
}
if (props.showDeleteBtn) {
showDelete.value = false;
}
};
const columnSelect = (option: any) => {
const dataType = option.dataType
const hasTypeChange = dataType !== tabsOptions.value[0].component
let termTypeChange = false
//
const termTypes = option.termTypes
const dataType = option.dataType;
const hasTypeChange = dataType !== tabsOptions.value[0].component;
let termTypeChange = false;
//
const termTypes = option.termTypes;
if (!termTypes.some((item: {id: string}) => paramsValue.termType === item.id)) { //
termTypeChange = true
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq'
}
console.log('hasTypeChange', paramsValue.value.source, tabsOptions.value)
if (hasTypeChange || !tabsOptions.value.every(a => a.key === paramsValue.value.source )) { //
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq'
paramsValue.value = {
source: tabsOptions.value[0].key,
value: undefined
if (
!termTypes.some(
(item: { id: string }) => paramsValue.termType === item.id,
)
) {
//
termTypeChange = true;
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq';
}
} else if (termTypeChange) {
const oldValue = isArray(paramsValue.value!.value) ? paramsValue.value!.value[0] : paramsValue.value!.value
const value = arrayParamsKey.includes(paramsValue.termType as string) ? [ oldValue, undefined ] : oldValue
console.log('hasTypeChange', paramsValue.value.source, tabsOptions.value);
if (
hasTypeChange ||
!tabsOptions.value.every((a) => a.key === paramsValue.value.source)
) {
//
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq';
paramsValue.value = {
source: tabsOptions.value[0].key,
value: undefined,
};
} else if (termTypeChange) {
const oldValue = isArray(paramsValue.value!.value)
? paramsValue.value!.value[0]
: paramsValue.value!.value;
const value = arrayParamsKey.includes(paramsValue.termType as string)
? [oldValue, undefined]
: oldValue;
const _source = paramsValue.value?.source || tabsOptions.value[0].key
const _source = paramsValue.value?.source || tabsOptions.value[0].key;
const newValue: any = {
source: _source,
value: value,
};
if (_source === 'metric') {
newValue.metric = paramsValue.value?.metric;
}
paramsValue.value = newValue;
}
console.log(paramsValue, hasTypeChange);
handOptionByColumn(option);
emit('update:value', { ...paramsValue });
nextTick(() => {
formItemContext.onFieldChange();
});
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
][0] = option.name;
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
][1] = paramsValue.termType;
};
const termsTypeSelect = (e: { key: string; name: string }) => {
const oldValue = isArray(paramsValue.value!.value)
? paramsValue.value!.value[0]
: paramsValue.value!.value;
let value = arrayParamsKey.includes(e.key)
? [oldValue, undefined]
: oldValue;
// timeTypeKeys
if (columnType.value === 'date') {
if (timeTypeKeys.includes(e.key)) {
if (tabsOptions.value[0].component !== 'int') {
value = undefined;
}
tabsOptions.value[0].component = 'int';
} else if (
!timeTypeKeys.includes(e.key) &&
tabsOptions.value[0].component == 'int'
) {
value = undefined;
tabsOptions.value[0].component = 'date';
}
}
const _source = paramsValue.value?.source || tabsOptions.value[0].key;
const newValue: any = {
source: _source,
value: value
}
source: _source,
value: value,
};
if (_source === 'metric') {
newValue.metric = paramsValue.value?.metric
newValue.metric = paramsValue.value?.metric;
const isArray = isString(paramsValue.value!.value)
? paramsValue.value!.value?.includes?.(',')
: false;
if (arrayParamsKey.includes(e.key) !== isArray) {
//
newValue.value = undefined;
}
}
if(
['isnull','notull'].includes(e.key)
){
newValue.value = 1
}
paramsValue.value = newValue;
emit('update:value', { ...paramsValue });
formItemContext.onFieldChange();
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
][1] = e.name;
};
const valueSelect = (
v: any,
label: string,
labelObj: Record<number, any>,
option: any,
) => {
if (paramsValue.value?.source === 'metric') {
paramsValue.value.metric = option?.id;
}
paramsValue.value = newValue
}
console.log(paramsValue, hasTypeChange)
handOptionByColumn(option)
emit('update:value', { ...paramsValue })
nextTick(() => {
formItemContext.onFieldChange()
})
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName][0] = option.name
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName][1] = paramsValue.termType
}
const newValues = { ...paramsValue };
const termsTypeSelect = (e: { key: string, name: string }) => {
const oldValue = isArray(paramsValue.value!.value) ? paramsValue.value!.value[0] : paramsValue.value!.value
let value = arrayParamsKey.includes(e.key) ? [ oldValue, undefined ] : oldValue
// timeTypeKeys
if (columnType.value === 'date') {
if (timeTypeKeys.includes(e.key)) {
if (tabsOptions.value[0].component !== 'int') {
value = undefined
}
tabsOptions.value[0].component = 'int'
} else if (!timeTypeKeys.includes(e.key) && tabsOptions.value[0].component == 'int') {
value = undefined
tabsOptions.value[0].component = 'date'
if (paramsValue.value?.source !== 'metric') {
delete newValues.value.metric;
}
}
const _source = paramsValue.value?.source || tabsOptions.value[0].key
const newValue: any = {
source: _source,
value: value
}
if (_source === 'metric') {
newValue.metric = paramsValue.value?.metric
const isArray = isString(paramsValue.value!.value) ? paramsValue.value!.value?.includes?.(',') : false
if (arrayParamsKey.includes(e.key) !== isArray) { //
newValue.value = undefined
}
}
paramsValue.value = newValue
emit('update:value', { ...paramsValue })
formItemContext.onFieldChange()
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName][1] = e.name
}
const valueSelect = (v: any, label: string, labelObj: Record<number, any>, option: any) => {
if (paramsValue.value?.source === 'metric') {
paramsValue.value.metric = option?.id
}
const newValues = { ...paramsValue }
if (paramsValue.value?.source !== 'metric') {
delete newValues.value.metric
}
emit('update:value', { ...newValues })
formItemContext.onFieldChange()
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName][2] = labelObj
}
emit('update:value', { ...newValues });
formItemContext.onFieldChange();
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
][2] = labelObj;
};
const typeSelect = (e: any) => {
emit('update:value', { ...paramsValue })
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName][3] = e.label
}
emit('update:value', { ...paramsValue });
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
][3] = e.label;
};
const termAdd = () => {
const terms = {
column: undefined,
value: {
source: 'manual',
value: undefined
},
termType: undefined,
type: 'and',
key: `params_${new Date().getTime()}`
}
formModel.value.branches?.[props.branchName]?.when?.[props.whenName]?.terms?.push(terms)
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[props.termsName].push(['', '', '', '并且'])
}
const terms = {
column: undefined,
value: {
source: 'manual',
value: undefined,
},
termType: undefined,
type: 'and',
key: `params_${new Date().getTime()}`,
};
formModel.value.branches?.[props.branchName]?.when?.[
props.whenName
]?.terms?.push(terms);
formModel.value.options!.when[props.branchName].terms[props.whenName].terms[
props.termsName
].push(['', '', '', '并且']);
};
const onDelete = () => {
formModel.value.branches?.[props.branchName]?.when?.[props.whenName]?.terms?.splice(props.termsName, 1)
formModel.value.options!.when[props.branchName].terms[props.whenName].terms.splice(props.termsName, 1)
}
formModel.value.branches?.[props.branchName]?.when?.[
props.whenName
]?.terms?.splice(props.termsName, 1);
formModel.value.options!.when[props.branchName].terms[
props.whenName
].terms.splice(props.termsName, 1);
};
nextTick(() => {
Object.assign(paramsValue, pick(props.value, ['column', 'options', 'termType', 'terms', 'type', 'value', 'metric', 'key']))
})
Object.assign(
paramsValue,
pick(props.value, [
'column',
'options',
'termType',
'terms',
'type',
'value',
'metric',
'key',
]),
);
});
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -88,7 +88,7 @@ const validateValue = async (_rule: Rule, value: string) => {
]
})
if (res.status === 200 && res.result) {
return Promise.reject('value重复');
return Promise.reject('value已存在,请重新输入');
} else {
return Promise.resolve();
}

View File

@ -31,7 +31,7 @@
<j-ellipsis :lineClamp="2">{{ variables }}</j-ellipsis>
</div>
</div>
<div class="item" v-if="isNoCommunity" >
<div class="item">
<div class="label">用户权限</div>
<div class="value">
<j-ellipsis :lineClamp="2">{{ obj.role }}</j-ellipsis>

View File

@ -70,12 +70,15 @@ const searchValue = ref()
const inputRef = ref()
const addName = ref()
const selectId = ref()
const addStatus = ref(false) //
const queryGroup = async (select?: Boolean, searchName?: string) => {
const params = searchName ? { sorts: [{ name: 'createTime', order: 'desc' }], terms: [{ terms: [{ value: '%' + searchName + '%', termType: 'like', column: 'name' }] }] } : { sorts: [{ name: 'createTime', order: 'desc' }] }
const req: any = await queryRoleGroup(params)
if (req.status === 200) {
listData.value[0].children = req.result
if(req.result[req.result.length - 1].id === 'default_group'){
req.result.unshift(req.result[req.result.length - 1])
req.result.pop()
}
// if(req.result.length && select){
// selectGroup(req.result[0].id)
// }
@ -84,10 +87,10 @@ const queryGroup = async (select?: Boolean, searchName?: string) => {
const addGroup = () => {
addName.value = ''
const newId = randomString()
listData.value[0].children.unshift({
listData.value[0].children.splice(1, 0, ({
name: '',
id: newId
})
}))
selectId.value = newId
nextTick(() => {
inputRef.value.focus()
@ -95,7 +98,7 @@ const addGroup = () => {
}
const saveGroup = async (data: any) => {
if (addName.value === '') {
listData.value[0].children.shift()
listData.value[0].children.splice(1,1)
} else {
const saveData = {
name: addName.value,
@ -124,7 +127,6 @@ const searchChange = () => {
const selectGroup = (id: string) => {
selectedKeys.value = [id]
id === 'global_role' ? emit('selectData', '') : emit('selectData', selectedKeys.value)
}
const deleteGroup = async (id: string) => {
const res: any = await deleteRoleGroup(id)

View File

@ -1,5 +1,5 @@
<template>
<page-container>
<div class="role-container">
<pro-search :columns="columns" target="system-role" @search="handelSearch" />
<FullPage>
@ -37,7 +37,7 @@
<AddDialog v-if="dialogVisible" v-model:visible="dialogVisible" :groupId="groupId" :modalType="modalType"
:current="current" />
</div>
</page-container>
</template>
<script setup lang="ts" name="Role">

View File

@ -5,7 +5,7 @@
<div class="left" >
<img
style="width: 100%; height: 100%"
:src="basis.backgroud || getImage('/login.png')"
:src="basis.background || getImage('/login.png')"
/>
<a
href="https://beian.miit.gov.cn/#/Integrated/index"