Merge branch 'dev' into dev-dictionary
This commit is contained in:
commit
7e550f4558
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
|
@ -54,8 +54,7 @@ export const queryPointNoPaging = (data: any) =>
|
|||
|
||||
export const scanOpcUAList = (data: any) =>
|
||||
server.get(
|
||||
`/data-collect/opc/channel/${data.id}/nodes?nodeId=${
|
||||
data?.nodeId || ''
|
||||
`/data-collect/opc/channel/${data.id}/nodes?nodeId=${data?.nodeId || ''
|
||||
}`,
|
||||
);
|
||||
|
||||
|
@ -64,3 +63,7 @@ export const queryTypeList = () => server.get(`/data-collect/opc/data-types`);
|
|||
export const getProviders = () => server.get('/data-collect/channel/gateway/codec/providers')
|
||||
|
||||
export const getStates = () => server.get('/dictionary/running-state/items')
|
||||
|
||||
export const getSnapTypes = () => server.get('/s7/client/s7codecs/list')
|
||||
|
||||
export const getArea = () => server.get('/s7/client/s7area/list')
|
|
@ -57,4 +57,5 @@ export const protocolList = [
|
|||
{ label: 'OPC_UA', value: 'OPC_UA', alias: 'opc-ua' },
|
||||
{ label: 'MODBUS_TCP', value: 'MODBUS_TCP', alias: 'Modbus/TCP' },
|
||||
{ label: 'COLLECTOR_GATEWAY', value: 'COLLECTOR_GATEWAY', alias: 'GATEWAY' },
|
||||
{ label: 'S7', value: 'snap7', alias: 'snap7' },
|
||||
]
|
||||
|
|
|
@ -171,6 +171,12 @@
|
|||
v-model:value="formData.configuration.password"
|
||||
/>
|
||||
</j-form-item>
|
||||
<!-- <j-form-item
|
||||
v-if="formData.provider === 'snap7'"
|
||||
:name="['configuration', 'connect']"
|
||||
>
|
||||
<j-input v-model:value="formData.configuration.connect"/>
|
||||
</j-form-item> -->
|
||||
<j-form-item label="说明" name="description">
|
||||
<j-textarea
|
||||
placeholder="请输入说明"
|
||||
|
@ -239,6 +245,12 @@ const handleOk = async () => {
|
|||
params.configuration.deviceName = formData.value.configuration.deviceName
|
||||
}
|
||||
|
||||
if(params?.provider === 'snap7'){
|
||||
params.configuration={
|
||||
connect : false
|
||||
}
|
||||
}
|
||||
|
||||
params.circuitBreaker = {
|
||||
type: 'Ignore'
|
||||
}
|
||||
|
@ -304,7 +316,7 @@ const getProvidersList = async () => {
|
|||
if (resp.status === 200) {
|
||||
const arr = resp.result
|
||||
.filter(
|
||||
(item: any) => ['GATEWAY', 'Modbus/TCP', 'opc-ua'].includes(item.name),
|
||||
(item: any) => ['GATEWAY', 'Modbus/TCP', 'opc-ua','snap7'].includes(item.name),
|
||||
)
|
||||
.map((it: any) => it.name);
|
||||
const providers: any = protocolList.filter((item: any) =>
|
||||
|
|
|
@ -17,6 +17,7 @@ export const FormState: FormDataType = {
|
|||
password: '',
|
||||
deviceId: undefined,
|
||||
deviceName: undefined,
|
||||
connect:false,
|
||||
},
|
||||
description: '',
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
>
|
||||
<template #img>
|
||||
<slot name="img">
|
||||
<img :src="getImage('/channel.png')" />
|
||||
<img :src="ImageMap.get(slotProps.provider)" />
|
||||
</slot>
|
||||
</template>
|
||||
<template #content>
|
||||
|
@ -157,6 +157,17 @@ const params = ref<Record<string, any>>({});
|
|||
const visible = ref(false);
|
||||
const current = ref({});
|
||||
|
||||
const opcImage = getImage('/DataCollect/device-opcua.png');
|
||||
const modbusImage = getImage('/DataCollect/device-modbus.png');
|
||||
const s7Image = getImage('/DataCollect/s7.png')
|
||||
const gatewayImage = getImage('/DataCollect/gateway.png')
|
||||
const ImageMap = new Map()
|
||||
ImageMap.set('OPC_UA',opcImage)
|
||||
ImageMap.set('MODBUS_TCP',modbusImage)
|
||||
ImageMap.set('snap7',s7Image)
|
||||
ImageMap.set('COLLECTOR_GATEWAY',gatewayImage)
|
||||
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '通道名称',
|
||||
|
|
|
@ -10,6 +10,7 @@ export interface ConfigurationType {
|
|||
authType: string | undefined,
|
||||
deviceId: string | undefined,
|
||||
deviceName: string | undefined,
|
||||
connect:boolean | undefined
|
||||
}
|
||||
|
||||
export interface FormDataType {
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
|
||||
<template>
|
||||
<div class="top"><j-switch v-model:checked="deathArea" @change="handleDeathArea"></j-switch></div>
|
||||
<div v-if="deathArea">
|
||||
<div class="content">
|
||||
<j-radio-group v-model:value="tag" @change="handleTag">
|
||||
<j-space>
|
||||
<j-radio-button value="currentValue">固定值</j-radio-button>
|
||||
<j-radio-button value="this['currentValue'] - this['lastValue']">百分比</j-radio-button>
|
||||
</j-space>
|
||||
</j-radio-group>
|
||||
<j-tooltip v-if="tag !== 'currentValue'" title="最近一次采集到的值与上一次采集值比对,数值浮动在百分比以内时将被过滤">
|
||||
<AIcon type="QuestionCircleOutlined" style="margin-left: 10px;font-size: 18px;color: rgb(153, 153, 153)" />
|
||||
</j-tooltip>
|
||||
</div>
|
||||
<j-form-item-rest>
|
||||
<div v-if="tag === 'currentValue'" class="fixed">
|
||||
<j-row :gutter="5" align="middle">
|
||||
<j-col>
|
||||
<j-input-number v-model:value="_value[0].value" style="width: 100%" placeholder="请输入值"
|
||||
:max="_value[1] ? _value[1].value : 999999" :min="1" @change="handleChange" />
|
||||
</j-col>
|
||||
<j-col>
|
||||
<j-select v-model:value="_value[0].termType" :showArrow="false" :options="termTypeOptions"
|
||||
placeholder="符号" @change="handleChange" />
|
||||
</j-col>
|
||||
<template v-if="swap === 'range'">
|
||||
<j-col>点位值</j-col>
|
||||
<j-col>
|
||||
<j-select :showArrow="false" v-model:value="_value[1].termType" :options="termTypeOptions"
|
||||
placeholder="符号" @change="handleChange" />
|
||||
</j-col>
|
||||
<j-col>
|
||||
<j-input-number v-model:value="_value[1].value" style="width: 100%" placeholder="请输入值"
|
||||
:min="_value[0].value" @change="handleChange" />
|
||||
</j-col>
|
||||
|
||||
</template>
|
||||
<j-button @click="handleSwap">
|
||||
<AIcon type="SwapOutlined" />
|
||||
</j-button>
|
||||
</j-row>
|
||||
</div>
|
||||
<div v-else class="percent">
|
||||
<div class="percent-title">点位值</div>
|
||||
<j-input-number v-model:value="percentValue" style="width: 200px" addon-after="%" placeholder="请输入值"
|
||||
:min="1" @change="handlePercent" :max="65535" />
|
||||
</div>
|
||||
</j-form-item-rest>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
import { Form } from 'ant-design-vue';
|
||||
|
||||
const formItemContext = Form.useInjectFormItemContext()
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [{}]
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:value', 'change']);
|
||||
const _value = ref<any>(props.value)
|
||||
const deathArea = ref(false);
|
||||
const tag = ref<string>('currentValue')
|
||||
const swap = ref<string>('fix')
|
||||
const percentValue = ref()
|
||||
|
||||
|
||||
const termTypeOptions = computed(() => {
|
||||
if (_value.value?.length === 1) {
|
||||
return [
|
||||
{ label: '=', value: 'neq' },
|
||||
{ label: '>', value: 'lte' },
|
||||
{ label: '<', value: 'gte' },
|
||||
{ label: '≥', value: 'lt' },
|
||||
{ label: '≤', value: 'gt' },
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{ label: '<', value: 'gte' },
|
||||
{ label: '≤', value: 'gt' },
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
const handleDeathArea = (e: any) => {
|
||||
if (e) {
|
||||
_value.value = [{
|
||||
column: 'currentValue',
|
||||
value: undefined,
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
}]
|
||||
} else {
|
||||
_value.value = []
|
||||
}
|
||||
handleChange()
|
||||
}
|
||||
|
||||
const handleSwap = () => {
|
||||
if (swap.value === 'fix') {
|
||||
swap.value = 'range'
|
||||
_value.value = [
|
||||
{
|
||||
column: 'currentValue',
|
||||
value: '',
|
||||
termType: undefined,
|
||||
type: 'or',
|
||||
},
|
||||
{
|
||||
column: 'currentValue',
|
||||
value: '',
|
||||
termType: undefined,
|
||||
type: 'or',
|
||||
},
|
||||
]
|
||||
} else {
|
||||
swap.value = 'fix'
|
||||
_value.value = [{
|
||||
column: 'currentValue',
|
||||
value: undefined,
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
}]
|
||||
}
|
||||
handleChange()
|
||||
}
|
||||
|
||||
const handleTag = (e: any) => {
|
||||
if (e.target.value === 'currentValue') {
|
||||
swap.value = 'fix'
|
||||
_value.value = [{
|
||||
column: 'currentValue',
|
||||
value: undefined,
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
}]
|
||||
} else {
|
||||
_value.value = [
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue']*init/100`,
|
||||
value: 0,
|
||||
termType: 'lt',
|
||||
type: 'or',
|
||||
},
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue']*0/100`,
|
||||
value: 0,
|
||||
termType: 'gt',
|
||||
type: 'or',
|
||||
}
|
||||
]
|
||||
}
|
||||
handleChange()
|
||||
}
|
||||
|
||||
const handlePercent = (e: any) => {
|
||||
if (e) {
|
||||
_value.value = [
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue'] * ${e}/100`,
|
||||
value: 0,
|
||||
termType: 'lt',
|
||||
type: 'or',
|
||||
},
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue'] * ${e + 100}/100`,
|
||||
value: 0,
|
||||
termType: 'gt',
|
||||
type: 'or',
|
||||
}
|
||||
]
|
||||
}else{
|
||||
_value.value = [
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue'] * 1/100`,
|
||||
value: 0,
|
||||
termType: 'lt',
|
||||
type: 'or',
|
||||
},
|
||||
{
|
||||
column: `this['currentValue'] - this['lastValue'] * 1/100`,
|
||||
value: 0,
|
||||
termType: 'gt',
|
||||
type: 'or',
|
||||
}
|
||||
]
|
||||
}
|
||||
handleChange()
|
||||
}
|
||||
|
||||
const handlePercentProps = (arr: any) => {
|
||||
const obj = arr.find((item: any) => item.termType === 'lt')
|
||||
const val = obj.column.split('*')[1].split('/')[0]
|
||||
percentValue.value = val !== 'init' ? val : undefined
|
||||
}
|
||||
|
||||
const handleChange = () => {
|
||||
emits('update:value', _value.value)
|
||||
emits('change', _value.value)
|
||||
formItemContext.onFieldChange()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(val: any) => {
|
||||
if (val && val.length !== 0) {
|
||||
deathArea.value = true
|
||||
if (val && val[0]?.column === 'currentValue') {
|
||||
tag.value = 'currentValue'
|
||||
_value.value = val
|
||||
if (val.length === 2) {
|
||||
swap.value = 'range'
|
||||
}
|
||||
} else {
|
||||
handlePercentProps(val)
|
||||
tag.value = `this['currentValue'] - this['lastValue']`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
.top {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
|
||||
.fixed {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.percent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
|
||||
.percent-title {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,337 @@
|
|||
<template >
|
||||
<j-modal :title="data.id ? '编辑' : '新增'" :visible="true" width="700px" @cancel="handleCancel">
|
||||
<j-form :model="form" layout="vertical" ref="formRef">
|
||||
<j-form-item label="点位名称" name="name">
|
||||
<j-input placeholder="请输入点位名称" v-model:value="form.name" />
|
||||
</j-form-item>
|
||||
<j-form-item label="地址区域" :name="['configuration', 'daveArea']" :rules="{
|
||||
required: true,
|
||||
message: '请选择地址区域',
|
||||
trigger: 'change',
|
||||
}">
|
||||
<j-select v-model:value="form.configuration.daveArea" show-search placeholder="请选择地址区域"
|
||||
@change="daveAreaChange">
|
||||
<j-select-option v-for="item in dataAreaFilterList" :key="item.id" :value="item.id">{{
|
||||
item.name }}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
<j-form-item label="地址编号" :name="['configuration', 'areaNumber']" v-show="form.configuration.daveArea == 'DB'"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '请输入地址编号',
|
||||
trigger: 'blur',
|
||||
}">
|
||||
<j-input-number v-model:value="form.configuration.areaNumber" :maxlength="64" style="width: 100%"
|
||||
:max="65535" autocomplete="off" :disabled="form.configuration.daveArea == 'DB' && deviceType == 'S200'"
|
||||
placeholder="请输入地址编号" />
|
||||
</j-form-item>
|
||||
<j-form-item label="数据类型" :name="['configuration', 'type']" :rules="{
|
||||
required: true,
|
||||
message: '请选择数据类型',
|
||||
trigger: 'change',
|
||||
}">
|
||||
<j-select v-model:value="form.configuration.type" show-search placeholder="请选择数据类型"
|
||||
@change="chooseS7DataType">
|
||||
<j-select-option v-for="item in dataTypesList" :key="item.id" :value="item.id">{{
|
||||
item.name }}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
|
||||
<j-form-item v-if="!disabled" label="字符串长度(byte)" :name="['configuration', 'bytes']" :rules="{
|
||||
required: true,
|
||||
message: '请输入0~65535之间的正整数',
|
||||
trigger: 'blur',
|
||||
}">
|
||||
<j-input-number type="number" style="width: 100%" addon-after="字节" v-model:value="form.configuration.bytes"
|
||||
placeholder="请输入字符串长度" :precision="0" :controls="false" :maxlength="64" :disabled="disabled" />
|
||||
</j-form-item>
|
||||
|
||||
<j-form-item v-if="form.type == 'Bool'" label="位偏移量(bit)" :name="['configuration', 'bits']" :rules="{
|
||||
required: true,
|
||||
message: '请输入0~7之间的正整数',
|
||||
trigger: 'blur',
|
||||
}">
|
||||
<j-input-number type="number" style="width: 100%" addon-after="位" v-model:value="form.configuration.bits"
|
||||
placeholder="请输入位偏移量" :precision="0" :min="0" :max="7" :controls="false" :maxlength="2" />
|
||||
</j-form-item>
|
||||
|
||||
<j-form-item label="偏移量" :name="['configuration', 'offset']" :rules="{
|
||||
required: true,
|
||||
message: '请输入0~65535之间的正整数',
|
||||
trigger: 'blur',
|
||||
}">
|
||||
<j-input-number type="number" style="width: 100%" v-model:value="form.configuration.offset"
|
||||
placeholder="请输入偏移量" :precision="0" :min="0" :max="65535" :controls="false" :maxlength="64" />
|
||||
</j-form-item>
|
||||
<j-form-item label="缩放因子" :name="['configuration', 'scaleFactor']">
|
||||
<j-input-number type="number" style="width: 100%" v-model:value="form.configuration.scaleFactor"
|
||||
placeholder="缩放因子" :min="0" :max="65535" :controls="false" :maxlength="64" />
|
||||
</j-form-item>
|
||||
<j-form-item label="小数保留位数" :name="['configuration', 'scale']">
|
||||
<j-input-number type="number" style="width: 100%" v-model:value="form.configuration.scale"
|
||||
placeholder="缩放因子" :precision="0" :min="1" :max="65535" :controls="false" :maxlength="64" />
|
||||
</j-form-item>
|
||||
<j-form-item label="访问类型" name="accessModes" :rules="{
|
||||
required: true,
|
||||
message: '请选择访问类型',
|
||||
}">
|
||||
<j-card-select multiple :showImage="false" v-model:value="form.accessModes" :options="[
|
||||
{ label: '读', value: 'read' },
|
||||
{ label: '写', value: 'write' },
|
||||
]
|
||||
" :column="2" />
|
||||
</j-form-item>
|
||||
<j-form-item :name="['configuration', 'terms']" :rules="[{
|
||||
validator: Area,
|
||||
trigger: 'change',
|
||||
}]">
|
||||
<template #label>
|
||||
<j-space>
|
||||
<span>点位死区</span><span class="explain">点位死区范围内的异常数据将被过滤(请勿配置非数值类型)</span>
|
||||
</j-space>
|
||||
</template>
|
||||
<DeathArea v-model:value="form.configuration.terms" />
|
||||
</j-form-item>
|
||||
<j-form-item label="轮询任务" :name="['configuration', 'interval']">
|
||||
<p>
|
||||
采集频率<span style="margin-left: 5px; color: #9d9ea1; font-size: 12px">采集频率为0时不执行轮询任务</span>
|
||||
</p>
|
||||
<j-radio-group v-model:value="form.configuration.interval">
|
||||
<j-space>
|
||||
<j-radio-button :value="3000">3000ms</j-radio-button>
|
||||
<j-radio-button :value="6000">6000ms</j-radio-button>
|
||||
<j-radio-button :value="9000">9000ms</j-radio-button>
|
||||
<j-radio-button :value="Number(form.configuration.interval)" @click="intervalRef.visible = true">
|
||||
{{
|
||||
![3000, 6000, 9000].includes(form.configuration.interval)
|
||||
? form.configuration.interval + 'ms'
|
||||
: '自定义'
|
||||
}}
|
||||
</j-radio-button>
|
||||
</j-space>
|
||||
</j-radio-group>
|
||||
</j-form-item>
|
||||
<j-form-item name="features">
|
||||
<j-checkbox-group v-model:value="form.features">
|
||||
<j-checkbox value="changedOnly">只推送变化的数据</j-checkbox>
|
||||
</j-checkbox-group>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
<j-modal title="采集频率" :visible="intervalRef.visible" @cancel="handleCancelInterval" @ok="handleInterval">
|
||||
<j-form ref="formRef2" name="virtual-form" layout="vertical" :model="intervalRef">
|
||||
<j-form-item label="采集频率" name="interval" :rules="[
|
||||
{ required: true, message: '请输入采集频率' },
|
||||
]">
|
||||
<j-input-number type="tel" addonAfter="ms" v-model:value="intervalRef.interval" placeholder="请输入采集频率"
|
||||
:controls="false" :precision="0" :maxlength="64" />
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</j-modal>
|
||||
<template #footer>
|
||||
<j-button key="back" @click="handleCancel">取消</j-button>
|
||||
<PermissionButton key="submit" type="primary" :loading="loading" @click="handleOk" style="margin-left: 8px"
|
||||
:hasPermission="`DataCollect/Collector:${data.id ? 'update' : 'add'}`">
|
||||
确认
|
||||
</PermissionButton>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
savePoint,
|
||||
updatePoint,
|
||||
_validateField,
|
||||
getArea,
|
||||
getSnapTypes
|
||||
} from '@/api/data-collect/collector';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
import DeathArea from './DeathArea.vue';
|
||||
import { randomString } from '@/utils/utils';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}
|
||||
});
|
||||
|
||||
const dataAreaFilter = {
|
||||
S200: [
|
||||
'RELAY',
|
||||
'HIGH_SPEED',
|
||||
'SYSTEM_FLAGS',
|
||||
'ANALOG_INPUTS',
|
||||
'ANALOG_OUTPUTS',
|
||||
'I',
|
||||
'Q',
|
||||
'M',
|
||||
'IEC_COUNTERS',
|
||||
'IEC_TIMERS',
|
||||
],
|
||||
S1200: ['I', 'Q', 'M', 'DB'],
|
||||
S1500: ['I', 'Q', 'M', 'DB'],
|
||||
S300: ['I', 'Q', 'M', 'DB', 'C', 'T'],
|
||||
S400: ['I', 'Q', 'M', 'DB', 'C', 'T'],
|
||||
};
|
||||
const emit = defineEmits(['change']);
|
||||
const loading = ref(false);
|
||||
const formRef = ref<FormInstance>();
|
||||
const formRef2 = ref<FormInstance>();
|
||||
const deviceType = ref<string>('S200');
|
||||
const dataTypesList = ref<any[]>([]);
|
||||
const daveAreaList = ref<any>([]);
|
||||
|
||||
|
||||
|
||||
const form = ref<any>({
|
||||
name: props.data.name || '',
|
||||
configuration: props.data.configuration || {
|
||||
type: undefined,
|
||||
interval: 3000,
|
||||
areaNumber: undefined,
|
||||
terms: []
|
||||
},
|
||||
accessModes: [],
|
||||
features: [],
|
||||
description: props.data.description || '',
|
||||
// inheritBreaker: true,
|
||||
// pointKey: randomString(9)
|
||||
});
|
||||
const intervalRef = reactive({
|
||||
visible: false,
|
||||
interval: 3000,
|
||||
})
|
||||
|
||||
|
||||
/**选择S7点位数据类型 */
|
||||
const disabled = ref(true);
|
||||
const chooseS7DataType = (val: string) => {
|
||||
const result: any = dataTypesList.value.find((item: any) => item.id == val);
|
||||
form.value.configuration.bytes = result.length;
|
||||
disabled.value = result.length != 0;
|
||||
};
|
||||
|
||||
const daveAreaChange = (val: string) => {
|
||||
if (val === 'DB') {
|
||||
form.value.configuration.areaNumber = 1;
|
||||
} else {
|
||||
form.value.configuration.areaNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区信息
|
||||
*/
|
||||
const getAreaList = async () => {
|
||||
const res = await getArea();
|
||||
if (res.success) {
|
||||
daveAreaList.value = res.result;
|
||||
}
|
||||
};
|
||||
getAreaList();
|
||||
|
||||
/**
|
||||
* 获取数据类型
|
||||
*/
|
||||
const getTypes = async () => {
|
||||
const res: any = await getSnapTypes();
|
||||
dataTypesList.value = res.result;
|
||||
};
|
||||
getTypes();
|
||||
|
||||
const dataAreaFilterList = computed(() => {
|
||||
let result = daveAreaList.value.filter((item: any) =>
|
||||
dataAreaFilter[deviceType.value].includes(item.id),
|
||||
);
|
||||
if (deviceType.value == 'S200') {
|
||||
result.push({
|
||||
id: 'DB',
|
||||
name: '变量存储区(V)',
|
||||
address: '',
|
||||
});
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
const handleInterval = async () => {
|
||||
const res = await formRef2.value?.validate()
|
||||
if (res) {
|
||||
form.value.configuration.interval = res.interval
|
||||
intervalRef.visible = false
|
||||
}
|
||||
};
|
||||
const handleCancelInterval = () => {
|
||||
intervalRef.visible = false
|
||||
intervalRef.interval = 3000
|
||||
}
|
||||
|
||||
|
||||
const handleOk = async () => {
|
||||
const res = await formRef.value?.validate();
|
||||
|
||||
const params = {
|
||||
...res,
|
||||
inheritBreaker: true,
|
||||
pointKey: props.data.pointKey || randomString(9),
|
||||
provider:props.data.provider,
|
||||
collectorId:props.data.collectorId,
|
||||
accessModes:res?.accessModes.filter((item:any)=>item)
|
||||
}
|
||||
loading.value = true;
|
||||
const response = !props.data.id
|
||||
? await savePoint(params).catch(() => { })
|
||||
: await updatePoint(props.data.id, { ...props.data, ...params }).catch(() => { });
|
||||
emit('change', response?.status === 200);
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('change', false);
|
||||
};
|
||||
|
||||
const Area = (_: any, value: any): Promise<any> =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
console.log('value',value)
|
||||
if(value.length === 0){
|
||||
return resolve('')
|
||||
}else if(value.length === 1){
|
||||
return value[0].value && value[0].termType ? resolve('') : reject('请配置点位死区');
|
||||
}else{
|
||||
if(value[0].column === 'currentValue'){
|
||||
// value.forEach((item:any) => {
|
||||
// if(item.termType && item.value){
|
||||
// return resolve('')
|
||||
// }else{
|
||||
// return reject('请配置点位死区')
|
||||
// }
|
||||
// });
|
||||
const pass = value.every((item:any)=>item.termType && item.value)
|
||||
return pass ? resolve(''):reject('请配置点位死区')
|
||||
}else{
|
||||
value.forEach((item:any) => {
|
||||
if(item.column ===`this['currentValue'] - this['lastValue']*init/100`){
|
||||
return reject('请配置点位死区')
|
||||
}else{
|
||||
return resolve('')
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
form.value.features = props.data.features?.map((item:any)=>item.value)
|
||||
if(props.data.accessModes?.length!==0){
|
||||
form.value.accessModes = props.data.accessModes?.map((item:any)=>item.value)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.explain {
|
||||
color: #adadad;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
|
@ -20,7 +20,7 @@
|
|||
<template #headerTitle>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
v-if="['MODBUS_TCP', 'COLLECTOR_GATEWAY'].includes(data?.provider)"
|
||||
v-if="['MODBUS_TCP', 'COLLECTOR_GATEWAY','snap7'].includes(data?.provider)"
|
||||
type="primary"
|
||||
@click="handlAdd"
|
||||
hasPermission="DataCollect/Collector:add"
|
||||
|
@ -150,13 +150,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #img>
|
||||
<img
|
||||
:src="
|
||||
slotProps.provider === 'OPC_UA'
|
||||
? opcImage
|
||||
: modbusImage
|
||||
"
|
||||
/>
|
||||
<img :src="ImageMap.get(slotProps.provider)"/>
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="card-box-content">
|
||||
|
@ -319,6 +313,7 @@
|
|||
:data="current"
|
||||
@change="saveChange"
|
||||
/>
|
||||
<SaveS7 v-if="visible.saveS7" :data="current" @change="saveChange"/>
|
||||
<Scan v-if="visible.scan" :data="current" @change="saveChange" />
|
||||
</j-spin>
|
||||
</template>
|
||||
|
@ -345,6 +340,7 @@ import { getWebSocket } from '@/utils/websocket';
|
|||
import { map } from 'rxjs/operators';
|
||||
import dayjs from 'dayjs';
|
||||
import { responsiveArray } from 'ant-design-vue/lib/_util/responsiveObserve';
|
||||
import SaveS7 from './Save/SaveS7.vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
@ -357,12 +353,22 @@ const tableRef = ref<Record<string, any>>({});
|
|||
const params = ref<Record<string, any>>({});
|
||||
const opcImage = getImage('/DataCollect/device-opcua.png');
|
||||
const modbusImage = getImage('/DataCollect/device-modbus.png');
|
||||
const s7Image = getImage('/DataCollect/s7.png')
|
||||
const gatewayImage = getImage('/DataCollect/gateway.png')
|
||||
const ImageMap = new Map()
|
||||
ImageMap.set('OPC_UA',opcImage)
|
||||
ImageMap.set('MODBUS_TCP',modbusImage)
|
||||
ImageMap.set('snap7',s7Image)
|
||||
ImageMap.set('COLLECTOR_GATEWAY',gatewayImage)
|
||||
|
||||
|
||||
const visible = reactive({
|
||||
saveModBus: false,
|
||||
saveOPCUA: false,
|
||||
writePoint: false,
|
||||
batchUpdate: false,
|
||||
scan: false,
|
||||
saveS7:false
|
||||
});
|
||||
const current: any = ref({});
|
||||
const accessModesOption = ref();
|
||||
|
@ -474,15 +480,27 @@ const clickBatch = () => {
|
|||
};
|
||||
|
||||
const handlAdd = () => {
|
||||
if( props.data?.provider === 'snap7'){
|
||||
console.log(props.data)
|
||||
visible.saveS7 = true
|
||||
current.value = {
|
||||
collectorId: props.data?.id,
|
||||
provider: props.data?.provider
|
||||
}
|
||||
}else{
|
||||
visible.saveModBus = true;
|
||||
current.value = {
|
||||
collectorId: props.data?.id,
|
||||
provider: props.data?.provider || 'MODBUS_TCP',
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
const handlEdit = (data: any) => {
|
||||
if (data?.provider === 'OPC_UA') {
|
||||
visible.saveOPCUA = true;
|
||||
} else if(data?.provider === 'snap7'){
|
||||
visible.saveS7 = true
|
||||
}else{
|
||||
visible.saveModBus = true;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,33 @@
|
|||
placeholder="请输入采集器名称"
|
||||
v-model:value="formData.name"
|
||||
/>
|
||||
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="IP" :name="['configuration', 'host']" :rules="LeftTreeRules.host" >
|
||||
<j-input v-model:value="formData.configuration.host" autocomplete="off" placeholder="请输入通道IP" :disabled="false"/>
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="端口" :name="['configuration', 'port']" :rules="LeftTreeRules.port">
|
||||
<j-input-number style="width: 100%" v-model:value="formData.configuration.port" autocomplete="off" placeholder="请输入通道端口"/>
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="机架号" :name="['configuration', 'rack']" :rules="LeftTreeRules.rack">
|
||||
<j-input-number style="width: 100%" v-model:value="formData.configuration.rack" autocomplete="off" placeholder="请输入机架号" :maxlength="64" />
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="型号" :name="['configuration', 'type']" :rules="LeftTreeRules.type">
|
||||
<j-select v-model:value="formData.configuration.type" placeholder="请选择型号" @change="typeChange">
|
||||
<j-select-option v-for="item in typeOptions" :key="item.value" :value="item.value">{{ item.label }}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="槽位" :name="['configuration', 'slot']" :rules="LeftTreeRules.slot">
|
||||
<j-input-number style="width: 100%" v-model:value="formData.configuration.slot" autocomplete="off" placeholder="请输入槽位" :maxlength="64" :disabled="formData.configuration.type == 'S200' || formData.configuration.type == 'S1200'"/>
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="超时时间(毫秒)" :name="['configuration', 'timeout']" :rules="LeftTreeRules.timeout">
|
||||
<j-input-number style="width: 100%" v-model:value="formData.configuration.timeout" autocomplete="off" placeholder="请输入超时时间" :maxlength="64" />
|
||||
</j-form-item>
|
||||
<j-form-item v-if="provider === 'snap7'" label="数据读取方式" :name="['configuration', 'serializable']">
|
||||
<j-radio-group v-model:value="formData.configuration.serializable">
|
||||
<j-radio-button :value="false">并行</j-radio-button>
|
||||
<j-radio-button :value="true">串行</j-radio-button>
|
||||
</j-radio-group>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
v-if="provider === 'COLLECTOR_GATEWAY'"
|
||||
|
@ -133,6 +160,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<j-form-item
|
||||
v-if="provider !== 'snap7'"
|
||||
:name="['configuration', 'requestTimeout']"
|
||||
:rules="LeftTreeRules.requestTimeout"
|
||||
>
|
||||
|
@ -196,6 +224,14 @@ const props = defineProps({
|
|||
|
||||
const emit = defineEmits(['change']);
|
||||
|
||||
const typeOptions = ref([
|
||||
{value: 'S200', label: 'S7-200'},
|
||||
{value: 'S300', label: 'S7-300'},
|
||||
{value: 'S400', label: 'S7-400'},
|
||||
{value: 'S1200', label: 'S7-1200'},
|
||||
{value: 'S1500', label: 'S7-1500'},
|
||||
])
|
||||
|
||||
const id = props.data.id;
|
||||
const formRef = ref<FormInstance>();
|
||||
const provider = ref()
|
||||
|
@ -248,16 +284,17 @@ const endianData = computed(() => {
|
|||
}
|
||||
});
|
||||
|
||||
const formData = ref({
|
||||
const formData = ref<any>({
|
||||
channelId: undefined,
|
||||
name: '',
|
||||
collectorProvider: undefined,
|
||||
configuration: {
|
||||
unitId: '',
|
||||
type: 'LowerFrequency',
|
||||
type: undefined,
|
||||
endian: 'BIG',
|
||||
endianIn: 'BIG',
|
||||
requestTimeout: 2000,
|
||||
serializable:false,
|
||||
inheritBreakerSpec: {
|
||||
type: 'LowerFrequency',
|
||||
}
|
||||
|
@ -347,10 +384,16 @@ const filterOption = (input: string, option: any) => {
|
|||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
|
||||
const typeChange = (val:any)=>{
|
||||
if(val == 'S200' || val == 'S1200') {
|
||||
formData.value.configuration.slot = 1
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formData.value.channelId,
|
||||
(value) => {
|
||||
const dt = _channelListAll.value.find((item) => item.id === value);
|
||||
const dt:any = _channelListAll.value.find((item:any) => item.id === value);
|
||||
visibleUnitId.value = visibleEndian.value =
|
||||
dt?.provider && ['MODBUS_TCP', 'COLLECTOR_GATEWAY'].includes(dt?.provider);
|
||||
},
|
||||
|
|
|
@ -22,6 +22,28 @@ export const getState = (record: any) => {
|
|||
};
|
||||
|
||||
export const regOnlyNumber = new RegExp(/^\d+$/);
|
||||
export const regular = {
|
||||
// IPV4 IPV6 域名
|
||||
IP_Domain: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/,
|
||||
// IP地址
|
||||
IP_URL: /^((2((5[0-5])|([0-4]\d)))|([0-1]?\d{1,2}))(\.((2((5[0-5])|([0-4]\d)))|([0-1]?\d{1,2}))){3}$/,
|
||||
// 英文或者数字或者-或者_
|
||||
EN_NUMBER: /^[A-Za-z0-9_-]+$/,
|
||||
// 服务器地址
|
||||
HTTP_URL: /^http:|https:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/,
|
||||
// 域名
|
||||
DOMAIN_NAME: /^(?:(?:(?:[a-zA-z\-]+)\:\/{1,3})?(?:[a-zA-Z0-9])(?:[a-zA-Z0-9-\.]){1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+|\[(?:(?:(?:[a-fA-F0-9]){1,4})(?::(?:[a-fA-F0-9]){1,4}){7}|::1|::)\]|(?:(?:[0-9]{1,3})(?:\.[0-9]{1,3}){3}))(?:\:[0-9]{1,5})?$/,
|
||||
// 数字
|
||||
// NUMBER: /^[0-9]*[1-9][0-9]*$/,
|
||||
NUMBER: /^([1-9]\d*|[0]{1,1})$/,
|
||||
// 正数、负数、小数
|
||||
ASSIGNMENT: /^(\-)?\d+(\.\d+)?$/,
|
||||
//密码验证
|
||||
PASSWORD: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,}$/,
|
||||
//IP子网掩码
|
||||
IP_MASK: /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$/,
|
||||
CronRegEx: new RegExp('^\\s*($|#|\\w+\\s*=|(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?(?:,(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?)*)\\s+(\\?|\\*|(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?(?:,(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?)*)\\s+(\\?|\\*|(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\\?|\\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\\s+(\\?|\\*|(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?)*|\\?|\\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\\s)+(\\?|\\*|(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?(?:,(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?)*))$',)
|
||||
}
|
||||
|
||||
export const checkProviderData = {
|
||||
int8: 1,
|
||||
|
@ -150,6 +172,73 @@ export const OPCUARules = {
|
|||
description: [{ max: 200, message: '最多可输入200个字符' }],
|
||||
};
|
||||
|
||||
const validatorUrl = (rule:any, value:any, callback:any) => {
|
||||
const reg = regular.DOMAIN_NAME
|
||||
const reg1 = regular.IP_URL
|
||||
if(value === undefined || value === '' || value === null) {
|
||||
return Promise.reject("请输入通道Ip")
|
||||
} else {
|
||||
if(reg.test(value) === false && reg1.test(value) === false) {
|
||||
return Promise.reject("请输入正确的域名或ip地址")
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 校验通道端口
|
||||
*/
|
||||
const validator1 = (rule:any, value:any, callback:any) => {
|
||||
if(value === undefined || value === '' || value === null) {
|
||||
return Promise.reject("请输入通道端口")
|
||||
} else {
|
||||
if(value < 0 || value > 65535) {
|
||||
return Promise.reject("请输入0~65535的整数")
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验机架号
|
||||
*/
|
||||
const validator2 = (rule:any, value:any, callback:any) => {
|
||||
if(value === undefined || value === '' || value === null) {
|
||||
return Promise.reject("请输入机架号")
|
||||
} else {
|
||||
if(value < 0 || value > 65535) {
|
||||
return Promise.reject("请输入0~65535的整数")
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验槽位
|
||||
*/
|
||||
const validator3 = (rule:any, value:any, callback:any) => {
|
||||
if(value === undefined || value === '' || value === null) {
|
||||
return Promise.reject("请输入槽位")
|
||||
} else {
|
||||
if(value < 0 || value > 65535) {
|
||||
return Promise.reject("请输入0~65535的整数")
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验超时时间
|
||||
*/
|
||||
const validator4 = (rule:any, value:any, callback:any) => {
|
||||
if(value === undefined || value === '' || value === null) {
|
||||
return Promise.reject("请输入超时时间")
|
||||
} else {
|
||||
if(value < 0 || value > 65535) {
|
||||
return Promise.reject("请输入0~65535的整数")
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
export const LeftTreeRules = {
|
||||
channelId: [{ required: true, message: '请选择所属通道', trigger: 'blur' }],
|
||||
name: [
|
||||
|
@ -163,7 +252,7 @@ export const LeftTreeRules = {
|
|||
message: '请输入0-255之间的正整数',
|
||||
},
|
||||
],
|
||||
type: [{ required: true, message: '请选择处理方式', trigger: 'blur' }],
|
||||
// type: [{ required: true, message: '请选择处理方式', trigger: 'blur' }],
|
||||
endian: [
|
||||
{ required: true, message: '请选择双字高低位切换', trigger: 'blur' },
|
||||
],
|
||||
|
@ -172,7 +261,16 @@ export const LeftTreeRules = {
|
|||
],
|
||||
requestTimeout:[
|
||||
{ pattern: /^\d+$/, message:'请输入2000-60000的正整数',trigger: 'change'}
|
||||
]
|
||||
],
|
||||
host: [
|
||||
{ required: true, trigger: 'blur', validator: validatorUrl, },
|
||||
],
|
||||
port: [{ required: true, trigger: 'blur' , validator: validator1}],
|
||||
rack: [{ required: true, trigger: 'blur', validator: validator2 }],
|
||||
slot: [{ required: true, trigger: 'blur', validator: validator3 }],
|
||||
timeout: [{ required: true, trigger: 'blur', validator: validator4 }],
|
||||
type: [{required: true, trigger: 'change', message: '请选择型号'}],
|
||||
serializable: [{required: true, trigger: 'change', message: '请选择型号'}],
|
||||
};
|
||||
|
||||
export const FormTableColumns = [
|
||||
|
@ -216,3 +314,5 @@ export const FormTableColumns = [
|
|||
width: 50,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ const pickerTimeChange = () => {
|
|||
};
|
||||
|
||||
const echartsOptions = computed(() => {
|
||||
console.log(serverActive.value)
|
||||
console.log(serverActive.value,'---')
|
||||
const series = serverActive.value.length
|
||||
? serverActive.value.map((key) => setOptions(serverData.data, key))
|
||||
: typeDataLine
|
||||
|
@ -173,7 +173,7 @@ const getCPUEcharts = async (val: any) => {
|
|||
|
||||
const setOptions = (optionsData: any, key: string) => ({
|
||||
data: arrayReverse(optionsData[key]),
|
||||
name: key,
|
||||
name: key != 'undefined' ? key : '',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
|
|
|
@ -140,7 +140,7 @@ const getJVMEcharts = async (val: any) => {
|
|||
|
||||
const setOptions = (optionsData: any, key: string) => ({
|
||||
data: arrayReverse(optionsData[key]),
|
||||
name: key,
|
||||
// name: key!= 'undefined' ? key : '',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
|
|
|
@ -96,8 +96,8 @@ export default defineConfig(({ mode}) => {
|
|||
// target: 'http://192.168.32.244:8881',
|
||||
// target: 'http://192.168.32.163:8844', //张季本地
|
||||
// target: 'http://120.77.179.54:8844', // 120测试
|
||||
target: 'http://192.168.33.46:8844', // 本地开发环境
|
||||
// target: 'http://192.168.33.1:8845', // 社区版开发环境
|
||||
// target: 'http://192.168.33.46:8844', // 本地开发环境
|
||||
target: 'http://192.168.33.1:8845', // 社区版开发环境
|
||||
// target: 'http://192.168.32.5:8848', // 刘本地
|
||||
// target: 'http://192.168.32.187:8844', // 谭本地
|
||||
ws: 'ws://192.168.33.46:8844',
|
||||
|
|
Loading…
Reference in New Issue