iot-ui-vue/src/views/media/Device/Save/SaveProduct.vue

283 lines
9.6 KiB
Vue

<template>
<a-modal
v-model:visible="_vis"
title="快速添加"
cancelText="取消"
okText="确定"
@ok="handleOk"
@cancel="handleCancel"
:confirmLoading="btnLoading"
width="660px"
>
<a-form layout="vertical">
<a-form-item label="产品名称" v-bind="validateInfos.name">
<a-input
v-model:value="formData.name"
placeholder="请输入名称"
/>
</a-form-item>
<template v-if="channel === 'gb28181-2016' && formData.accessId">
<a-form-item
label="接入密码"
v-bind="validateInfos['configuration.access_pwd']"
>
<a-input-password
v-model:value="formData.configuration.access_pwd"
placeholder="请输入接入密码"
/>
</a-form-item>
<a-form-item label="流传输模式">
<a-select
v-model:value="formData.configuration.stream_mode"
placeholder="请选择流传输模式"
:options="streamMode"
/>
</a-form-item>
</template>
<a-form-item label="接入网关" v-bind="validateInfos.accessId">
<div class="gateway-box">
<div v-if="!gatewayList.length">
暂无数据,请先
<a-button type="link">
添加{{ providerType[props.channel] }} 接入网关
</a-button>
</div>
<div
class="gateway-item"
v-for="(item, index) in gatewayList"
:key="index"
>
<CardBox
@click="handleClick"
:active="_selectedRowKeys.includes(item.id)"
:value="item"
v-bind="item"
:status="item.state?.value"
:statusText="item.state?.text"
:statusNames="{
online: 'enabled',
offline: 'disabled',
}"
>
<template #img>
<slot name="img">
<img
:src="getImage('/device-access.png')"
/>
</slot>
</template>
<template #content>
<h3 class="card-item-content-title">
{{ item.name }}
</h3>
<div class="desc">{{ item.description }}</div>
<a-row v-if="props.channel === 'gb28181-2016'">
<a-col :span="12">
{{ item.channelInfo?.name }}
</a-col>
<a-col :span="12">
{{ item.protocolDetail.name }}
</a-col>
<a-col :span="12">
<p
v-for="(i, idx) in item.channelInfo
?.addresses"
:key="`${i.address}_address${idx}`"
>
<a-badge
:text="i.address"
:color="
i.health === -1
? 'red'
: 'green'
"
/>
</p>
</a-col>
</a-row>
<a-row v-else>
<a-col :span="24">
<div class="subtitle">
{{ item.protocolDetail.name }}
</div>
<p>
{{
item.protocolDetail.description
}}
</p>
</a-col>
</a-row>
</template>
</CardBox>
</div>
</div>
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup lang="ts">
import { Form, message } from 'ant-design-vue';
import { PropType } from 'vue';
import { streamMode } from '@/views/media/Device/const';
import DeviceApi from '@/api/media/device';
import { getImage } from '@/utils/comm';
import { gatewayType } from '@/views/media/Device/typings';
import { providerType } from '../const';
const useForm = Form.useForm;
type Emits = {
(e: 'update:visible', data: boolean): void;
(e: 'update:productId', data: string): void;
(e: 'close'): void;
};
const emit = defineEmits<Emits>();
const props = defineProps({
visible: { type: Boolean, default: false },
productId: { type: String, default: '' },
channel: { type: String, default: '' },
});
const _vis = computed({
get: () => props.visible,
set: (val) => emit('update:visible', val),
});
/**
* 获取接入网关
*/
const gatewayList = ref<gatewayType[]>([]);
const getGatewayList = async () => {
const params = {
pageSize: 100,
sorts: [{ name: 'createTime', order: 'desc' }],
terms: [{ column: 'provider', value: props.channel }],
};
const { result } = await DeviceApi.queryProvider(params);
gatewayList.value = result.data;
};
/**
* 点击接入网关, 获取对应配置
* @param e
*/
const _selectedRowKeys = ref<string[]>([]);
const handleClick = async (e: any) => {
_selectedRowKeys.value = [e.id];
formData.value.accessId = e.id;
formData.value.accessName = e.name;
formData.value.accessProvider = e.provider;
formData.value.messageProtocol = e.provider;
formData.value.protocolName = e.protocolDetail.name;
formData.value.transportProtocol = e.transport;
const { result } = await DeviceApi.getConfiguration(
props.channel,
e.transport,
);
console.log('result: ', result);
};
watch(
() => _vis.value,
(val) => {
if (val) {
getGatewayList();
formRules.value['configuration.access_pwd'][0].required =
props.channel === 'gb28181-2016';
validate();
} else {
emit('close');
}
},
);
// 表单数据
const formData = ref({
accessId: '',
accessName: '',
accessProvider: '',
configuration: {
access_pwd: '',
stream_mode: 'UDP',
},
deviceType: 'device',
messageProtocol: '',
name: '',
protocolName: '',
transportProtocol: '',
});
// 验证规则
const formRules = ref({
name: [{ required: true, message: '请输入产品名称' }],
'configuration.access_pwd': [{ required: true, message: '请输入接入密码' }],
accessId: [{ required: true, message: '请选择接入网关' }],
});
const { resetFields, validate, validateInfos, clearValidate } = useForm(
formData.value,
formRules.value,
);
/**
* 提交
*/
const btnLoading = ref(false);
const handleOk = () => {
// console.log('formData.value: ', formData.value);
validate()
.then(async () => {
btnLoading.value = true;
const res = await DeviceApi.saveProduct(formData.value);
if (res.success) {
emit('update:productId', res.result.id);
const deployResp = await DeviceApi.deployProductById(
res.result.id,
);
if (deployResp.success) {
message.success('操作成功');
handleCancel();
}
}
btnLoading.value = false;
})
.catch((err) => {
console.log('err: ', err);
});
};
const handleCancel = () => {
_vis.value = false;
resetFields();
};
</script>
<style lang="less" scoped>
.gateway-box {
max-height: 450px;
overflow-y: auto;
text-align: center;
.gateway-item {
padding: 16px;
.card-item-content-title,
.desc,
.subtitle {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.desc,
.subtitle {
margin-top: 10px;
color: #666;
font-weight: 400;
font-size: 12px;
}
}
}
</style>