Commit 298ab0caa620bac92e14699c2d58f621c800e358
Merge branch 'ww' into 'main'
fix: DEFECT-507 chart series useage stack attribute See merge request huang/yun-teng-iot-front!248
Showing
5 changed files
with
390 additions
and
1 deletions
| 1 | 1 | import { defHttp } from '/@/utils/http/axios'; |
| 2 | -import { CameraModel, CameraQueryParam } from './model/cameraModel'; | |
| 2 | +import { | |
| 3 | + CameraModel, | |
| 4 | + CameraQueryParam, | |
| 5 | + StreamingMediaDeleteParam, | |
| 6 | + StreamingQueryParam, | |
| 7 | + StreamingSubmitParam, | |
| 8 | +} from './model/cameraModel'; | |
| 3 | 9 | |
| 4 | 10 | enum CameraManagerApi { |
| 5 | 11 | CAMERA_POST_URL = '/video', |
| 6 | 12 | CAMERA_GET_URL = '/video', |
| 7 | 13 | CAMERA_DELETE_URL = '/video', |
| 8 | 14 | CAMERA_GET_DETAIL_URL = '/video', |
| 15 | + STERAMING_GET_URL = '/video/platform', | |
| 16 | + STERAMING_POST_URL = '/video/platform', | |
| 17 | + STERAMING_DELETE_URL = '/video/platform', | |
| 9 | 18 | } |
| 10 | 19 | |
| 11 | 20 | export const cameraPage = (params: CameraQueryParam) => { |
| ... | ... | @@ -42,3 +51,39 @@ export const getCameraManageDetail = (id: string) => { |
| 42 | 51 | url: CameraManagerApi.CAMERA_GET_DETAIL_URL + `/${id}`, |
| 43 | 52 | }); |
| 44 | 53 | }; |
| 54 | + | |
| 55 | +/** | |
| 56 | + * @description 获取流媒体列表 | |
| 57 | + * @param params | |
| 58 | + * @returns | |
| 59 | + */ | |
| 60 | +export const getStreamingMediaList = (params: StreamingQueryParam) => { | |
| 61 | + return defHttp.get({ | |
| 62 | + url: CameraManagerApi.STERAMING_GET_URL, | |
| 63 | + params, | |
| 64 | + }); | |
| 65 | +}; | |
| 66 | + | |
| 67 | +/** | |
| 68 | + * @description 更新/新增流媒体记录 | |
| 69 | + * @param params | |
| 70 | + * @returns | |
| 71 | + */ | |
| 72 | +export const createOrUpdateStreamingMediaRecord = (params: StreamingSubmitParam) => { | |
| 73 | + return defHttp.post({ | |
| 74 | + url: CameraManagerApi.STERAMING_POST_URL, | |
| 75 | + params, | |
| 76 | + }); | |
| 77 | +}; | |
| 78 | + | |
| 79 | +/** | |
| 80 | + * @description 删除流媒体记录 | |
| 81 | + * @param params | |
| 82 | + * @returns | |
| 83 | + */ | |
| 84 | +export const deleteStreamingMediaRecord = (params: StreamingMediaDeleteParam) => { | |
| 85 | + return defHttp.delete({ | |
| 86 | + url: CameraManagerApi.STERAMING_POST_URL, | |
| 87 | + params, | |
| 88 | + }); | |
| 89 | +}; | ... | ... |
| ... | ... | @@ -35,3 +35,34 @@ export interface CameraModel { |
| 35 | 35 | updater?: string; |
| 36 | 36 | videoUrl: string; |
| 37 | 37 | } |
| 38 | + | |
| 39 | +export interface StreamingMediaModel { | |
| 40 | + id: string; | |
| 41 | + creator: string; | |
| 42 | + createTime: string; | |
| 43 | + enabled: boolean; | |
| 44 | + tenantId: string; | |
| 45 | + type: number; | |
| 46 | + host: string; | |
| 47 | + appKey: string; | |
| 48 | + appSecret: string; | |
| 49 | + ssl: number; | |
| 50 | +} | |
| 51 | + | |
| 52 | +export interface StreamingQueryParam { | |
| 53 | + host?: string; | |
| 54 | +} | |
| 55 | + | |
| 56 | +export interface StreamingSubmitParam { | |
| 57 | + type: number; | |
| 58 | + ssl: number; | |
| 59 | + host: string; | |
| 60 | + appKey: string; | |
| 61 | + appSecret: string; | |
| 62 | + id?: string; | |
| 63 | +} | |
| 64 | + | |
| 65 | +export interface StreamingMediaDeleteParam { | |
| 66 | + tenantId?: string; | |
| 67 | + ids: string[]; | |
| 68 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { formDetailSchema } from './config.data'; | |
| 5 | + import type { DrawerParams } from './config.data'; | |
| 6 | + import { ref, computed, unref } from 'vue'; | |
| 7 | + import { createOrUpdateStreamingMediaRecord } from '/@/api/camera/cameraManager'; | |
| 8 | + import { StreamingMediaModel } from '/@/api/camera/model/cameraModel'; | |
| 9 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
| 10 | + | |
| 11 | + const emit = defineEmits({ | |
| 12 | + success: null, | |
| 13 | + }); | |
| 14 | + | |
| 15 | + const createFlag = ref(false); | |
| 16 | + | |
| 17 | + const getDrawerTitle = computed(() => `${unref(createFlag) ? '新增' : '编辑'}流媒体配置`); | |
| 18 | + | |
| 19 | + let id: Nullable<string> = null; | |
| 20 | + | |
| 21 | + const [register, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({ | |
| 22 | + schemas: formDetailSchema, | |
| 23 | + labelWidth: 90, | |
| 24 | + showActionButtonGroup: false, | |
| 25 | + }); | |
| 26 | + | |
| 27 | + const [registerDrawer, { setDrawerProps }] = useDrawerInner((data: DrawerParams) => { | |
| 28 | + createFlag.value = data.createFlag; | |
| 29 | + if (!unref(createFlag)) { | |
| 30 | + id = data.record!.id; | |
| 31 | + setFieldsValue(data.record); | |
| 32 | + } else { | |
| 33 | + resetFields(); | |
| 34 | + } | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const handleSubmit = async () => { | |
| 38 | + await validate(); | |
| 39 | + let value = getFieldsValue() as StreamingMediaModel; | |
| 40 | + let message = '修改成功'; | |
| 41 | + if (unref(createFlag)) message = '添加成功'; | |
| 42 | + else value = { ...value, id: id! }; | |
| 43 | + try { | |
| 44 | + setDrawerProps({ | |
| 45 | + confirmLoading: true, | |
| 46 | + }); | |
| 47 | + await createOrUpdateStreamingMediaRecord(value); | |
| 48 | + const { createMessage } = useMessage(); | |
| 49 | + createMessage.success(message); | |
| 50 | + emit('success'); | |
| 51 | + } catch (e) { | |
| 52 | + } finally { | |
| 53 | + setDrawerProps({ | |
| 54 | + confirmLoading: false, | |
| 55 | + }); | |
| 56 | + } | |
| 57 | + }; | |
| 58 | +</script> | |
| 59 | + | |
| 60 | +<template> | |
| 61 | + <BasicDrawer | |
| 62 | + @register="registerDrawer" | |
| 63 | + v-bind="$attrs" | |
| 64 | + showFooter | |
| 65 | + :title="getDrawerTitle" | |
| 66 | + width="30%" | |
| 67 | + @ok="handleSubmit" | |
| 68 | + > | |
| 69 | + <BasicForm @register="register" /> | |
| 70 | + </BasicDrawer> | |
| 71 | +</template> | ... | ... |
src/views/camera/streaming/config.data.ts
0 → 100644
| 1 | +import type { StreamingMediaModel } from '/@/api/camera/model/cameraModel'; | |
| 2 | +import { BasicColumn, FormSchema } from '/@/components/Table'; | |
| 3 | + | |
| 4 | +export interface DrawerParams { | |
| 5 | + createFlag: boolean; | |
| 6 | + record?: StreamingMediaModel; | |
| 7 | +} | |
| 8 | + | |
| 9 | +export const streamingMediaTypeMapping = { | |
| 10 | + 0: '海康ISC平台', | |
| 11 | +}; | |
| 12 | + | |
| 13 | +export const streamingMediaSSLMapping = { | |
| 14 | + 0: 'http', | |
| 15 | + 1: 'https', | |
| 16 | +}; | |
| 17 | + | |
| 18 | +export const columnSchema: BasicColumn[] = [ | |
| 19 | + { | |
| 20 | + title: '平台类型', | |
| 21 | + dataIndex: 'type', | |
| 22 | + width: 80, | |
| 23 | + slots: { customRender: 'type' }, | |
| 24 | + }, | |
| 25 | + { | |
| 26 | + title: '部署环境', | |
| 27 | + dataIndex: 'ssl', | |
| 28 | + width: 80, | |
| 29 | + slots: { customRender: 'ssl' }, | |
| 30 | + }, | |
| 31 | + { | |
| 32 | + title: '平台地址', | |
| 33 | + dataIndex: 'host', | |
| 34 | + width: 80, | |
| 35 | + }, | |
| 36 | + { | |
| 37 | + title: '用户Key', | |
| 38 | + dataIndex: 'appKey', | |
| 39 | + width: 80, | |
| 40 | + }, | |
| 41 | + { | |
| 42 | + title: '用户密钥', | |
| 43 | + dataIndex: 'appSecret', | |
| 44 | + width: 80, | |
| 45 | + }, | |
| 46 | +]; | |
| 47 | + | |
| 48 | +export const formSchema: FormSchema[] = [ | |
| 49 | + { | |
| 50 | + field: 'host', | |
| 51 | + label: '平台地址', | |
| 52 | + component: 'Input', | |
| 53 | + colProps: { span: 8 }, | |
| 54 | + }, | |
| 55 | +]; | |
| 56 | + | |
| 57 | +export const formDetailSchema: FormSchema[] = [ | |
| 58 | + { | |
| 59 | + label: '平台类型', | |
| 60 | + field: 'type', | |
| 61 | + component: 'Select', | |
| 62 | + rules: [{ required: true, message: '平台类型为必填项', type: 'number' }], | |
| 63 | + componentProps: { | |
| 64 | + options: [{ label: '海康ISC平台', value: 0 }], | |
| 65 | + placeholder: '请输入选择平台类型', | |
| 66 | + }, | |
| 67 | + }, | |
| 68 | + { | |
| 69 | + label: '部署环境', | |
| 70 | + field: 'ssl', | |
| 71 | + component: 'RadioGroup', | |
| 72 | + rules: [{ required: true, message: '流媒体部署环境为必填项', type: 'number' }], | |
| 73 | + componentProps: { | |
| 74 | + options: [ | |
| 75 | + { label: 'http', value: 0 }, | |
| 76 | + { label: 'https', value: 1 }, | |
| 77 | + ], | |
| 78 | + }, | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + label: '平台地址', | |
| 82 | + field: 'host', | |
| 83 | + component: 'Input', | |
| 84 | + helpMessage: ['平台IP + 端口'], | |
| 85 | + rules: [{ required: true, message: '平台地址为必填项' }], | |
| 86 | + componentProps: { | |
| 87 | + placeholder: '请输入平台地址', | |
| 88 | + }, | |
| 89 | + }, | |
| 90 | + { | |
| 91 | + label: '用户Key', | |
| 92 | + field: 'appKey', | |
| 93 | + component: 'Input', | |
| 94 | + rules: [{ required: true, message: '用户Key为必填项' }], | |
| 95 | + componentProps: { | |
| 96 | + placeholder: '请输入用户Key', | |
| 97 | + }, | |
| 98 | + }, | |
| 99 | + { | |
| 100 | + label: '用户密钥', | |
| 101 | + field: 'appSecret', | |
| 102 | + component: 'Input', | |
| 103 | + rules: [{ required: true, message: '用户密钥为必填项' }], | |
| 104 | + componentProps: { | |
| 105 | + placeholder: '请输入用户密钥', | |
| 106 | + }, | |
| 107 | + }, | |
| 108 | +]; | ... | ... |
src/views/camera/streaming/index.vue
0 → 100644
| 1 | +<script lang="ts" setup> | |
| 2 | + import { PageWrapper } from '/@/components/Page'; | |
| 3 | + import { useDrawer } from '/@/components/Drawer'; | |
| 4 | + import type { DrawerParams } from './config.data'; | |
| 5 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
| 6 | + import { | |
| 7 | + columnSchema, | |
| 8 | + formSchema, | |
| 9 | + streamingMediaTypeMapping, | |
| 10 | + streamingMediaSSLMapping, | |
| 11 | + } from './config.data'; | |
| 12 | + import SteramingDrawer from './SteramingDrawer.vue'; | |
| 13 | + import { getStreamingMediaList, deleteStreamingMediaRecord } from '/@/api/camera/cameraManager'; | |
| 14 | + import { StreamingMediaModel } from '/@/api/camera/model/cameraModel'; | |
| 15 | + import { ref } from 'vue'; | |
| 16 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
| 17 | + | |
| 18 | + const enabledBatchDelete = ref(true); | |
| 19 | + const [register, { reload, getSelectRowKeys }] = useTable({ | |
| 20 | + title: '流媒体列表', | |
| 21 | + api: getStreamingMediaList, | |
| 22 | + columns: columnSchema, | |
| 23 | + showIndexColumn: false, | |
| 24 | + clickToRowSelect: false, | |
| 25 | + formConfig: { | |
| 26 | + labelWidth: 120, | |
| 27 | + schemas: formSchema, | |
| 28 | + }, | |
| 29 | + useSearchForm: true, | |
| 30 | + showTableSetting: true, | |
| 31 | + bordered: true, | |
| 32 | + rowKey: 'id', | |
| 33 | + actionColumn: { | |
| 34 | + width: 100, | |
| 35 | + title: '操作', | |
| 36 | + dataIndex: 'action', | |
| 37 | + slots: { customRender: 'action' }, | |
| 38 | + fixed: 'right', | |
| 39 | + }, | |
| 40 | + | |
| 41 | + rowSelection: { | |
| 42 | + type: 'checkbox', | |
| 43 | + onChange(rowKeys: string[]) { | |
| 44 | + enabledBatchDelete.value = rowKeys.length <= 0; | |
| 45 | + }, | |
| 46 | + }, | |
| 47 | + }); | |
| 48 | + | |
| 49 | + const [registerDrawer, { openDrawer }] = useDrawer(); | |
| 50 | + | |
| 51 | + const handleCreateStreamingMedia = () => { | |
| 52 | + openDrawer<DrawerParams>(true, { | |
| 53 | + createFlag: true, | |
| 54 | + }); | |
| 55 | + }; | |
| 56 | + | |
| 57 | + const handleUpdateStreamingMedia = (record: StreamingMediaModel) => { | |
| 58 | + openDrawer<DrawerParams>(true, { | |
| 59 | + createFlag: false, | |
| 60 | + record, | |
| 61 | + }); | |
| 62 | + }; | |
| 63 | + | |
| 64 | + const handleDeleteRecord = async (record?: StreamingMediaModel) => { | |
| 65 | + let ids = record ? [record.id] : getSelectRowKeys(); | |
| 66 | + try { | |
| 67 | + await deleteStreamingMediaRecord({ ids }); | |
| 68 | + enabledBatchDelete.value = true; | |
| 69 | + const { createMessage } = useMessage(); | |
| 70 | + createMessage.success('删除成功'); | |
| 71 | + } catch (e) { | |
| 72 | + } finally { | |
| 73 | + reload(); | |
| 74 | + } | |
| 75 | + }; | |
| 76 | + | |
| 77 | + const handleDrawerSubmitSuccess = () => { | |
| 78 | + openDrawer(false); | |
| 79 | + reload(); | |
| 80 | + }; | |
| 81 | +</script> | |
| 82 | + | |
| 83 | +<template> | |
| 84 | + <PageWrapper dense contentFullHeight> | |
| 85 | + <BasicTable @register="register"> | |
| 86 | + <template #type="{ record }"> | |
| 87 | + <span>{{ streamingMediaTypeMapping[record.type] }}</span> | |
| 88 | + </template> | |
| 89 | + <template #ssl="{ record }"> | |
| 90 | + <span>{{ streamingMediaSSLMapping[record.ssl] }}</span> | |
| 91 | + </template> | |
| 92 | + <template #action="{ record }"> | |
| 93 | + <TableAction | |
| 94 | + :actions="[ | |
| 95 | + { | |
| 96 | + label: '编辑', | |
| 97 | + auth: 'api:yt:streaming:update', | |
| 98 | + icon: 'clarity:note-edit-line', | |
| 99 | + onClick: handleUpdateStreamingMedia.bind(null, record), | |
| 100 | + }, | |
| 101 | + { | |
| 102 | + label: '删除', | |
| 103 | + auth: 'api:yt:streaming:delete', | |
| 104 | + icon: 'ant-design:delete-outlined', | |
| 105 | + color: 'error', | |
| 106 | + popConfirm: { | |
| 107 | + title: '是否确认删除', | |
| 108 | + confirm: handleDeleteRecord.bind(null, record), | |
| 109 | + }, | |
| 110 | + }, | |
| 111 | + ]" | |
| 112 | + /> | |
| 113 | + </template> | |
| 114 | + <template #toolbar> | |
| 115 | + <Authority value="api:yt:streaming:post"> | |
| 116 | + <a-button type="primary" @click="handleCreateStreamingMedia">新增流媒体</a-button> | |
| 117 | + </Authority> | |
| 118 | + <Authority value="api:yt:streaming:delete"> | |
| 119 | + <a-button | |
| 120 | + color="error" | |
| 121 | + type="primary" | |
| 122 | + :disabled="enabledBatchDelete" | |
| 123 | + @click="handleDeleteRecord()" | |
| 124 | + > | |
| 125 | + 批量删除 | |
| 126 | + </a-button> | |
| 127 | + </Authority> | |
| 128 | + </template> | |
| 129 | + </BasicTable> | |
| 130 | + <SteramingDrawer @register="registerDrawer" @success="handleDrawerSubmitSuccess" /> | |
| 131 | + </PageWrapper> | |
| 132 | +</template> | |
| 133 | + | |
| 134 | +<style></style> | ... | ... |