Files
ndm-web-platform/src/components/device/device-card/ndm-server/server-update.vue

168 lines
6.0 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.
<script setup lang="ts">
import {
detailMediaServerApi,
detailVideoServerApi,
icmpEntityByDeviceId,
updateMediaServerApi,
updateVideoServerApi,
type NdmMediaServerUpdateVO,
type NdmServerResultVO,
type NdmServerUpdateVO,
type NdmVideoServerUpdateVO,
type Station,
} from '@/apis';
import { DEVICE_TYPE_LITERALS, tryGetDeviceType } from '@/enums';
import { useDeviceStore } from '@/stores';
import { parseErrorFeedback } from '@/utils';
import { useMutation } from '@tanstack/vue-query';
import { isCancel } from 'axios';
import destr from 'destr';
import { isString } from 'es-toolkit';
import { NButton, NCard, NFlex, NForm, NFormItem, NFormItemGi, NGrid, NInput, NSwitch, type FormInst, type FormRules } from 'naive-ui';
import { computed, onBeforeUnmount, ref, toRefs, useTemplateRef, watch } from 'vue';
const props = defineProps<{
ndmDevice: NdmServerResultVO;
station: Station;
}>();
const deviceStore = useDeviceStore();
const { ndmDevice, station } = toRefs(props);
const localDevice = ref<NdmServerUpdateVO>({ ...ndmDevice.value });
watch(ndmDevice, (newDevice) => {
localDevice.value = { ...newDevice };
});
const canEditDeviceId = computed(() => {
const { deviceId } = ndmDevice.value;
if (!isString(deviceId)) return true;
if (deviceId.length === 0) return true;
return false;
});
const validatorAbortController = ref<AbortController>(new AbortController());
const abortController = ref<AbortController>(new AbortController());
const formInst = useTemplateRef<FormInst>('formInst');
const formRules: FormRules = {
deviceId: {
trigger: ['input'],
asyncValidator: async (rule, value: string) => {
await validateDeviceIdDuplicated({ deviceId: value }).catch((error) => {
if (isCancel(error)) return;
throw error;
});
},
},
};
const { mutateAsync: validateDeviceIdDuplicated } = useMutation({
mutationFn: async (params: { deviceId?: string }) => {
const { deviceId } = params;
if (!deviceId) throw new Error('请输入设备ID');
const deviceIdPattern = /^\d{4}(09|11)\d{4}$/;
if (!deviceIdPattern.test(deviceId)) throw new Error('设备ID不符合规范');
// 如果没有修改设备ID则不做ID唯一性校验
if (deviceId === ndmDevice.value.deviceId) return;
validatorAbortController.value.abort();
validatorAbortController.value = new AbortController();
const icmpEntities = await icmpEntityByDeviceId(deviceId, {
stationCode: station.value.code,
signal: validatorAbortController.value.signal,
});
if (icmpEntities.length > 0) throw new Error('该设备ID已存在');
},
});
const { mutate: updateDevice, isPending } = useMutation({
mutationFn: async () => {
await formInst.value?.validate().catch(() => {
throw new Error('表单校验失败');
});
abortController.value.abort();
abortController.value = new AbortController();
const deviceType = tryGetDeviceType(localDevice.value.deviceType);
const stationCode = station.value.code;
const signal = abortController.value.signal;
if (deviceType === DEVICE_TYPE_LITERALS.ndmMediaServer) {
await updateMediaServerApi(localDevice.value as NdmMediaServerUpdateVO, { stationCode, signal });
return await detailMediaServerApi(`${localDevice.value.id}`, { stationCode, signal });
} else if (deviceType === DEVICE_TYPE_LITERALS.ndmVideoServer) {
await updateVideoServerApi(`${localDevice.value.id}`, localDevice.value as NdmVideoServerUpdateVO, { stationCode, signal });
return await detailVideoServerApi(`${localDevice.value.id}`, { stationCode, signal });
} else {
throw new Error('不是服务器设备');
}
},
onSuccess: (newDevice) => {
localDevice.value = { ...newDevice };
deviceStore.patchDevice(station.value.code, { ...newDevice });
window.$message.success('更新成功');
},
onError: (error) => {
if (isCancel(error)) return;
console.error(error);
const errorFeedback = parseErrorFeedback(error);
window.$message.error(errorFeedback);
},
});
onBeforeUnmount(() => {
validatorAbortController.value.abort();
abortController.value.abort();
});
</script>
<template>
<NCard hoverable size="small">
<template #default>
<NForm size="small" ref="formInst" :model="localDevice" :rules="formRules">
<NGrid>
<NFormItemGi span="8" label-placement="left" label="ICMP启用">
<NSwitch :value="destr(localDevice.icmpEnabled)" @update:value="(enabled: boolean) => (localDevice.icmpEnabled = enabled)" />
</NFormItemGi>
<NFormItemGi span="8" label-placement="left" label="SNMP启用">
<NSwitch :value="destr(localDevice.snmpEnabled)" @update:value="(enabled: boolean) => (localDevice.snmpEnabled = enabled)" />
</NFormItemGi>
</NGrid>
<NFormItem label-placement="left" label="设备ID" path="deviceId">
<NInput v-model:value="localDevice.deviceId" :disabled="!canEditDeviceId" />
</NFormItem>
<NFormItem label-placement="left" label="设备名称">
<NInput v-model:value="localDevice.name" />
</NFormItem>
<NFormItem label-placement="left" label="设备厂商">
<NInput v-model:value="localDevice.manufacturer" />
</NFormItem>
<NFormItem label-placement="left" label="型号">
<NInput v-model:value="localDevice.model" />
</NFormItem>
<NFormItem label-placement="left" label="团体字符串">
<NInput v-model:value="localDevice.community" />
</NFormItem>
<NFormItem label-placement="left" label="设备描述">
<NInput v-model:value="localDevice.description" />
</NFormItem>
<NFormItem label-placement="left" label="上游设备">
<NInput v-model:value="localDevice.linkDescription" />
</NFormItem>
</NForm>
</template>
<template #action>
<NFlex justify="end">
<NButton secondary size="small" :loading="isPending" @click="() => updateDevice()">更新</NButton>
</NFlex>
</template>
</NCard>
</template>
<style scoped lang="scss"></style>