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

View File

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

View File

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

View File

@ -32,7 +32,7 @@
</div> </div>
<div v-else> <div v-else>
<File v-if='importData.type ==="file"' :product='importData.productId' /> <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>
</div> </div>
<template #footer> <template #footer>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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