Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev

This commit is contained in:
jackhoo_98 2023-03-29 15:14:24 +08:00
commit 1b596d4599
12 changed files with 404 additions and 200 deletions

View File

@ -27,7 +27,11 @@
terms: [ terms: [
{ {
terms: [ terms: [
{ column: 'parentId$isnull', value: '1' }, {
column: 'parentId$isnull',
value: '',
type: 'or',
},
{ {
column: 'parentId$not', column: 'parentId$not',
value: detail.id, value: detail.id,
@ -43,6 +47,7 @@
type: 'and', type: 'and',
}, },
], ],
type: 'and',
}, },
{ {
terms: [ terms: [

View File

@ -1,21 +1,25 @@
<template> <template>
<j-select allowClear v-model:value="_value" @change="onChange" placeholder="请选择" style="width: 100%"> <j-select
allowClear
v-model:value="_value"
@change="onChange"
placeholder="请选择"
style="width: 100%"
>
<j-select-option <j-select-option
v-for="item in list" v-for="item in list"
v-bind="item"
:key="item.id" :key="item.id"
:value="item.id" :value="item.id"
:label="item.name" :label="item.name"
:filter-option="filterOption" showSearch
>{{ item.name }}</j-select-option >{{ item.name }}</j-select-option
> >
</j-select> </j-select>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { import queryDataList from './utils';
edgeCollector,
edgePoint,
} from '@/api/device/instance';
const _props = defineProps({ const _props = defineProps({
modelValue: { modelValue: {
@ -33,15 +37,17 @@ const _props = defineProps({
edgeId: { edgeId: {
type: String, type: String,
default: '', default: '',
} },
provider: {
type: String,
default: '',
},
}); });
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
type Emits = { type Emits = {
(e: 'update:modelValue', data: string | undefined): void; (e: 'update:modelValue', data: string | undefined): void;
(e: 'update:provider', data: string | undefined): void;
(e: 'change', data: string | undefined): void;
}; };
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
@ -52,64 +58,16 @@ watchEffect(() => {
_value.value = _props.modelValue; _value.value = _props.modelValue;
}); });
const onChange = (_val: string) => { const onChange = (_val: string, _options: any) => {
emit('update:modelValue', _val); emit('update:modelValue', _val);
}; emit('update:provider', _options?.provider);
emit('change', _val);
const getCollector = async (_val: string) => {
if (!_val) {
return [];
} else {
const resp = await edgeCollector(_props.edgeId, {
terms: [
{
terms: [
{
column: 'channelId',
value: _val,
},
],
},
],
});
if (resp.status === 200) {
list.value = (resp.result as any[])?.[0] || []
}
}
};
const getPoint = async (_val: string) => {
if (!_val) {
return [];
} else {
const resp = await edgePoint(_props.edgeId, {
terms: [
{
terms: [
{
column: 'collectorId',
value: _val,
},
],
},
],
});
if (resp.status === 200) {
list.value = (resp.result as any[])?.[0] || []
}
}
}; };
watchEffect(() => { watchEffect(() => {
if (_props.id) { queryDataList(_props.id, _props.edgeId, _props.type).then((_data: any) => {
if (_props.type === 'POINT') { list.value = _data;
getPoint(_props.id); });
} else {
getCollector(_props.id);
}
} else {
list.value = [];
}
}); });
</script> </script>

View File

@ -31,7 +31,9 @@
v-model:value="record[column.dataIndex]" v-model:value="record[column.dataIndex]"
placeholder="请选择" placeholder="请选择"
allowClear allowClear
:filter-option="filterOption" @change="
() => onChannelChange(index, 'channel')
"
> >
<j-select-option <j-select-option
v-for="item in channelList" v-for="item in channelList"
@ -58,6 +60,10 @@
:id="record.channelId" :id="record.channelId"
type="COLLECTOR" type="COLLECTOR"
:edgeId="instanceStore.current.parentId" :edgeId="instanceStore.current.parentId"
v-model:provider="record.provider"
@change="
onChannelChange(index, 'collector')
"
/> />
</j-form-item> </j-form-item>
</template> </template>
@ -80,61 +86,84 @@
</j-form-item> </j-form-item>
</template> </template>
<template v-if="column.dataIndex === 'id'"> <template v-if="column.dataIndex === 'id'">
<j-badge <template v-if="record[column.dataIndex]">
v-if="record[column.dataIndex]" <j-badge
status="success" v-if="record.state.value === 'enabled'"
text="已绑定" status="success"
/> text="在线"
/>
<j-badge
v-else
status="warning"
text="离线"
/>
</template>
<j-badge v-else status="error" text="未绑定" /> <j-badge v-else status="error" text="未绑定" />
</template> </template>
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
<j-space> <j-space>
<PermissionButton <j-tooltip
type="link" :title="
:disabled="!record.id" isPermission
:popConfirm="{ ? '解绑'
title: '确认解绑?', : '暂无权限,请联系管理员'
onConfirm: unbind(record.id), "
}"
style="padding: 0 5px"
hasPermission="device/Instance:update"
:tooltip="{
title: '解绑',
}"
> >
<AIcon type="icon-jiebang" /> <j-popconfirm
</PermissionButton> title="确认解绑?"
:disabled="!record.id || !isPermission"
@confirm="unbind(record.id)"
>
<j-button
type="link"
:disabled="
!record.id || !isPermission
"
style="padding: 0 5px"
>
<AIcon type="icon-jiebang" />
</j-button>
</j-popconfirm>
</j-tooltip>
<template v-if="record.id"> <template v-if="record.id">
<PermissionButton <j-tooltip
type="link" :title="
:disabled="!record.id" isPermission
style="padding: 0 5px" ? record.state.value ===
:popConfirm="{ 'enabled'
title: ? '禁用'
: '启用'
: '暂无权限,请联系管理员'
"
>
<j-popconfirm
:title="
record.state.value === 'enabled' record.state.value === 'enabled'
? '确认禁用?' ? '确认禁用?'
: '确认启用?', : '确认启用?'
onConfirm: onAction(record),
}"
hasPermission="device/Instance:update"
:tooltip="{
title:
record.state.value === 'enabled'
? '禁用'
: '启用',
}"
>
<AIcon
v-if="
record.state.value === 'enabled'
" "
type="StopOutlined" :disabled="!isPermission"
/> @confirm="onAction(record)"
<AIcon >
v-else <j-button
type="PlayCircleOutlined" type="link"
/> style="padding: 0 5px"
</PermissionButton> :disabled="!isPermission"
>
<AIcon
v-if="
record.state.value ===
'enabled'
"
type="StopOutlined"
/>
<AIcon
v-else
type="PlayCircleOutlined"
/>
</j-button>
</j-popconfirm>
</j-tooltip>
</template> </template>
</j-space> </j-space>
</template> </template>
@ -142,10 +171,10 @@
</j-table> </j-table>
<div class="pagination"> <div class="pagination">
<j-pagination <j-pagination
@change="onPageChange"
v-model:pageSize="pageSize" v-model:pageSize="pageSize"
v-model:current="current" v-model:current="current"
:total="metadata?.properties?.length || 0" :total="metadata?.properties?.length || 0"
@change="onPageChange"
/> />
</div> </div>
</j-form> </j-form>
@ -175,6 +204,8 @@ import {
import MSelect from './MSelect.vue'; import MSelect from './MSelect.vue';
import PatchMapping from './PatchMapping.vue'; import PatchMapping from './PatchMapping.vue';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import { cloneDeep } from 'lodash-es';
import { usePermissionStore } from '@/store/permission';
const columns = [ const columns = [
{ {
@ -214,19 +245,22 @@ const columns = [
}, },
]; ];
const current = ref<number>(1); const permissionStore = usePermissionStore();
const pageSize = ref<number>(10);
const filterOption = (input: string, option: any) => { const isPermission = permissionStore.hasPermission('device/Instance:update');
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
}; const current = ref<number>(0);
const pageSize = ref<number>(10);
const instanceStore = useInstanceStore(); const instanceStore = useInstanceStore();
const metadata = JSON.parse(instanceStore.current?.metadata || '{}'); const metadata = JSON.parse(instanceStore.current?.metadata || '{}');
const loading = ref<boolean>(false); const loading = ref<boolean>(false);
const channelList = ref<any[]>([]); const channelList = ref<any[]>([]);
const _properties = ref<any[]>([]); const _properties = computed(() => {
const _cur = current.value >= 1 ? current.value : 1;
return metadata.properties.slice((_cur - 1) * 10, _cur * 10);
});
const modelRef = reactive<{ const modelRef = reactive<{
dataSource: any[]; dataSource: any[];
@ -250,18 +284,9 @@ const getChannel = async () => {
} }
}; };
const queryData = (cur: number) => { const handleSearch = async (_array: any[]) => {
_properties.value = metadata.properties.slice(
(cur > 0 ? cur - 1 : 0) * 10,
cur * 10,
);
handleSearch(_properties.value)
};
const handleSearch = async (array: any[]) => {
loading.value = true; loading.value = true;
getChannel(); const _metadata: any[] = _array.map((item: any) => ({
const _metadata: any[] = array.map((item: any) => ({
metadataId: item.id, metadataId: item.id,
metadataName: `${item.name}(${item.id})`, metadataName: `${item.name}(${item.id})`,
metadataType: 'property', metadataType: 'property',
@ -297,11 +322,12 @@ const handleSearch = async (array: any[]) => {
}; };
const unbind = async (id: string) => { const unbind = async (id: string) => {
if (id) { const _deviceId = instanceStore.current.id;
if (id && _deviceId) {
const resp = await removeEdgeMap( const resp = await removeEdgeMap(
instanceStore.current?.parentId || '', instanceStore.current?.parentId || '',
{ {
deviceId: instanceStore.current.id, deviceId: _deviceId,
idList: [id], idList: [id],
}, },
); );
@ -314,22 +340,31 @@ const unbind = async (id: string) => {
const onPatchBind = () => { const onPatchBind = () => {
visible.value = false; visible.value = false;
handleSearch(_properties.value); onRefresh();
}; };
const onPageChange = (page: any) => { const onChannelChange = (_index: number, type: 'collector' | 'channel') => {
queryData(page) if (type === 'channel') {
modelRef.dataSource[_index].collectorId = undefined;
modelRef.dataSource[_index].pointId = undefined;
} else {
modelRef.dataSource[_index].pointId = undefined;
}
}; };
onMounted(() => { onMounted(() => {
_properties.value = metadata.properties.slice(0, 10); getChannel();
handleSearch(_properties.value); handleSearch(_properties.value);
}); });
const onPageChange = () => {
handleSearch(_properties.value);
};
const onSave = () => { const onSave = () => {
formRef.value formRef.value
.validate() .validate()
.then(async () => { .then(async (_data: any) => {
const arr = toRaw(modelRef).dataSource.filter( const arr = toRaw(modelRef).dataSource.filter(
(i: any) => i.channelId, (i: any) => i.channelId,
); );
@ -345,7 +380,7 @@ const onSave = () => {
); );
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('操作成功!', 'success'); onlyMessage('操作成功!', 'success');
handleSearch(_properties.value); onRefresh();
} }
} }
}) })
@ -355,8 +390,9 @@ const onSave = () => {
}; };
const onAction = async (record: any) => { const onAction = async (record: any) => {
const value = await formRef.value.validate(); const array = (modelRef.dataSource || [])?.filter(
const array = value.filter((item: any) => item.channelId); (item: any) => item.channelId,
);
const findArray = array.find((item: any) => item.id === record?.id); const findArray = array.find((item: any) => item.id === record?.id);
const arr = { const arr = {
...findArray, ...findArray,
@ -374,9 +410,42 @@ const onAction = async (record: any) => {
); );
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('操作成功!', 'success'); onlyMessage('操作成功!', 'success');
handleSearch(_properties.value); onRefresh();
} }
}; };
const onRefresh = async () => {
loading.value = true;
if (modelRef.dataSource && modelRef.dataSource.length) {
const resp: any = await getEdgeMap(
instanceStore.current?.parentId || '',
{
deviceId: instanceStore.current.id,
query: {},
},
).catch(() => {
loading.value = false;
});
if (resp.status === 200) {
const arr = cloneDeep(modelRef.dataSource);
const array = resp.result?.[0].map((x: any) => {
const _item = arr.find(
(item: any) => item.metadataId === x.metadataId,
);
if (_item) {
return {
..._item,
...x,
};
} else {
return x;
}
});
modelRef.dataSource = array;
}
}
loading.value = false;
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -0,0 +1,48 @@
import { edgeCollector, edgePoint } from "@/api/device/instance";
const channelMap = new Map()
const queryDataList = (_val: string, edgeId: string, type: string) => new Promise(async (resolve) => {
if (!_val || !edgeId || !type) {
resolve([])
} else {
if (channelMap.get(_val)) {
resolve(channelMap.get(_val))
} else {
let resp = undefined
if (type === 'POINT') {
resp = await edgePoint(edgeId, {
terms: [
{
terms: [
{
column: 'collectorId',
value: _val,
},
],
},
],
});
} else {
resp = await edgeCollector(edgeId, {
terms: [
{
terms: [
{
column: 'channelId',
value: _val,
},
],
},
],
});
}
if (resp && resp.status === 200) {
const _data = (resp.result as any[])?.[0] || []
channelMap.set(_val, _data)
resolve(_data)
}
}
}
})
export default queryDataList

View File

@ -308,8 +308,8 @@ import dayjs from 'dayjs';
import BadgeStatus from '@/components/BadgeStatus/index.vue'; import BadgeStatus from '@/components/BadgeStatus/index.vue';
import BatchDropdown from '@/components/BatchDropdown/index.vue'; import BatchDropdown from '@/components/BatchDropdown/index.vue';
import { BatchActionsType } from '@/components/BatchDropdown/types'; import { BatchActionsType } from '@/components/BatchDropdown/types';
import {useRouterParams} from "@/utils/hooks/useParams"; import { useRouterParams } from '@/utils/hooks/useParams';
import { accessConfigTypeFilter } from '@/utils/setting' import { accessConfigTypeFilter } from '@/utils/setting';
const instanceRef = ref<Record<string, any>>({}); const instanceRef = ref<Record<string, any>>({});
const params = ref<Record<string, any>>({}); const params = ref<Record<string, any>>({});
@ -322,22 +322,22 @@ const operationVisible = ref<boolean>(false);
const api = ref<string>(''); const api = ref<string>('');
const type = ref<string>(''); const type = ref<string>('');
const isCheck = ref<boolean>(false); const isCheck = ref<boolean>(false);
const routerParams = useRouterParams() const routerParams = useRouterParams();
const menuStory = useMenuStore(); const menuStory = useMenuStore();
const transformData = (arr: any[]): any[] => { const transformData = (arr: any[]): any[] => {
if(Array.isArray(arr) && arr.length){ if (Array.isArray(arr) && arr.length) {
return (arr || []).map((item: any) => { return (arr || []).map((item: any) => {
return { return {
...item, ...item,
id: `classifiedId is ${item.id}`, id: `classifiedId is ${item.id}`,
children: transformData(item.children) children: transformData(item.children),
} };
}) });
} else { } else {
return [] return [];
} }
} };
const columns = [ const columns = [
{ {
@ -412,7 +412,7 @@ const columns = [
hideInTable: true, hideInTable: true,
search: { search: {
type: 'treeSelect', type: 'treeSelect',
rename: 'productId$product-info', // rename: 'productId$product-info',
options: () => options: () =>
new Promise((resolve) => { new Promise((resolve) => {
queryTree({ paging: false }).then((resp: any) => { queryTree({ paging: false }).then((resp: any) => {
@ -429,22 +429,24 @@ const columns = [
hideInTable: true, hideInTable: true,
search: { search: {
type: 'select', type: 'select',
rename: 'productId$product-info', // rename: 'productId$product-info',
options: () => options: () =>
new Promise((resolve) => { new Promise((resolve) => {
getProviders().then((resp: any) => { getProviders().then((resp: any) => {
const data = resp.result || [] const data = resp.result || [];
resolve(accessConfigTypeFilter(data).map(item => ({ resolve(
...item, accessConfigTypeFilter(data).map((item) => ({
value: `accessProvider is ${item.id}` ...item,
}))) value: `accessProvider is ${item.id}`,
})),
);
}); });
}), }),
}, },
}, },
{ {
key: 'productId$product-info', key: 'accessId',
dataIndex: 'productId$product-info', dataIndex: 'accessId',
title: '接入方式', title: '接入方式',
hideInTable: true, hideInTable: true,
search: { search: {
@ -728,9 +730,9 @@ const syncDeviceStatus = () => {
}; };
const delSelectedDevice = async () => { const delSelectedDevice = async () => {
if(!_selectedRowKeys.value.length){ if (!_selectedRowKeys.value.length) {
message.error('请选择设备') message.error('请选择设备');
return return;
} }
const resp = await batchDeleteDevice(_selectedRowKeys.value); const resp = await batchDeleteDevice(_selectedRowKeys.value);
if (resp.status === 200) { if (resp.status === 200) {
@ -754,9 +756,9 @@ const delSelectedDevice = async () => {
// }; // };
const disabledSelectedDevice = async () => { const disabledSelectedDevice = async () => {
if(!_selectedRowKeys.value.length){ if (!_selectedRowKeys.value.length) {
message.error('请选择设备') message.error('请选择设备');
return return;
} }
const resp = await batchUndeployDevice(_selectedRowKeys.value); const resp = await batchUndeployDevice(_selectedRowKeys.value);
if (resp.status === 200) { if (resp.status === 200) {
@ -842,7 +844,7 @@ const batchActions: BatchActionsType[] = [
popConfirm: { popConfirm: {
title: '确认禁用选中设备?', title: '确认禁用选中设备?',
onConfirm: disabledSelectedDevice, onConfirm: disabledSelectedDevice,
} },
}, },
}, },
]; ];
@ -853,7 +855,25 @@ const saveBtn = () => {
}; };
const handleSearch = (_params: any) => { const handleSearch = (_params: any) => {
params.value = _params; // params.value = _params;
const newParams = (_params?.terms as any[])?.map((item1) => {
item1.terms = item1.terms.map((item2: any) => {
if (
item2.column &&
['classifiedId', 'accessId', 'accessProvider'].includes(
item2.column,
)
) {
return {
...item2,
column: 'productId$product-info'
};
}
return item2;
});
return item1;
});
params.value = { terms: newParams || [] };
}; };
const onRefresh = () => { const onRefresh = () => {

View File

@ -8,6 +8,12 @@
v-if=" v-if="
permissionStore.hasPermission( permissionStore.hasPermission(
'device/Product:update', 'device/Product:update',
) &&
permissionStore.hasPermission(
'link/AccessConfig:add',
) &&
permissionStore.hasPermission(
'link/AccessConfig:update',
) )
" "
> >
@ -24,7 +30,7 @@
<j-col :span="12"> <j-col :span="12">
<Title data="接入方式"> <Title data="接入方式">
<template #extra> <template #extra>
<j-tooltip <!-- <j-tooltip
:title=" :title="
productStore.current?.count && productStore.current?.count &&
productStore.current?.count > 0 productStore.current?.count > 0
@ -44,7 +50,48 @@
@click="showDevice" @click="showDevice"
>更换</j-button >更换</j-button
> >
</j-tooltip> </j-tooltip> -->
<PermissionButton
style="margin: 0 0 0 20px"
type="primary"
size="small"
:tooltip="{
title:
productStore.current?.count &&
productStore.current?.count > 0
? '产品下有设备实例时不能更换接入方式'
: !(permissionStore.hasPermission(
'device/Product:update',
) &&
permissionStore.hasPermission(
'link/AccessConfig:add',
) &&
permissionStore.hasPermission(
'link/AccessConfig:update',
))
? '暂无权限,请联系管理员'
: '',
}"
:disabled="
(productStore.current?.count &&
productStore.current?.count > 0) ||
!(
permissionStore.hasPermission(
'device/Product:update',
) &&
permissionStore.hasPermission(
'link/AccessConfig:add',
) &&
permissionStore.hasPermission(
'link/AccessConfig:update',
)
)
"
ghost
@click="showDevice"
>
更换
</PermissionButton>
</template> </template>
</Title> </Title>
<div> <div>
@ -419,7 +466,7 @@ import { marked } from 'marked';
import type { TableColumnType } from 'ant-design-vue'; import type { TableColumnType } from 'ant-design-vue';
import { useMenuStore } from '@/store/menu'; import { useMenuStore } from '@/store/menu';
import _ from 'lodash'; import _ from 'lodash';
import { accessConfigTypeFilter } from '@/utils/setting' import { accessConfigTypeFilter } from '@/utils/setting';
const tableRef = ref(); const tableRef = ref();
const formRef = ref(); const formRef = ref();
@ -502,8 +549,8 @@ const query = reactive({
options: async () => { options: async () => {
return new Promise((resolve) => { return new Promise((resolve) => {
getProviders().then((resp: any) => { getProviders().then((resp: any) => {
const data = resp.result || [] const data = resp.result || [];
resolve(accessConfigTypeFilter(data)) resolve(accessConfigTypeFilter(data));
}); });
}); });
}, },
@ -935,7 +982,7 @@ const getData = async (accessId?: string) => {
); );
getProviders().then((resp) => { getProviders().then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
const data = resp.result || [] const data = resp.result || [];
dataSource.value = accessConfigTypeFilter(data as any[]); dataSource.value = accessConfigTypeFilter(data as any[]);
} }
}); });
@ -1019,10 +1066,13 @@ watchEffect(() => {
nextTick(() => { nextTick(() => {
getData(); getData();
}); });
watch(()=>productStore.current,()=>{ watch(
getData(); () => productStore.current,
formData.data = productStore.current?.configuration || {} () => {
}) getData();
formData.data = productStore.current?.configuration || {};
},
);
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
:deep( :deep(

View File

@ -85,6 +85,7 @@
:value="form.deviceType" :value="form.deviceType"
:options="deviceList" :options="deviceList"
@change="changeDeviceType" @change="changeDeviceType"
:disabled="productStore.detail?.accessId ? true : false"
> >
<template #title="item"> <template #title="item">
<span>{{ item.title }}</span> <span>{{ item.title }}</span>
@ -141,12 +142,9 @@ const loading = ref<boolean>(false);
const dialogRef = ref(); const dialogRef = ref();
const treeList = ref<Record<string, any>[]>([]); const treeList = ref<Record<string, any>[]>([]);
const visible = ref<boolean>(false); const visible = ref<boolean>(false);
const logoLoading = ref<boolean>(false);
const formRef = ref(); const formRef = ref();
const disabled = ref<boolean>(false);
const idDisabled = ref<boolean>(false); const idDisabled = ref<boolean>(false);
const useForm = Form.useForm; const useForm = Form.useForm;
const _selectedRowKeys = ref([]);
const photoValue = ref('/images/device-product.png'); const photoValue = ref('/images/device-product.png');
const imageTypes = reactive([ const imageTypes = reactive([
'image/jpeg', 'image/jpeg',
@ -257,21 +255,14 @@ const queryProductTree = async () => {
* 处理产品分类key * 处理产品分类key
*/ */
const dealProductTree = (arr: any) => { const dealProductTree = (arr: any) => {
return arr.map((element: any) => { return arr.map((element: any) => {
element.key = element.id; element.key = element.id;
if (element.children) { if (element.children) {
element.children = dealProductTree(element.children); element.children = dealProductTree(element.children);
} }
return element return element;
}); });
}; };
watch(
() => props.isAdd,
() => {
// queryProductTree();
},
{ immediate: true, deep: true },
);
/** /**
* 显示弹窗 * 显示弹窗
*/ */
@ -285,9 +276,9 @@ const show = (data: any) => {
form.deviceType = data.deviceType.value; form.deviceType = data.deviceType.value;
form.describe = form.describe; form.describe = form.describe;
form.id = data.id; form.id = data.id;
disabled.value = productStore.current?.accessId ? true : false;
idDisabled.value = true; idDisabled.value = true;
} else if (props.isAdd === 1) { } else if (props.isAdd === 1) {
productStore.reSet();
form.name = ''; form.name = '';
form.classifiedId = undefined; form.classifiedId = undefined;
form.classifiedName = ''; form.classifiedName = '';
@ -295,8 +286,7 @@ const show = (data: any) => {
form.deviceType = ''; form.deviceType = '';
form.describe = undefined; form.describe = undefined;
form.id = undefined; form.id = undefined;
disabled.value = false; idDisabled.value = false;
disabled.vlaue = false;
} }
visible.value = true; visible.value = true;
}; };
@ -318,7 +308,6 @@ const submitData = () => {
formRef.value formRef.value
.validate() .validate()
.then(async () => { .then(async () => {
console.log(form);
// //
if (props.isAdd === 1) { if (props.isAdd === 1) {
if (form.id === '') { if (form.id === '') {

View File

@ -70,9 +70,14 @@
<div class="gateway-box"> <div class="gateway-box">
<div v-if="!gatewayList.length"> <div v-if="!gatewayList.length">
暂无数据请先 暂无数据请先
<j-button type="link"> <PermissionButton
添加{{ providerType[props.channel] }} 接入网关 type="link"
</j-button> style="padding: 0"
hasPermission="link/AccessConfig:add"
@click="onJump"
>
添加{{ providerType[props.channel] }}接入网关
</PermissionButton>
</div> </div>
<div <div
class="gateway-item" class="gateway-item"
@ -156,6 +161,9 @@ import DeviceApi from '@/api/media/device';
import { getImage } from '@/utils/comm'; import { getImage } from '@/utils/comm';
import { gatewayType } from '@/views/media/Device/typings'; import { gatewayType } from '@/views/media/Device/typings';
import { providerType } from '../const'; import { providerType } from '../const';
import { useMenuStore } from '@/store/menu';
const menuStory = useMenuStore();
type Emits = { type Emits = {
(e: 'update:visible', data: boolean): void; (e: 'update:visible', data: boolean): void;
@ -234,8 +242,8 @@ watch(
if (val) { if (val) {
getGatewayList(); getGatewayList();
} else { } else {
_selectedRowKeys.value = [] _selectedRowKeys.value = [];
extendFormItem.value = [] extendFormItem.value = [];
emit('close'); emit('close');
} }
}, },
@ -290,6 +298,14 @@ const handleCancel = () => {
_vis.value = false; _vis.value = false;
formRef.value.resetFields(); formRef.value.resetFields();
}; };
const onJump = () => {
menuStory.jumpPage(
`link/AccessConfig/Detail`,
{ id: ':id' },
{ view: false },
);
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -42,6 +42,15 @@
enabled: 'processing', enabled: 'processing',
disabled: 'error', disabled: 'error',
}" }"
@click="
() => {
menuStory.jumpPage(
'rule-engine/Alarm/Configuration/Save',
{},
{ id: slotProps.id },
);
}
"
> >
<template #img> <template #img>
<slot name="img"> <slot name="img">

View File

@ -43,6 +43,8 @@
:multiple="true" :multiple="true"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
:value="relationData" :value="relationData"
showSearch
treeNodeFilterProp="title"
> >
<template #title="{ key, username, title }"> <template #title="{ key, username, title }">
<div <div
@ -69,6 +71,8 @@
:tree-data="treeData" :tree-data="treeData"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
:value="relationData" :value="relationData"
showSearch
treeNodeFilterProp="title"
> >
<template #title="{ key, username, title }"> <template #title="{ key, username, title }">
<div <div
@ -110,6 +114,7 @@
placeholder="请输入收件人邮箱,多个收件人用换行分隔" placeholder="请输入收件人邮箱,多个收件人用换行分隔"
:value="value?.value" :value="value?.value"
mode="tags" mode="tags"
max-tag-count="responsive"
@change=" @change="
(val) => (val) =>
onChange( onChange(

View File

@ -50,6 +50,7 @@
<script setup lang="ts" name="RolePermiss"> <script setup lang="ts" name="RolePermiss">
import { FormInstance, message } from 'ant-design-vue'; import { FormInstance, message } from 'ant-design-vue';
import PermissTree from '../components/PermissTree.vue'; import PermissTree from '../components/PermissTree.vue';
import { useMenuStore } from '@/store/menu';
import { import {
getRoleDetails_api, getRoleDetails_api,
@ -57,6 +58,7 @@ import {
updatePrimissTree_api, updatePrimissTree_api,
} from '@/api/system/role'; } from '@/api/system/role';
const { jumpPage } = useMenuStore();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const roleId = route.params.id as string; const roleId = route.params.id as string;
@ -86,7 +88,7 @@ const form = reactive({
console.log(form.menus); console.log(form.menus);
Promise.all([updateRole, updateTree]).then((resp) => { Promise.all([updateRole, updateTree]).then((resp) => {
message.success('操作成功'); message.success('操作成功');
// router.push('/system/Role'); jumpPage(`system/Role`);
}); });
}); });
}, },

View File

@ -137,8 +137,29 @@ const selectAllChange = () => {
item.buttons?.forEach((button) => { item.buttons?.forEach((button) => {
button.granted = selectedAll.value; button.granted = selectedAll.value;
}); });
if (selectedAll.value) {
//
item.selectAccesses = 'creator';
} else {
//
item.selectAccesses = '';
}
if (item.accessSupport && item.accessSupport.value === 'support') {
item.assetAccesses?.forEach((asset) => {
if (asset.supportId === item.selectAccesses) {
asset.granted = true;
} else {
asset.granted = false;
}
});
}
}); });
console.log('selectAllChange: ', flatTableData);
indeterminate.value = false; indeterminate.value = false;
emits(
'update:selectItems',
flatTableData.filter((item) => item.granted),
);
}; };
// - // -
const bulkShow = ref<boolean>(false); const bulkShow = ref<boolean>(false);
@ -166,8 +187,20 @@ const bulkChange = () => {
flatTableData.forEach((item) => { flatTableData.forEach((item) => {
if (item.accessSupport && item.accessSupport.value === 'support') { if (item.accessSupport && item.accessSupport.value === 'support') {
item.selectAccesses = bulkValue.value; item.selectAccesses = bulkValue.value;
item.assetAccesses?.forEach((asset) => {
if (asset.supportId === bulkValue.value) {
asset.granted = true;
} else {
asset.granted = false;
}
});
} }
}); });
console.log('bulkChange: ', flatTableData);
emits(
'update:selectItems',
flatTableData.filter((item) => item.granted),
);
}; };
// //