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

This commit is contained in:
JiangQiming 2023-03-31 18:56:06 +08:00
commit 19944afb8b
15 changed files with 323 additions and 92 deletions

View File

@ -47,8 +47,7 @@ const emit = defineEmits<Emits>()
const props = defineProps({
value: {
type: Object as PropType<ModelValueType>,
default: () => ({
})
default: () => ({})
},
name: {
type: Array as PropType<(string| number)[]>,
@ -67,6 +66,15 @@ onMounted(() => {
})
})
watchEffect(() => {
if (typeof props.value.trueValue === 'boolean') {
props.value.trueValue = String(props.value.trueValue)
}
if (typeof props.value.falseValue === 'boolean') {
props.value.falseValue = String(props.value.falseValue)
}
})
</script>
<style lang="less" scoped>
.boolean-param {

View File

@ -413,23 +413,17 @@ const filterOption = (input: string, option: any) => {
const getProviderList = async () => {
const res: any = await queryCodecProvider();
providerListAll.value = res.result
.filter((i: any) => i.id !== 'property')
.filter((i: any) => i.id !== 'property' && i.id !== 'bool')
.map((item: any) => ({
value: item.id,
label: item.name,
}));
setProviderList(formData.value.configuration.function);
};
getProviderList();
const setProviderList = (value: string | undefined) => {
providerList.value =
value === 'HoldingRegisters'
? providerListAll.value
: providerListAll.value.filter(
(item: any) => item.value !== 'bool',
);
providerList.value = providerListAll.value;
};
watch(

View File

@ -281,9 +281,14 @@
<span>{{
getText(slotProps)
}}</span>
<span>{{
getInterval(slotProps)
}}</span>
<span
v-if="
getInterval(slotProps)
"
>{{
getInterval(slotProps)
}}</span
>
</div>
</Ellipsis>
</div>
@ -334,7 +339,7 @@ import SaveModBus from './Save/SaveModBus.vue';
import SaveOPCUA from './Save/SaveOPCUA.vue';
import Scan from './Scan/index.vue';
import { colorMap } from '../data.ts';
import { cloneDeep, isNumber } from 'lodash-es';
import { cloneDeep, isNumber, throttle } from 'lodash-es';
import { getWebSocket } from '@/utils/websocket';
import { map } from 'rxjs/operators';
import dayjs from 'dayjs';
@ -616,17 +621,6 @@ const handleClick = (dt: any) => {
}
};
//
let timer: any = null;
function throttle(fn: any, delay = 1000) {
if (timer == null) {
timer = setTimeout(() => {
fn();
clearTimeout(timer);
timer = null;
}, delay);
}
}
const subscribeProperty = (value: any) => {
const list = value.map((item: any) => item.id);
const id = `collector-${props.data?.channelId || 'channel'}-${
@ -643,7 +637,7 @@ const subscribeProperty = (value: any) => {
//
throttle(() => {
propertyValue.value.set(payload.pointId, payload);
});
}, 1000);
});
};

View File

@ -107,11 +107,7 @@
/>
</j-form-item>
<div style="color: #616161" v-if="visibleEndian">
<p>
当前内存布局:{{
endianMap.get(formData.configuration.endian)
}}{{ endianMap.get(formData.configuration.endianIn) }}
</p>
<p>当前内存布局: {{ endianData }}</p>
<p>
只有4字节数据类型(int32ieee754 float)
具有4种内存布局其它只有ABCDDCBA两种内存布局(以双字配置为准)
@ -182,10 +178,21 @@ const emit = defineEmits(['change']);
const id = props.data.id;
const formRef = ref<FormInstance>();
const endianMap = new Map([
['BIG', 'AB'],
['LITTLE', 'BA'],
]);
const endianData = computed(() => {
const { endian, endianIn } = formData.value.configuration;
if (endian) {
if (endianIn) {
if (endian === 'BIG') {
return endianIn === 'BIG' ? 'ABCD' : 'BADC';
} else {
return endianIn === 'BIG' ? 'CDBA' : 'DCBA';
}
} else {
return endian === 'BIG' ? 'ABCD' : 'DCBA';
}
}
});
const formData = ref({
channelId: undefined,

View File

@ -134,12 +134,8 @@ const submitData = async () => {
* 判断是否已有配置
*/
const judgeInitSet = async () => {
if (userInfo.$state.userInfos.username === 'admin') {
const resp: any = await getInit();
if (resp.status === 200 && resp.result.length) {
window.location.href = '/';
}
} else {
const resp: any = await getInit();
if (resp.status === 200 && resp.result.length) {
window.location.href = '/';
}
};

View File

@ -654,7 +654,7 @@ const saveData = () => {
onlyMessage('操作成功', 'success');
if (route.query.save) {
// @ts-ignore
window?.onTabSaveSuccess(resp.result);
window?.onTabSaveSuccess(resp);
window.close();
} else {
history.back();

View File

@ -1366,10 +1366,7 @@ const getDetail = () => {
...configuration,
};
} else {
dynamicValidateForm.cluster = {
...cloneDeep(FormStates2), //
...cluster,
};
dynamicValidateForm.cluster = cluster;
}
if (dynamicValidateForm.cluster.length === 1) {

View File

@ -319,9 +319,9 @@ const handleAdd = () => {
const tab: any = window.open(
`${origin}/#/iot/link/accessConfig/detail/:id?save=true&view=false&type=${props.channel}`,
);
tab.onTabSaveSuccess = async (value: string) => {
tab.onTabSaveSuccess = async (value: any) => {
await getGatewayList();
handleClick(value);
handleClick(value?.result);
};
};
</script>

View File

@ -123,6 +123,7 @@ export const EventEmitter = {
}
export const isActionChange = (_metadata: any, _message: any) => {
console.log(_metadata, _message)
const _properties = _metadata?.properties || [];
const _functions = _metadata?.functions || [];
if (
@ -144,7 +145,7 @@ export const isActionChange = (_metadata: any, _message: any) => {
} else if (_message?.messageType === 'WRITE_PROPERTY') {
const _data = Object.keys(_message?.properties)?.[0]
if (_data) {
const _item = _functions.find((i: any) => i.id === _data);
const _item = _properties.find((i: any) => i.id === _data);
return _item?.id;
}
return false;

View File

@ -258,7 +258,6 @@
<script setup lang="ts">
import PermissionButton from '@/components/PermissionButton/index.vue';
import { FormInstance, message } from 'ant-design-vue';
import ChooseIconDialog from '../components/ChooseIconDialog.vue';
import PermissChoose from '../components/PermissChoose.vue';

View File

@ -63,26 +63,29 @@
<script setup lang="ts">
import PermissionButton from '@/components/PermissionButton/index.vue';
import ButtonAddDialog from '../components/ButtonAddDialog.vue';
import { getMenuInfo_api, saveMenuInfo_api } from '@/api/system/menu';
import { message } from 'jetlinks-ui-components';
const permission = 'system/Menu';
//
const route = useRoute();
const routeParams = {
const routeParams = reactive({
id: route.params.id === ':id' ? '' : (route.params.id as string),
...route.query,
};
});
const paramsId = ref('');
//
const selectItem = ref<any>({});
const dialogVisible = ref(false);
const dialogTitle = ref<'查看' | '新增' | '编辑'>('新增');
const openDialog = (mode: '查看' | '新增' | '编辑', row: object) => {
if (!routeParams.id) return message.warning('请先新增菜单基本信息');
if (!routeParams.id && !paramsId.value) {
return message.warning('请先新增菜单基本信息');
}
console.log(3);
selectItem.value = { ...row };
dialogTitle.value = mode;
dialogVisible.value = true;
@ -147,6 +150,15 @@ type tableDataItem = {
description?: string;
permissions: object[];
};
watch(
() => route.params.id,
(value) => {
if (!!value) {
paramsId.value = value;
}
},
);
</script>
<style lang="less" scoped>

View File

@ -10,6 +10,7 @@
<j-radio-button
v-for="typeStr in iconKeys"
:value="typeStr"
:key="typeStr"
:class="{ active: selected === typeStr }"
>
<AIcon :type="typeStr" />
@ -19,6 +20,7 @@
</template>
<script setup lang="ts">
import iconKeys from './fields';
const emits = defineEmits(['confirm', 'update:visible']);
const props = defineProps<{
visible: boolean;
@ -28,38 +30,6 @@ const confirm = () => {
emits('confirm', selected.value);
emits('update:visible', false);
};
const iconKeys = [
'EyeOutlined',
'EditOutlined',
'PlusOutlined',
'DeleteOutlined',
'CheckCircleOutlined',
'StopOutlined',
'CheckOutlined',
'CloseOutlined',
'DownOutlined',
'ImportOutlined',
'ExportOutlined',
'SyncOutlined',
'ExclamationCircleOutlined',
'UploadOutlined',
'LoadingOutlined',
'PlusCircleOutlined',
'QuestionCircleOutlined',
'DisconnectOutlined',
'LinkOutlined',
'PoweroffOutlined',
'SwapOutlined',
'BugOutlined',
'BarsOutlined',
'ArrowDownOutlined',
'SmallDashOutlined',
'TeamOutlined',
'MenuUnfoldOutlined',
'MenuFoldOutlined',
'InfoCircleOutlined',
'SearchOutlined',
];
const selected = ref<string>('');
</script>

View File

@ -131,7 +131,6 @@ const permission = reactive({
const newProp = props.value.filter(
(item) => item.permission !== row.id,
);
if (newValue.length === row.options.length) {
row.checkAll = true;
row.indeterminate = false;
@ -146,6 +145,8 @@ const permission = reactive({
permission: row.id,
actions: newValue,
});
}else{
row.indeterminate = false
}
emits('update:value', newProp);

View File

@ -0,0 +1,246 @@
const direction = [
'StepBackward',
'StepForward',
'FastBackward',
'FastForward',
'Shrink',
'ArrowsAlt',
'Down',
'Up',
'Left',
'Right',
'CaretUp',
'CaretDown',
'CaretLeft',
'CaretRight',
'UpCircle',
'DownCircle',
'LeftCircle',
'RightCircle',
'DoubleRight',
'DoubleLeft',
'VerticalLeft',
'VerticalRight',
'VerticalAlignTop',
'VerticalAlignMiddle',
'VerticalAlignBottom',
'Forward',
'Backward',
'Rollback',
'Enter',
'Retweet',
'Swap',
'SwapLeft',
'SwapRight',
'ArrowUp',
'ArrowDown',
'ArrowLeft',
'ArrowRight',
'PlayCircle',
'UpSquare',
'DownSquare',
'LeftSquare',
'RightSquare',
'Login',
'Logout',
'MenuFold',
'MenuUnfold',
'BorderBottom',
'BorderHorizontal',
'BorderInner',
'BorderOuter',
'BorderLeft',
'BorderRight',
'BorderTop',
'BorderVerticle',
'PicCenter',
'PicLeft',
'PicRight',
'RadiusBottomleft',
'RadiusBottomright',
'RadiusUpleft',
'RadiusUpright',
'Fullscreen',
'FullscreenExit',
];
const suggestion = [
'Question',
'QuestionCircle',
'Plus',
'PlusCircle',
'Pause',
'PauseCircle',
'Minus',
'MinusCircle',
'PlusSquare',
'MinusSquare',
'Info',
'InfoCircle',
'Exclamation',
'ExclamationCircle',
'Close',
'CloseCircle',
'CloseSquare',
'Check',
'CheckCircle',
'CheckSquare',
'ClockCircle',
'Warning',
'IssuesClose',
'Stop',
];
const editor = [
'Edit',
'Form',
'Copy',
'Scissor',
'Delete',
'Snippets',
'Diff',
'Highlight',
'AlignCenter',
'AlignLeft',
'AlignRight',
'BgColors',
'Bold',
'Italic',
'Underline',
'Strikethrough',
'Redo',
'Undo',
'ZoomIn',
'ZoomOut',
'FontColors',
'FontSize',
'LineHeight',
'Dash',
'SmallDash',
'SortAscending',
'SortDescending',
'Drag',
'OrderedList',
'UnorderedList',
'RadiusSetting',
'ColumnWidth',
'ColumnHeight',
];
const data = [
'AreaChart',
'PieChart',
'BarChart',
'DotChart',
'LineChart',
'RadarChart',
'HeatMap',
'Fall',
'Rise',
'Stock',
'BoxPlot',
'Fund',
'Sliders',
];
// const logo = [
// 'Android',
// 'Apple',
// 'Windows',
// 'Ie',
// 'Chrome',
// 'Github',
// 'Aliwangwang',
// 'Dingding',
// 'WeiboSquare',
// 'WeiboCircle',
// 'TaobaoCircle',
// 'Html5',
// 'Weibo',
// 'Twitter',
// 'Wechat',
// 'Youtube',
// 'AlipayCircle',
// 'Taobao',
// 'Skype',
// 'Qq',
// 'MediumWorkmark',
// 'Gitlab',
// 'Medium',
// 'Linkedin',
// 'GooglePlus',
// 'Dropbox',
// 'Facebook',
// 'Codepen',
// 'CodeSandbox',
// 'CodeSandboxCircle',
// 'Amazon',
// 'Google',
// 'CodepenCircle',
// 'Alipay',
// 'AntDesign',
// 'AntCloud',
// 'Aliyun',
// 'Zhihu',
// 'Slack',
// 'SlackSquare',
// 'Behance',
// 'BehanceSquare',
// 'Dribbble',
// 'DribbbleSquare',
// 'Instagram',
// 'Yuque',
// 'Alibaba',
// 'Yahoo',
// 'Reddit',
// 'Sketch',
// ];
// 不显示,需要过滤
// const filter = [
// 'AlipaySquare',
// 'AmazonCircle',
// 'AmazonSquare',
// 'BehanceCircle',
// 'CodeSandboxSquare',
// 'CodeSandboxSquare',
// 'CodepenSquare',
// 'DingtalkCircle',
// 'DingtalkSquare',
// 'DribbbleCircle',
// 'DropboxCircle',
// 'DropboxSquare',
// 'Golden',
// 'GoogleCircle',
// 'GoogleSquare',
// 'GooglePlusCircle',
// 'GooglePlusSquare',
// 'GooglePlusSquare',
// 'IeCircle',
// 'IeSquare',
// 'MediumCircle',
// 'MediumSquare',
// 'QqCircle',
// 'QqSquare',
// 'RedditCircle',
// 'RedditSquare',
// 'Signal',
// 'SketchCircle',
// 'SketchSquare',
// 'SlackCircle',
// 'TaobaoSquare',
// 'TwitterCircle',
// 'TwitterSquare',
// 'ZhihuCircle',
// 'ZhihuSquare',
// 'createFromIconfontCN',
// 'default',
// 'getTwoToneColor',
// 'setTwoToneColor',
// ];
const datum = [...direction, ...suggestion, ...editor, ...data];
const iconKeys = datum.map((item) => item + 'Outlined');
export default iconKeys;

View File

@ -25,6 +25,7 @@
<AIcon type="PlusOutlined" />新增
</PermissionButton>
<j-button
v-if="admin"
style="margin-left: 12px"
@click="router.push('/system/Menu/Setting')"
>菜单配置</j-button
@ -79,10 +80,12 @@
<script setup lang="ts" name="Menu">
import PermissionButton from '@/components/PermissionButton/index.vue';
import { getMenuTree_api, delMenuInfo_api } from '@/api/system/menu';
import { message } from 'jetlinks-ui-components';
import dayjs from 'dayjs';
import { useUserInfo } from '@/store/userInfo';
const admin = useUserInfo().userInfos?.type.id === 'admin';
const permission = 'system/Menu';
@ -108,7 +111,7 @@ const columns = [
search: {
type: 'string',
},
width: 220,
// width: 220,
},
{
title: '页面地址',
@ -133,7 +136,8 @@ const columns = [
title: '说明',
dataIndex: 'describe',
key: 'describe',
width: 200,
ellipsis: true,
// width: 200,
},
{
title: '创建时间',
@ -150,8 +154,9 @@ const columns = [
title: '操作',
dataIndex: 'action',
key: 'action',
fixed: 'right',
scopedSlots: true,
width: 140,
width: 200,
},
];
const queryParams = ref({ terms: [] });
@ -246,6 +251,7 @@ const table = reactive({
<style lang="less" scoped>
.menu-container {
width: 100%;
:deep(.ant-table-cell) {
.ant-btn-link {
padding: 0;