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

This commit is contained in:
JiangQiming 2023-03-29 20:01:36 +08:00
commit 9f0bc42fb9
21 changed files with 184 additions and 64 deletions

View File

@ -26,6 +26,10 @@
required: true,
message: '请输入',
},
{
validator: checkLength,
trigger: 'change',
},
]"
>
<j-input

View File

@ -88,7 +88,7 @@
import type { FormInstance } from 'ant-design-vue';
import { savePointBatch } from '@/api/data-collect/collector';
import { Rule } from 'ant-design-vue/lib/form';
import { cloneDeep } from 'lodash';
import { cloneDeep, isObject } from 'lodash';
import { regOnlyNumber } from '../../../data';
const props = defineProps({
@ -125,7 +125,15 @@ const handleOk = async () => {
if (ischange) {
const params = cloneDeep(props.data);
params.forEach((i: any) => {
accessModes.length !== 0 && (i.accessModes = data.accessModes);
if (accessModes.length !== 0) {
i.accessModes = data.accessModes;
} else {
if (isObject(i.accessModes)) {
i.accessModes = i.accessModes.map(
(item: any) => item.value,
);
}
}
features.length !== 0 && (i.features = data.features);
if (!!interval) {
i.interval = data.interval;

View File

@ -28,7 +28,7 @@
defualtDataSource.length !== 0 ||
defualtDataSource?.[0]?.children?.length !== 0
"
:height="600"
:height="660"
defaultExpandAll
>
<template #title="{ name, data }">
@ -302,6 +302,10 @@ watch(
}
}
:deep(.ant-tree-list-holder-inner) {
width: 90%;
}
:deep(.ant-tree-treenode) {
width: 100%;
.ant-tree-node-content-wrapper {

View File

@ -6,19 +6,19 @@ const getParams = (dt: any) => {
return {
limit: 24,
interval: '1h',
format: 'HH:mm',
format: 'YYYY-MM-dd HH:mm',
};
case 'week':
return {
limit: 7,
interval: '1d',
format: 'MM-dd',
format: 'YYYY-MM-dd HH:mm',
};
case 'hour':
return {
limit: 60,
interval: '1m',
format: 'HH:mm',
format: 'YYYY-MM-dd HH:mm',
};
default:
const time = dt.time[1] - dt.time[0];
@ -29,31 +29,31 @@ const getParams = (dt: any) => {
return {
limit: Math.abs(Math.ceil(time / (60 * 60))),
interval: '1m',
format: 'HH:mm',
format: 'YYYY-MM-dd HH:mm',
};
} else if (time > hour && time <= days) {
return {
limit: Math.abs(Math.ceil(time / hour)),
interval: '1h',
format: 'HH:mm',
format: 'YYYY-MM-dd HH:mm',
};
} else if (time > days && time <= days * 7) {
return {
limit: Math.abs(Math.ceil(time / days / 7)) + 1,
interval: '1d',
format: 'YYYY-MM-DD',
format: 'YYYY-MM-dd HH:mm',
};
} else if (time >= year) {
return {
limit: Math.abs(Math.ceil(time / days / 31)) + 1,
interval: '1M',
format: 'yyyy年-M月',
format: 'YYYY-MM-dd HH:mm',
};
} else {
return {
limit: Math.abs(Math.ceil(time / days)) + 1,
interval: '1d',
format: 'MM-dd',
format: 'YYYY-MM-dd HH:mm',
};
}
}

View File

@ -87,7 +87,7 @@ export default {
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
@ -149,7 +149,7 @@ export default {
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
@ -194,7 +194,25 @@ export default {
granted: true,
},
],
assetAccesses: [],
assetAccesses: [{
supportId: 'ignore',
name: '全部数据',
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
enabled: false,
granted: false,
},
{
supportId: 'org-include-children',
name: '所在组织及下级组织',
enabled: false,
granted: false,
},],
options: { switch: true },
createTime: 1659344075524,
granted: true,
@ -541,7 +559,7 @@ export default {
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
@ -603,7 +621,7 @@ export default {
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: false, granted: false },
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
@ -648,7 +666,25 @@ export default {
granted: true,
},
],
assetAccesses: [],
assetAccesses: [{
supportId: 'ignore',
name: '全部数据',
enabled: false,
granted: false,
},
{ supportId: 'creator', name: '自己创建的', enabled: true, granted: true },
{
supportId: 'org',
name: '所在组织',
enabled: false,
granted: false,
},
{
supportId: 'org-include-children',
name: '所在组织及下级组织',
enabled: false,
granted: false,
}],
options: { switch: true },
createTime: 1659344075524,
granted: true,

View File

@ -188,7 +188,7 @@ import {
} from '@/api/link/accessConfig';
import { onlyMessage } from '@/utils/comm';
import { useMenuStore } from 'store/menu';
import { accessConfigTypeFilter } from '@/utils/setting'
import { accessConfigTypeFilter } from '@/utils/setting';
const menuStory = useMenuStore();
const tableRef = ref<Record<string, any>>({});
@ -304,10 +304,12 @@ const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
popConfirm: {
title: '确认删除?',
onConfirm: async () => {
const res = await remove(data.id);
if (res.success) {
const res: any = await remove(data.id);
if (res.status === 200) {
onlyMessage('操作成功', 'success');
tableRef.value.reload();
} else {
onlyMessage(res?.message, 'error');
}
},
},
@ -319,7 +321,7 @@ const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
const getProvidersList = async () => {
const res: any = await getProviders();
providersList.value = res.result;
providersOptions.value = accessConfigTypeFilter(res.result || [])
providersOptions.value = accessConfigTypeFilter(res.result || []);
};
getProvidersList();

View File

@ -80,7 +80,7 @@ const columns = [
type: 'select',
options: [
{
label: '证书标准',
label: '国际标准',
value: 'common',
},
],

View File

@ -99,6 +99,7 @@ export const networkParams = (val: any) => {
from: Number(val.time.time[0]),
to: Number(val.time.time[1]),
limit: _limit,
format: 'YYYY-MM-dd HH:mm',
},
},
];

View File

@ -238,10 +238,12 @@ const getActions = (
popConfirm: {
title: '确认删除?',
onConfirm: async () => {
const res = await remove(data.id);
if (res.success) {
const res: any = await remove(data.id);
if (res.status === 200) {
onlyMessage('操作成功', 'success');
tableRef.value.reload();
} else {
onlyMessage(res?.message, 'error');
}
},
},

View File

@ -327,10 +327,12 @@ const getActions = (
popConfirm: {
title: '确认删除?',
onConfirm: async () => {
const res = await remove(data.id);
if (res.success) {
const res: any = await remove(data.id);
if (res.status === 200) {
onlyMessage('操作成功', 'success');
tableRef.value.reload();
} else {
onlyMessage(res?.message, 'error');
}
},
},

View File

@ -73,15 +73,21 @@
style="margin-top: 50px"
>
<template #description>
暂无数据请先
<PermissionButton
type="link"
style="padding: 0"
hasPermission="link/AccessConfig:add"
@click="handleAdd"
<template v-if="!isPermission"
>暂无权限, 请联系管理员</template
>
添加{{ providerType[props.channel] }}接入网关
</PermissionButton>
<template v-else>
暂无数据请先
<j-button
type="link"
style="padding: 0"
@click="handleAdd"
>
添加{{
providerType[props.channel]
}}接入网关
</j-button>
</template>
</template>
</j-empty>
<div
@ -166,9 +172,11 @@ import DeviceApi from '@/api/media/device';
import { getImage } from '@/utils/comm';
import { gatewayType } from '@/views/media/Device/typings';
import { providerType } from '../const';
import { useMenuStore } from '@/store/menu';
import { usePermissionStore } from '@/store/permission';
const menuStory = useMenuStore();
const isPermission = usePermissionStore().hasPermission(
'link/AccessConfig:add',
);
type Emits = {
(e: 'update:visible', data: boolean): void;

View File

@ -1,6 +1,5 @@
<template>
<ParamsDropdown
placeholder="请选择"
:options="handleOptions"
:tabsOptions="tabOptions"
:metricOptions="upperOptions"
@ -10,7 +9,7 @@
valueName="id"
>
<template v-slot="{ label }">
<j-input :value="label" readonly />
<j-input :value="label" readonly placeholder="请选择" />
</template>
</ParamsDropdown>
</template>

View File

@ -113,9 +113,10 @@ const deleteItem = (_index: number) => {
};
const onTypeSelect = (key: any, _index: number) => {
const indexItem = tagList[_index];
const indexItem = tagList.value[_index];
indexItem.type = key;
tagList.value[_index] = indexItem;
onValueChange()
};
const onTagSelect = (_data: any, _index: number) => {
@ -127,6 +128,7 @@ const onTagSelect = (_data: any, _index: number) => {
handleItem({ ..._data, value: undefined, type: indexType }),
);
tagList.value = newList;
onValueChange()
};
watch(
@ -173,7 +175,7 @@ const onValueChange = () => {
const newValue = _data.map((item: any) => {
return {
column: item.id,
type: item?.valueType,
type: item?.type,
value: item?.value,
};
});
@ -181,10 +183,21 @@ const onValueChange = () => {
emits('change', [{ value: newValue, name: '标签' }], _data);
};
// onMounted(() => {
// // console.log(tagList.value, props.tagData, props.value)
// // emits('change', props.value, _data);
// })
onMounted(() => {
if(props.value?.[0]?.value){
const arr: any[] = []
props.value?.[0]?.value.map((item: any) => {
const _item = props.tagData.find(i => i.id === item.column)
if(_item){
arr.push({
..._item,
...item,
})
}
})
emits('change', props.value, arr);
}
})
</script>
<style lang="less" scoped>

View File

@ -31,7 +31,7 @@
/>
</j-form-item>
<j-form-item
v-else-if="modelRef.selector === 'tag'"
v-else-if="modelRef.selector === 'tag' && isTags"
name="selectorValues"
:rules="[{ required: true, message: '请选择标签' }]"
>
@ -80,6 +80,7 @@ import Tag from './Tag.vue';
import RelationSelect from './RelationSelect.vue';
import { getParams } from '../../../util';
import { handleParamsData } from '../../../components/Terms/util';
import _ from 'lodash';
const props = defineProps({
values: {
@ -107,6 +108,11 @@ const props = defineProps({
},
});
// option
const isTags = computed(() => {
return _.map(list.value, 'value').includes('tag');
});
// savedeviceDetail
const emits = defineEmits(['save', 'cancel']);
@ -281,17 +287,10 @@ const onTagChange = (val: any[], arr: any[]) => {
modelRef.source = 'fixed';
}
const tagName = arr.map((i, _index) => {
return `${_index !== 0 && _index !== (arr || []).length && i.type}${
i.name
}为${i.value}`;
const _type = (_index !== 0 && _index !== (arr || []).length && i.type) ? (i.type === 'and' ? '并且' : '或者') : '';
return `${_type}${i.name}${i.value}`;
});
console.log(tagName)
emits(
'save',
unref(modelRef),
{},
arr ? { tagName: tagName.join('') } : {},
);
emits('save', unref(modelRef), { tagName: tagName.join('') });
};
const onVariableChange = (val: any, node: any) => {
@ -315,7 +314,7 @@ watch(
() => props.productDetail,
async (newVal) => {
await sourceChangeEvent();
if (newVal) {
if (newVal?.id) {
filterType(newVal);
}
},

View File

@ -72,6 +72,7 @@ import { onlyMessage } from '@/utils/comm';
import { useSceneStore } from '@/store/scene';
import { storeToRefs } from 'pinia';
import { isActionChange } from '../../util';
const sceneStore = useSceneStore();
const { data } = storeToRefs(sceneStore);
@ -173,11 +174,17 @@ const onSave = (_data: any) => {
const onProductChange = (_val: any, bol: boolean) => {
if (!bol) {
DeviceModel.selectorValues = undefined;
DeviceModel.message = {
messageType: 'INVOKE_FUNCTION',
};
const flag = isActionChange(
JSON.parse(_val.metadata || '{}'),
DeviceModel?.message,
);
if (!flag) {
DeviceModel.message = {
messageType: 'INVOKE_FUNCTION',
};
}
}
productDetail.value = _val
productDetail.value = _val;
DeviceOptions.value.productName = _val?.name;
};

View File

@ -12,7 +12,8 @@ type DeviceModelType = {
message: {
properties?: any;
messageType: string;
inputs?: any[]
inputs?: any[];
functionId?: string;
}
}

View File

@ -16,6 +16,7 @@
}"
:params="params"
:gridColumn="2"
:noPagination="true"
:rowSelection="{
selectedRowKeys: _selectedRowKeys,
onChange: onSelectChange,

View File

@ -52,6 +52,7 @@
/>
</j-form-item>
</j-form>
<j-empty v-else style="margin: 20px 0" description="暂无模板变量" />
</template>
<script lang="ts" setup>

View File

@ -203,11 +203,11 @@ const onCancel = () => {
emit('cancel');
};
const onOk = async () => {
let _data = undefined
let _data = null
if(variable.value.length){
_data = await variableRef.value.onSave()
}
formModel.variables = _data || [];
formModel.variables = _data;
const { options, ...extra } = formModel;
emit('save', { ...extra }, { ...options });
};

View File

@ -66,7 +66,9 @@ const save = async () => {
if (formData) {
loading.value = true
const branches = data.value.branches?.filter(item => item)
const resp = await modify(data.value.id!, { ...data.value, branches }).then(res => res)
const resp: any = await modify(data.value.id!, { ...data.value, branches }).then(res => res).catch(() => {
loading.value = false
})
loading.value = false
if (resp.success) {
menuStore.jumpPage('rule-engine/Scene')

View File

@ -121,3 +121,33 @@ export const EventEmitter = {
return this
}
}
export const isActionChange = (_metadata: any, _message: any) => {
const _properties = _metadata?.properties || [];
const _functions = _metadata?.functions || [];
if (
_message?.messageType === 'READ_PROPERTY' &&
_message?.properties?.[0]
) {
const _item = _properties.find(
(i: any) => i.id === _message?.properties?.[0],
);
return _item?.id;
} else if (
_message?.messageType === 'INVOKE_FUNCTION' &&
_message?.functionId
) {
const _item = _functions.find(
(i: any) => i.id === _message?.functionId,
);
return _item?.id;
} else if (_message?.messageType === 'WRITE_PROPERTY') {
const _data = Object.keys(_message?.properties)?.[0]
if (_data) {
const _item = _functions.find((i: any) => i.id === _data);
return _item?.id;
}
return false;
}
return false;
};