feat: 流媒体服务 卡片列表/新增/编辑等功能
This commit is contained in:
parent
51b234b2b0
commit
2555f827ef
|
@ -0,0 +1,21 @@
|
||||||
|
import server from '@/utils/request';
|
||||||
|
|
||||||
|
|
||||||
|
export const save = (data: object) => server.post(`/media/server`, data);
|
||||||
|
|
||||||
|
export const update = (data: object) => server.patch(`/media/server`, data);
|
||||||
|
|
||||||
|
export const query = (data: object) => server.post(`/media/server/_query`, data);
|
||||||
|
|
||||||
|
export const queryDetail = (id: string) => server.get(`/media/server/${id}`);
|
||||||
|
|
||||||
|
export const remove = (id: string) => server.remove(`/media/server/${id}`);
|
||||||
|
|
||||||
|
export const queryProviders = () => server.get(`/media/server/providers`);
|
||||||
|
|
||||||
|
export const enalbe = (id: string) => server.post(`/media/server/${id}/_enable`);
|
||||||
|
|
||||||
|
export const disable = (id: string) => server.post(`/media/server/${id}/_disable`);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,391 @@
|
||||||
|
<template>
|
||||||
|
<page-container>
|
||||||
|
<a-card>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
class="form"
|
||||||
|
layout="vertical"
|
||||||
|
:model="formData"
|
||||||
|
name="basic"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<a-row :gutter="[16, 0]">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="流媒体名称"
|
||||||
|
name="name"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入流媒体名称',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最大可输入64个字符',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="formData.name"
|
||||||
|
placeholder="请输入流媒体名称"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="服务商"
|
||||||
|
name="provider"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择服务商',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
ref="select"
|
||||||
|
v-model:value="formData.provider"
|
||||||
|
:options="options"
|
||||||
|
placeholder="请选择服务商"
|
||||||
|
></a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item
|
||||||
|
label="密钥"
|
||||||
|
:name="['configuration', 'secret']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最大可输入64个字符',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input-password
|
||||||
|
placeholder="请输入密钥"
|
||||||
|
v-model:value="formData.configuration.secret"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8" class="form-item">
|
||||||
|
<a-form-item
|
||||||
|
:name="['configuration', 'apiHost']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入API Host',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: regDomain,
|
||||||
|
message: '请输入正确的IP地址或者域名',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label">
|
||||||
|
API Host
|
||||||
|
<span class="form-label-required">*</span>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
<p>调用流媒体接口时请求的服务地址</p>
|
||||||
|
</template>
|
||||||
|
<question-circle-outlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入API Host"
|
||||||
|
v-model:value="formData.configuration.apiHost"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4">
|
||||||
|
<a-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'apiPort']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
|
||||||
|
<a-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="请输入输入端口"
|
||||||
|
v-model:value="formData.configuration.apiPort"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8" class="form-item">
|
||||||
|
<a-form-item
|
||||||
|
:name="['configuration', 'rtpIp']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入RTP IP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: regDomain,
|
||||||
|
message: '请输入正确的IP地址或者域名',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label">
|
||||||
|
RTP IP
|
||||||
|
<span class="form-label-required">*</span>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>
|
||||||
|
<p>
|
||||||
|
视频设备将流推送到该IP地址下,部分设备仅支持IP地址,建议全是用IP地址
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<question-circle-outlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-input
|
||||||
|
placeholder="请输入RTP IP"
|
||||||
|
v-model:value="formData.configuration.rtpIp"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4" v-if="!checked">
|
||||||
|
<a-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'rtpPort']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
|
||||||
|
<a-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="请输入端口"
|
||||||
|
v-model:value="formData.configuration.rtpPort"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4" v-if="checked">
|
||||||
|
<a-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'dynamicRtpPortRange0']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入起始端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<a-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="
|
||||||
|
formData.configuration.dynamicRtpPortRange1
|
||||||
|
"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="起始端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.dynamicRtpPortRange0
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<div class="form-item-checked" v-if="checked">至</div>
|
||||||
|
<a-col :span="4" v-if="checked">
|
||||||
|
<a-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'dynamicRtpPortRange1']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入终止端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<a-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="
|
||||||
|
formData.configuration.dynamicRtpPortRange0
|
||||||
|
"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="终止端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.dynamicRtpPortRange1
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="4">
|
||||||
|
<a-form-item
|
||||||
|
class="form-item-checked2"
|
||||||
|
:name="['configuration', 'dynamicRtpPort']"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<a-checkbox
|
||||||
|
v-model:checked="
|
||||||
|
formData.configuration.dynamicRtpPort
|
||||||
|
"
|
||||||
|
>
|
||||||
|
动态端口
|
||||||
|
</a-checkbox>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item>
|
||||||
|
<a-button
|
||||||
|
v-if="view === 'false'"
|
||||||
|
class="form-submit"
|
||||||
|
html-type="submit"
|
||||||
|
type="primary"
|
||||||
|
@click.prevent="onSubmit"
|
||||||
|
:loading="loading"
|
||||||
|
>保存</a-button
|
||||||
|
>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
</page-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="CertificateDetail">
|
||||||
|
import { message, Form } from 'ant-design-vue';
|
||||||
|
import { queryProviders, queryDetail, save, update } from '@/api/media/stream';
|
||||||
|
import type { FormInstance } from 'ant-design-vue';
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
import { FormDataType } from '../type';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const view = route.query.view as string;
|
||||||
|
const id = route.params.id as string;
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const options = ref([]);
|
||||||
|
const checked = ref(false);
|
||||||
|
const regDomain =
|
||||||
|
/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/;
|
||||||
|
|
||||||
|
const formData = ref<FormDataType>({
|
||||||
|
name: '',
|
||||||
|
provider: undefined,
|
||||||
|
configuration: {
|
||||||
|
secret: '',
|
||||||
|
apiHost: '',
|
||||||
|
apiPort: '',
|
||||||
|
rtpIp: '',
|
||||||
|
rtpPort: '',
|
||||||
|
dynamicRtpPort: false,
|
||||||
|
// dynamicRtpPortRange: [],
|
||||||
|
dynamicRtpPortRange0: '',
|
||||||
|
dynamicRtpPortRange1: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
let data = await formRef.value?.validate();
|
||||||
|
let params = { ...data };
|
||||||
|
const { configuration } = data;
|
||||||
|
if (configuration.dynamicRtpPort) {
|
||||||
|
const { dynamicRtpPortRange0, dynamicRtpPortRange1 } = configuration;
|
||||||
|
delete configuration.dynamicRtpPortRange0;
|
||||||
|
delete configuration.dynamicRtpPortRange1;
|
||||||
|
params.configuration = {
|
||||||
|
...configuration,
|
||||||
|
dynamicRtpPortRange: [dynamicRtpPortRange0, dynamicRtpPortRange1],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
const response =
|
||||||
|
id === ':id' ? await save(params) : await update({ ...params, id });
|
||||||
|
if (response.status === 200) {
|
||||||
|
message.success('操作成功');
|
||||||
|
router.push('/iot/link/Stream');
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const detail = async (id: string) => {
|
||||||
|
loading.value = true;
|
||||||
|
const resp = await queryProviders();
|
||||||
|
options.value = resp.result.map((item) => ({
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
}));
|
||||||
|
if (id !== ':id') {
|
||||||
|
const res = await queryDetail(id);
|
||||||
|
if (res.success) {
|
||||||
|
const result = res.result as any;
|
||||||
|
formData.value = { ...result };
|
||||||
|
|
||||||
|
const { configuration } = result;
|
||||||
|
if (configuration.dynamicRtpPort) {
|
||||||
|
const { dynamicRtpPortRange } = configuration;
|
||||||
|
delete configuration.dynamicRtpPortRange;
|
||||||
|
formData.value.configuration = {
|
||||||
|
...configuration,
|
||||||
|
dynamicRtpPortRange0: dynamicRtpPortRange[0],
|
||||||
|
dynamicRtpPortRange1: dynamicRtpPortRange[1],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
detail(id);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => formData.value.configuration.dynamicRtpPort,
|
||||||
|
(value) => {
|
||||||
|
checked.value = value;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.form {
|
||||||
|
.form-submit {
|
||||||
|
background-color: @primary-color !important;
|
||||||
|
}
|
||||||
|
.form-item-checked {
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 35px;
|
||||||
|
}
|
||||||
|
.form-item-checked2 {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.form-label {
|
||||||
|
height: 30px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
.form-label-required {
|
||||||
|
color: red !important;
|
||||||
|
margin: 0 4px 0 -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,319 @@
|
||||||
|
<template>
|
||||||
|
<page-container>
|
||||||
|
<div>
|
||||||
|
<Search :columns="columns" target="search" @search="handleSearch" />
|
||||||
|
|
||||||
|
<JTable
|
||||||
|
ref="tableRef"
|
||||||
|
model="CARD"
|
||||||
|
:columns="columns"
|
||||||
|
:gridColumn="2"
|
||||||
|
:gridColumns="[1, 2]"
|
||||||
|
:request="query"
|
||||||
|
:defaultParams="{
|
||||||
|
sorts: [{ name: 'id', order: 'desc' }],
|
||||||
|
}"
|
||||||
|
:params="params"
|
||||||
|
>
|
||||||
|
<template #headerTitle>
|
||||||
|
<a-button type="primary" @click="handlAdd"
|
||||||
|
><plus-outlined />新增</a-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template #card="slotProps">
|
||||||
|
<CardBox
|
||||||
|
:showStatus="true"
|
||||||
|
:value="slotProps"
|
||||||
|
:actions="getActions(slotProps)"
|
||||||
|
v-bind="slotProps"
|
||||||
|
:class="
|
||||||
|
slotProps.state.value === 'disabled'
|
||||||
|
? 'tableCardDisabled'
|
||||||
|
: 'tableCardEnabled'
|
||||||
|
"
|
||||||
|
:status="slotProps.state.value"
|
||||||
|
:statusText="slotProps.state.text"
|
||||||
|
:statusNames="{
|
||||||
|
enabled: 'success',
|
||||||
|
disabled: 'error',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #img>
|
||||||
|
<slot name="img">
|
||||||
|
<img :src="getImage('/stream.png')" />
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<div class="card-item-content">
|
||||||
|
<a
|
||||||
|
@click="handlEye(slotProps.id)"
|
||||||
|
class="card-item-content-title-a"
|
||||||
|
>
|
||||||
|
{{ slotProps.name }}
|
||||||
|
</a>
|
||||||
|
<a-row class="card-item-content-box">
|
||||||
|
<a-col
|
||||||
|
:span="8"
|
||||||
|
class="card-item-content-text"
|
||||||
|
>
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
服务商
|
||||||
|
</div>
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{
|
||||||
|
slotProps.provider
|
||||||
|
}}</template>
|
||||||
|
{{ slotProps.provider }}
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
RTP IP
|
||||||
|
</div>
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{
|
||||||
|
slotProps.configuration
|
||||||
|
?.rtpIp
|
||||||
|
}}</template>
|
||||||
|
{{
|
||||||
|
slotProps.configuration
|
||||||
|
?.rtpIp
|
||||||
|
}}
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
API HOST
|
||||||
|
</div>
|
||||||
|
<div class="card-item-content-text">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{
|
||||||
|
slotProps.configuration
|
||||||
|
?.apiHost
|
||||||
|
}}</template>
|
||||||
|
{{
|
||||||
|
slotProps.configuration
|
||||||
|
?.apiHost
|
||||||
|
}}
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #actions="item">
|
||||||
|
<a-tooltip
|
||||||
|
v-bind="item.tooltip"
|
||||||
|
:title="item.disabled && item.tooltip.title"
|
||||||
|
>
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="item.popConfirm"
|
||||||
|
v-bind="item.popConfirm"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
>
|
||||||
|
<a-button :disabled="item.disabled">
|
||||||
|
<AIcon
|
||||||
|
type="DeleteOutlined"
|
||||||
|
v-if="item.key === 'delete'"
|
||||||
|
/>
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<template v-else>
|
||||||
|
<a-button
|
||||||
|
:disabled="item.disabled"
|
||||||
|
@click="item.onClick"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="DeleteOutlined"
|
||||||
|
v-if="item.key === 'delete'"
|
||||||
|
/>
|
||||||
|
<template v-else>
|
||||||
|
<AIcon :type="item.icon" />
|
||||||
|
<span>{{ item.text }}</span>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</CardBox>
|
||||||
|
</template>
|
||||||
|
</JTable>
|
||||||
|
</div>
|
||||||
|
</page-container>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup name="AccessConfigPage">
|
||||||
|
import type { ActionsType } from '@/components/Table/index.vue';
|
||||||
|
import { getImage } from '@/utils/comm';
|
||||||
|
import { query, remove, disable, enalbe } from '@/api/media/stream';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import Detail from './Detail/index.vue';
|
||||||
|
|
||||||
|
const tableRef = ref<Record<string, any>>({});
|
||||||
|
const router = useRouter();
|
||||||
|
const params = ref<Record<string, any>>({});
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
search: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
scopedSlots: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'state',
|
||||||
|
key: 'state',
|
||||||
|
search: {
|
||||||
|
type: 'select',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '禁用',
|
||||||
|
value: 'disabled',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '正常',
|
||||||
|
value: 'enabled',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
scopedSlots: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
|
||||||
|
if (!data) return [];
|
||||||
|
const state = data.state.value;
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
key: 'edit',
|
||||||
|
text: '编辑',
|
||||||
|
tooltip: {
|
||||||
|
title: '编辑',
|
||||||
|
},
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
onClick: () => {
|
||||||
|
handlEdit(data.id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'action',
|
||||||
|
text: state === 'enabled' ? '禁用' : '启用',
|
||||||
|
tooltip: {
|
||||||
|
title: state === 'enabled' ? '禁用' : '启用',
|
||||||
|
},
|
||||||
|
icon: state === 'enabled' ? 'StopOutlined' : 'CheckCircleOutlined',
|
||||||
|
popConfirm: {
|
||||||
|
title: `确认${state === 'enabled' ? '禁用' : '启用'}?`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
let res =
|
||||||
|
state === 'enabled'
|
||||||
|
? await disable(data.id)
|
||||||
|
: await enalbe(data.id);
|
||||||
|
if (res.success) {
|
||||||
|
message.success('操作成功');
|
||||||
|
tableRef.value?.reload();
|
||||||
|
} else {
|
||||||
|
message.error('操作失败!');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
text: '删除',
|
||||||
|
disabled: state === 'enabled',
|
||||||
|
tooltip: {
|
||||||
|
title: state === 'enabled' ? '正常的流媒体不能删除' : '删除',
|
||||||
|
},
|
||||||
|
popConfirm: {
|
||||||
|
title: '确认删除?',
|
||||||
|
onConfirm: async () => {
|
||||||
|
const res = await remove(data.id);
|
||||||
|
if (res.success) {
|
||||||
|
message.success('操作成功');
|
||||||
|
tableRef.value.reload();
|
||||||
|
} else {
|
||||||
|
message.error('操作失败!');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
icon: 'DeleteOutlined',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return actions;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlAdd = () => {
|
||||||
|
router.push({
|
||||||
|
path: `/iot/link/Stream/detail/:id`,
|
||||||
|
query: { view: false },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handlEdit = (id: string) => {
|
||||||
|
router.push({
|
||||||
|
path: `/iot/link/Stream/detail/${id}`,
|
||||||
|
query: { view: false },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handlEye = (id: string) => {
|
||||||
|
router.push({
|
||||||
|
path: `/iot/link/Stream/detail/${id}`,
|
||||||
|
query: { view: true },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
const handleSearch = (e: any) => {
|
||||||
|
params.value = e;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.tableCardDisabled {
|
||||||
|
width: 100%;
|
||||||
|
background: url('/images/access-config-diaabled.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableCardEnabled {
|
||||||
|
width: 100%;
|
||||||
|
background: url('/images/access-config-enabled.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-item-content {
|
||||||
|
min-height: 100px;
|
||||||
|
|
||||||
|
.card-item-content-title-a {
|
||||||
|
// color: #000 !important;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
overflow: hidden; //超出的文本隐藏
|
||||||
|
text-overflow: ellipsis; //溢出用省略号显示
|
||||||
|
white-space: nowrap; //溢出不换行
|
||||||
|
}
|
||||||
|
.card-item-content-box {
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
.card-item-content-text {
|
||||||
|
color: rgba(0, 0, 0, 0.75);
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden; //超出的文本隐藏
|
||||||
|
text-overflow: ellipsis; //溢出用省略号显示
|
||||||
|
white-space: nowrap; //溢出不换行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
export interface Configuration = {
|
||||||
|
secret: string,
|
||||||
|
apiHost: string,
|
||||||
|
apiPort: number,
|
||||||
|
rtpIp: string,
|
||||||
|
rtpPort: number,
|
||||||
|
dynamicRtpPort: boolean,
|
||||||
|
dynamicRtpPortRange?: array,
|
||||||
|
dynamicRtpPortRange0?: number,
|
||||||
|
dynamicRtpPortRange1?: number,
|
||||||
|
};
|
||||||
|
export type FormDataType = {
|
||||||
|
name: string;
|
||||||
|
provider: undefined;
|
||||||
|
configuration: Configuration;
|
||||||
|
id?: string;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue