iot-ui-vue/src/views/DataCollect/Collector/Point/Scan/Table.vue

349 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<j-form class="table" ref="formTableRef" :model="modelRef">
<j-table
v-if="modelRef.dataSource.length !== 0"
:dataSource="modelRef.dataSource"
:columns="FormTableColumns"
:scroll="{ y: 580 }"
>
<template #headerCell="{ column }">
<template
v-if="column.key === 'nodeId' || column.key === 'action'"
>
<span> {{ column.title }} </span>
</template>
<template v-else>
<span> {{ column.title }} </span>
<span style="margin-left: 5px; color: red">*</span>
</template>
</template>
<template #bodyCell="{ column: { dataIndex }, record, index }">
<template v-if="dataIndex === 'name'">
<j-form-item
:name="['dataSource', index, 'name']"
:rules="[
{
required: true,
message: '请输入',
},
{
validator: checkLength,
trigger: 'change',
},
]"
>
<j-input
v-model:value="record[dataIndex]"
placeholder="请输入"
allowClear
></j-input>
</j-form-item>
</template>
<template v-if="dataIndex === 'id'">
<j-form-item
v-show="false"
:name="['dataSource', index, 'id']"
>
<j-input
v-model:value="record[dataIndex]"
disabled
:bordered="false"
></j-input>
</j-form-item>
<div
style="
margin: -24px 0 0 10px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
"
>
<j-tooltip>
<template #title>{{ record[dataIndex] }}</template>
{{ record[dataIndex] }}
</j-tooltip>
</div>
</template>
<template v-if="dataIndex === 'accessModes'">
<j-form-item
class="form-item"
:name="['dataSource', index, 'accessModes', 'value']"
:rules="[
{
required: true,
message: '请选择',
},
]"
>
<j-select
style="width: 75%"
v-model:value="record[dataIndex].value"
placeholder="请选择"
allowClear
mode="multiple"
:filter-option="filterOption"
:options="[
{ label: '读', value: 'read' },
{ label: '写', value: 'write' },
{ label: '订阅', value: 'subscribe' },
]"
:disabled="index !== 0 && record[dataIndex].check"
@change="changeValue(index, dataIndex)"
>
</j-select>
<j-checkbox
style="margin-left: 5px"
v-if="index !== 0"
v-model:checked="record[dataIndex].check"
@click="changeCheckbox(index, dataIndex)"
>同上</j-checkbox
>
</j-form-item>
</template>
<template v-if="dataIndex === 'interval'">
<j-form-item
class="form-item"
:name="[
'dataSource',
index,
'configuration',
'interval',
'value',
]"
:rules="[
{
validator: checkLength,
trigger: 'change',
},
{
pattern: regOnlyNumber,
message: '请输入0或者正整数',
},
]"
>
<j-input
style="width: 60%"
v-model:value="
record.configuration[dataIndex].value
"
placeholder="请输入"
allowClear
addon-after="ms"
:disabled="
index !== 0 &&
record.configuration[dataIndex].check
"
@blur="changeValue(index, dataIndex)"
></j-input>
<j-checkbox
style="margin-left: 5px; margin-top: 5px"
v-show="index !== 0"
v-model:checked="
record.configuration[dataIndex].check
"
@click="changeCheckbox(index, dataIndex)"
>同上</j-checkbox
>
</j-form-item>
</template>
<template v-if="dataIndex === 'features'">
<j-form-item
class="form-item"
:name="['dataSource', index, 'features', 'value']"
:rules="[
{
required: true,
message: '请选择',
},
]"
>
<j-select
style="width: 40%"
v-model:value="record[dataIndex].value"
placeholder="请选择"
allowClear
:filter-option="filterOption"
:options="[
{
label: '是',
value: true,
},
{
label: '否',
value: false,
},
]"
:disabled="index !== 0 && record[dataIndex].check"
@change="changeValue(index, dataIndex)"
>
</j-select>
<j-checkbox
style="margin-left: 5px"
v-show="index !== 0"
v-model:checked="record[dataIndex].check"
@click="changeCheckbox(index, dataIndex)"
>同上</j-checkbox
>
</j-form-item>
</template>
<template v-if="dataIndex === 'action'">
<j-tooltip title="删除">
<j-popconfirm
title="确认删除"
@confirm="clickDelete(record.id)"
>
<a style="color: red"
><AIcon type="DeleteOutlined"
/></a>
</j-popconfirm>
</j-tooltip>
</template>
</template>
</j-table>
<j-empty v-else style="margin-top: 10%" />
</j-form>
</template>
<script lang="ts" setup>
import { FormTableColumns, regOnlyNumber } from '../../data';
import { Rule } from 'ant-design-vue/lib/form';
const props = defineProps({
data: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['change']);
const formTableRef = ref();
const defaultType = ['accessModes', 'interval', 'features'];
const modelRef: any = reactive({
dataSource: [],
});
const checkLength = (_rule: Rule, value: string): Promise<any> =>
new Promise(async (resolve, reject) => {
if (value) {
return String(value).length > 64
? reject('最多可输入64个字符')
: resolve('');
} else {
reject('请输入');
}
});
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
const clickDelete = (value: string) => {
emits('change', value);
};
const getTargetData = (index: number, type: string) => {
const { dataSource } = modelRef;
const Interval = type === 'interval';
return !Interval
? dataSource[index][type]
: dataSource[index].configuration[type];
};
const changeValue = (index: number, type: string) => {
const { dataSource } = modelRef;
const originData = getTargetData(index, type);
for (let i = index + 1; i < dataSource.length; i++) {
const targetType = getTargetData(i, type);
if (!targetType.check) return;
targetType.value = originData.value;
}
};
const changeCheckbox = async (index: number, type: string) => {
//Dom未更新完成需要用 setTimeout 或者 await nextTick() 处理
setTimeout(() => {
let startIndex = 0;
const { dataSource } = modelRef;
const currentCheck = getTargetData(index, type).check;
if (!currentCheck) return;
for (let i = index; i >= 0; i--) {
const preDataCheck = getTargetData(i, type).check;
if (!preDataCheck) {
startIndex = i;
break;
}
}
const originData = getTargetData(startIndex, type);
for (let i = startIndex; i < dataSource.length - 1; i++) {
const targetType = getTargetData(i + 1, type);
if (!targetType.check) return;
targetType.value = originData.value;
}
}, 0);
};
const validate = () => {
return new Promise((res, rej) => {
formTableRef.value
.validate()
.then(() => {
res(modelRef.dataSource);
})
.catch((err: any) => {
rej(err);
});
});
};
defineExpose({
validate,
});
watch(
() => props.data,
(value, preValue) => {
modelRef.dataSource = value;
// 有新增时同上数据
const vlength = value.length,
plength = preValue.length;
if (plength !== 0 && plength < vlength) {
defaultType.forEach((type) => {
vlength === 2
? changeValue(0, type)
: changeCheckbox(vlength - 1, type);
});
}
},
{ deep: true },
);
</script>
<style lang="less" scoped>
.table {
width: 100%;
min-width: 600px;
:deep(.ant-table-header) {
.ant-table-cell {
padding: 16px 5px;
}
}
:deep(.ant-table-tbody) {
.ant-table-cell {
padding: 24px 0 0 0;
}
.ant-table-cell-fix-right-first {
padding: 0 0 0 10px;
}
}
:deep(.ant-pagination) {
display: none;
}
}
.form-item {
display: flex;
}
</style>