Commit 39f9876d59256f7ecdcea4bb0759b2db9752d491
Merge branch 'ft' into 'main_dev'
feat(src/packages): 摄像头新增源类型获取 See merge request yunteng/thingskit-view!114
Showing
6 changed files
with
226 additions
and
29 deletions
| 1 | import { defHttp } from '@/utils/external/http/axios' | 1 | import { defHttp } from '@/utils/external/http/axios' |
| 2 | -import { DictItem, UploadResponse } from './model' | 2 | +import { DictItem, OrganizationListItem, UploadResponse } from './model' |
| 3 | 3 | ||
| 4 | enum Api { | 4 | enum Api { |
| 5 | GET_DICT = '/dict_item', | 5 | GET_DICT = '/dict_item', |
| @@ -8,7 +8,9 @@ enum Api { | @@ -8,7 +8,9 @@ enum Api { | ||
| 8 | AREALIST = '/area/list', | 8 | AREALIST = '/area/list', |
| 9 | PLATFORM = '/platform/get', | 9 | PLATFORM = '/platform/get', |
| 10 | CONFIGURATION = '/configuration/center', | 10 | CONFIGURATION = '/configuration/center', |
| 11 | - CONFIGURATION_SHARE = '/configuration/center/share/' | 11 | + CONFIGURATION_SHARE = '/configuration/center/share/', |
| 12 | + BASEORIGINATION = '/organization/me/list/', | ||
| 13 | + VIDEO = '/video/list' | ||
| 12 | } | 14 | } |
| 13 | 15 | ||
| 14 | export const getDictItemByCode = (value: string) => { | 16 | export const getDictItemByCode = (value: string) => { |
| @@ -48,7 +50,7 @@ export const getConfigurationList = (params: object) => { | @@ -48,7 +50,7 @@ export const getConfigurationList = (params: object) => { | ||
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | //组态设置是否公开或私有 | 52 | //组态设置是否公开或私有 |
| 51 | -export const setConfigurationIsShare = (params: string,isShare:boolean,data:object) => { | 53 | +export const setConfigurationIsShare = (params: string, isShare: boolean, data: object) => { |
| 52 | return defHttp.post({ | 54 | return defHttp.post({ |
| 53 | url: `${Api.CONFIGURATION_SHARE}${params}?isShare=${isShare}`, | 55 | url: `${Api.CONFIGURATION_SHARE}${params}?isShare=${isShare}`, |
| 54 | data | 56 | data |
| @@ -59,10 +61,24 @@ export const setConfigurationIsShare = (params: string,isShare:boolean,data:obje | @@ -59,10 +61,24 @@ export const setConfigurationIsShare = (params: string,isShare:boolean,data:obje | ||
| 59 | export const getDeviceActiveTime = (entityId: string) => { | 61 | export const getDeviceActiveTime = (entityId: string) => { |
| 60 | return defHttp.get( | 62 | return defHttp.get( |
| 61 | { | 63 | { |
| 62 | - url: `/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active`, | 64 | + url: `/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active` |
| 63 | }, | 65 | }, |
| 64 | { | 66 | { |
| 65 | - joinPrefix: false, | 67 | + joinPrefix: false |
| 66 | } | 68 | } |
| 67 | - ); | ||
| 68 | -}; | ||
| 69 | + ) | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +//获取组织列表 | ||
| 73 | +export const getOrganizationList = (params?: OrganizationListItem) => | ||
| 74 | + defHttp.get({ | ||
| 75 | + url: Api.BASEORIGINATION, | ||
| 76 | + params | ||
| 77 | + }) | ||
| 78 | + | ||
| 79 | +//获取视频列表 | ||
| 80 | +export const getVideoList = (params?:object) => | ||
| 81 | + defHttp.get({ | ||
| 82 | + url: Api.VIDEO, | ||
| 83 | + params | ||
| 84 | + }) |
| @@ -16,3 +16,11 @@ export interface UploadResponse { | @@ -16,3 +16,11 @@ export interface UploadResponse { | ||
| 16 | size: number | 16 | size: number |
| 17 | fileStaticUri: string | 17 | fileStaticUri: string |
| 18 | } | 18 | } |
| 19 | + | ||
| 20 | + | ||
| 21 | +export interface OrganizationListItem { | ||
| 22 | + id: string; | ||
| 23 | + name: string; | ||
| 24 | + parentId?: string; | ||
| 25 | + remark: string; | ||
| 26 | +} |
| @@ -3,10 +3,17 @@ import { CreateComponentType } from '@/packages/index.d' | @@ -3,10 +3,17 @@ import { CreateComponentType } from '@/packages/index.d' | ||
| 3 | import { CameraConfig } from './index' | 3 | import { CameraConfig } from './index' |
| 4 | import cloneDeep from 'lodash/cloneDeep' | 4 | import cloneDeep from 'lodash/cloneDeep' |
| 5 | 5 | ||
| 6 | +export enum sourceTypeEnum { | ||
| 7 | + CUSTOM = 'custom', | ||
| 8 | + PLATFORM = 'platform' | ||
| 9 | +} | ||
| 10 | + | ||
| 6 | export const option = { | 11 | export const option = { |
| 7 | dataset: [ | 12 | dataset: [ |
| 8 | { | 13 | { |
| 9 | - url: '' | 14 | + url: '', |
| 15 | + sourceType: 'custom', | ||
| 16 | + organization: '' | ||
| 10 | } | 17 | } |
| 11 | ] as any, | 18 | ] as any, |
| 12 | // 自动播放的间隔(ms) | 19 | // 自动播放的间隔(ms) |
| 1 | <template> | 1 | <template> |
| 2 | <CollapseItem name="播放器配置" :expanded="true"> | 2 | <CollapseItem name="播放器配置" :expanded="true"> |
| 3 | - <setting-item-box name="源地址" :alone="true"> | ||
| 4 | - <setting-item v-for="(item, index) in optionData.dataset" :key="index"> | ||
| 5 | - <n-input-group> | ||
| 6 | - <n-input v-model:value="item.url" size="small" placeholder="请输入源地址"></n-input> | ||
| 7 | - <n-button ghost @click="optionData.dataset.splice(index, 1)"> - </n-button> | ||
| 8 | - </n-input-group> | ||
| 9 | - </setting-item> | ||
| 10 | - <setting-item> | ||
| 11 | - <n-button v-if="optionData.dataset.length < 9" size="small" @click="optionData.dataset.push({ url: '' })"> | ||
| 12 | - + | ||
| 13 | - </n-button> | ||
| 14 | - </setting-item> | ||
| 15 | - </setting-item-box> | 3 | + <template v-for="(item, index) in optionData.dataset" :key="index"> |
| 4 | + <setting-item-box name="源类型" :alone="true"> | ||
| 5 | + <setting-item> | ||
| 6 | + <n-radio-group @change="handleChecked($event, item)" v-model:value="item.sourceType" name="radiogroup"> | ||
| 7 | + <n-space> | ||
| 8 | + <n-radio v-for="(item, index) in sourceTypes" :key="item.value" :value="item.value"> | ||
| 9 | + {{ item.label }} | ||
| 10 | + </n-radio> | ||
| 11 | + </n-space> | ||
| 12 | + </n-radio-group> | ||
| 13 | + </setting-item> | ||
| 14 | + </setting-item-box> | ||
| 15 | + <setting-item-box v-if="item.sourceType === sourceTypeEnum.CUSTOM" name="源地址" :alone="true"> | ||
| 16 | + <setting-item> | ||
| 17 | + <n-input-group> | ||
| 18 | + <n-input v-model:value="item.url" size="small" placeholder="请输入源地址"></n-input> | ||
| 19 | + </n-input-group> | ||
| 20 | + </setting-item> | ||
| 21 | + </setting-item-box> | ||
| 22 | + <setting-item-box v-if="item.sourceType === sourceTypeEnum.PLATFORM" name="组织" :alone="true"> | ||
| 23 | + <setting-item> | ||
| 24 | + <n-tree-select | ||
| 25 | + placement="top-start" | ||
| 26 | + label-field="name" | ||
| 27 | + v-model:value="item.organization" | ||
| 28 | + key-field="id" | ||
| 29 | + children-field="children" | ||
| 30 | + :options="originationOption" | ||
| 31 | + @update:value="handleUpdateTreeValue($event, item)" | ||
| 32 | + /> | ||
| 33 | + </setting-item> | ||
| 34 | + </setting-item-box> | ||
| 35 | + <setting-item-box v-if="item.sourceType === sourceTypeEnum.PLATFORM" name="视频" :alone="true"> | ||
| 36 | + <setting-item> | ||
| 37 | + <n-select v-model:value="item.url" :options="videoOptions" /> | ||
| 38 | + </setting-item> | ||
| 39 | + </setting-item-box> | ||
| 40 | + <n-button size="small" @click="optionData.dataset.splice(index, 1)"> - </n-button> | ||
| 41 | + </template> | ||
| 42 | + <n-button | ||
| 43 | + style="margin-left: 10px" | ||
| 44 | + v-if="optionData.dataset.length < 9" | ||
| 45 | + size="small" | ||
| 46 | + @click="optionData.dataset.push({ url: '', sourceType: 'custom', organization: '' })" | ||
| 47 | + > | ||
| 48 | + + | ||
| 49 | + </n-button> | ||
| 16 | </CollapseItem> | 50 | </CollapseItem> |
| 17 | </template> | 51 | </template> |
| 18 | 52 | ||
| 19 | <script setup lang="ts"> | 53 | <script setup lang="ts"> |
| 20 | -import { PropType } from 'vue' | ||
| 21 | -import { option } from './config' | 54 | +import { PropType, ref, onMounted } from 'vue' |
| 55 | +import { option, sourceTypeEnum } from './config' | ||
| 22 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 56 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
| 57 | +import { getOrganizationList, getVideoList } from '@/api/external/common/index' | ||
| 58 | +import { NTreeSelect } from 'naive-ui' | ||
| 23 | 59 | ||
| 24 | -defineProps({ | 60 | +const props = defineProps({ |
| 25 | optionData: { | 61 | optionData: { |
| 26 | type: Object as PropType<typeof option>, | 62 | type: Object as PropType<typeof option>, |
| 27 | required: true | 63 | required: true |
| 28 | } | 64 | } |
| 29 | }) | 65 | }) |
| 66 | + | ||
| 67 | +const sourceTypes = [ | ||
| 68 | + { | ||
| 69 | + value: 'custom', | ||
| 70 | + label: '自定义' | ||
| 71 | + }, | ||
| 72 | + { | ||
| 73 | + value: 'platform', | ||
| 74 | + label: '平台获取' | ||
| 75 | + } | ||
| 76 | +] | ||
| 77 | + | ||
| 78 | +const originationOption = ref([]) | ||
| 79 | + | ||
| 80 | +const videoOptions = ref([]) | ||
| 81 | + | ||
| 82 | +const getOriginationList = async () => { | ||
| 83 | + const res = await getOrganizationList() | ||
| 84 | + originationOption.value = res | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +const handleUpdateTreeValue = (e: any, value: object) => { | ||
| 88 | + getVideoLists(e) | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +const getVideoLists = async (organizationId: string) => { | ||
| 92 | + const res = await getVideoList({ organizationId }) | ||
| 93 | + videoOptions.value = res?.data?.map((item: any) => ({ label: item.name, value: item.videoUrl })) | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +const handleChecked = ({ target }: any, values: object) => { | ||
| 97 | + const { value } = target | ||
| 98 | + if (value === sourceTypeEnum.PLATFORM) { | ||
| 99 | + getOriginationList() | ||
| 100 | + } | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +onMounted(() => { | ||
| 104 | + props.optionData.dataset.forEach((item: any) => { | ||
| 105 | + if (item.sourceType === sourceTypeEnum.PLATFORM) { | ||
| 106 | + getOriginationList() | ||
| 107 | + if (item.organization) { | ||
| 108 | + getVideoLists(item.organization) | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + }) | ||
| 112 | +}) | ||
| 30 | </script> | 113 | </script> |
| @@ -3,10 +3,17 @@ import { CreateComponentType } from '@/packages/index.d' | @@ -3,10 +3,17 @@ import { CreateComponentType } from '@/packages/index.d' | ||
| 3 | import { SingleCameraConfig } from './index' | 3 | import { SingleCameraConfig } from './index' |
| 4 | import cloneDeep from 'lodash/cloneDeep' | 4 | import cloneDeep from 'lodash/cloneDeep' |
| 5 | 5 | ||
| 6 | +export enum sourceTypeEnum { | ||
| 7 | + CUSTOM = 'custom', | ||
| 8 | + PLATFORM = 'platform' | ||
| 9 | +} | ||
| 10 | + | ||
| 6 | export const option = { | 11 | export const option = { |
| 7 | dataset: '', | 12 | dataset: '', |
| 8 | autoplay: false, | 13 | autoplay: false, |
| 9 | - poster: '' | 14 | + poster: '', |
| 15 | + sourceType: 'custom', | ||
| 16 | + organization: '' | ||
| 10 | } | 17 | } |
| 11 | 18 | ||
| 12 | export default class Config extends PublicConfigClass implements CreateComponentType { | 19 | export default class Config extends PublicConfigClass implements CreateComponentType { |
| @@ -22,13 +22,42 @@ | @@ -22,13 +22,42 @@ | ||
| 22 | </n-card> | 22 | </n-card> |
| 23 | </setting-item> | 23 | </setting-item> |
| 24 | </setting-item-box> | 24 | </setting-item-box> |
| 25 | - <setting-item-box name="源地址" :alone="true"> | 25 | + <setting-item-box name="源类型" :alone="true"> |
| 26 | + <setting-item> | ||
| 27 | + <n-radio-group @change="handleChecked" v-model:value="optionData.sourceType" name="radiogroup"> | ||
| 28 | + <n-space> | ||
| 29 | + <n-radio v-for="(item, index) in sourceTypes" :key="item.value" :value="item.value"> | ||
| 30 | + {{ item.label }} | ||
| 31 | + </n-radio> | ||
| 32 | + </n-space> | ||
| 33 | + </n-radio-group> | ||
| 34 | + </setting-item> | ||
| 35 | + </setting-item-box> | ||
| 36 | + <setting-item-box v-if="optionData.sourceType === sourceTypeEnum.CUSTOM" name="源地址" :alone="true"> | ||
| 26 | <setting-item> | 37 | <setting-item> |
| 27 | <n-input-group> | 38 | <n-input-group> |
| 28 | <n-input v-model:value="optionData.dataset" size="small" placeholder="请输入源地址"></n-input> | 39 | <n-input v-model:value="optionData.dataset" size="small" placeholder="请输入源地址"></n-input> |
| 29 | </n-input-group> | 40 | </n-input-group> |
| 30 | </setting-item> | 41 | </setting-item> |
| 31 | </setting-item-box> | 42 | </setting-item-box> |
| 43 | + <setting-item-box v-if="optionData.sourceType === sourceTypeEnum.PLATFORM" name="组织" :alone="true"> | ||
| 44 | + <setting-item> | ||
| 45 | + <n-tree-select | ||
| 46 | + placement="top-start" | ||
| 47 | + label-field="name" | ||
| 48 | + v-model:value="optionData.organization" | ||
| 49 | + key-field="id" | ||
| 50 | + children-field="children" | ||
| 51 | + :options="originationOption" | ||
| 52 | + @update:value="handleUpdateTreeValue" | ||
| 53 | + /> | ||
| 54 | + </setting-item> | ||
| 55 | + </setting-item-box> | ||
| 56 | + <setting-item-box v-if="optionData.sourceType === sourceTypeEnum.PLATFORM" name="视频" :alone="true"> | ||
| 57 | + <setting-item> | ||
| 58 | + <n-select v-model:value="optionData.dataset" :options="videoOptions" /> | ||
| 59 | + </setting-item> | ||
| 60 | + </setting-item-box> | ||
| 32 | <setting-item-box name="自动播放"> | 61 | <setting-item-box name="自动播放"> |
| 33 | <setting-item> | 62 | <setting-item> |
| 34 | <n-switch v-model:value="optionData.autoplay" size="small" /> | 63 | <n-switch v-model:value="optionData.autoplay" size="small" /> |
| @@ -38,14 +67,15 @@ | @@ -38,14 +67,15 @@ | ||
| 38 | </template> | 67 | </template> |
| 39 | 68 | ||
| 40 | <script setup lang="ts"> | 69 | <script setup lang="ts"> |
| 41 | -import { PropType, ref, nextTick } from 'vue' | ||
| 42 | -import { option } from './config' | 70 | +import { PropType, ref, nextTick, onMounted } from 'vue' |
| 71 | +import { option, sourceTypeEnum } from './config' | ||
| 43 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 72 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
| 44 | import { FileTypeEnum } from '@/enums/fileTypeEnum' | 73 | import { FileTypeEnum } from '@/enums/fileTypeEnum' |
| 45 | import { uploadFile } from '@/api/external/contentSave/content' | 74 | import { uploadFile } from '@/api/external/contentSave/content' |
| 46 | -import { UploadCustomRequestOptions } from 'naive-ui' | 75 | +import { UploadCustomRequestOptions, NTreeSelect } from 'naive-ui' |
| 47 | import { backgroundImageSize } from '@/settings/designSetting' | 76 | import { backgroundImageSize } from '@/settings/designSetting' |
| 48 | import { fetchRouteParamsLocation } from '@/utils' | 77 | import { fetchRouteParamsLocation } from '@/utils' |
| 78 | +import { getOrganizationList, getVideoList } from '@/api/external/common/index' | ||
| 49 | 79 | ||
| 50 | const props = defineProps({ | 80 | const props = defineProps({ |
| 51 | optionData: { | 81 | optionData: { |
| @@ -56,6 +86,52 @@ const props = defineProps({ | @@ -56,6 +86,52 @@ const props = defineProps({ | ||
| 56 | 86 | ||
| 57 | const uploadFileListRef = ref() | 87 | const uploadFileListRef = ref() |
| 58 | 88 | ||
| 89 | +const sourceTypes = [ | ||
| 90 | + { | ||
| 91 | + value: 'custom', | ||
| 92 | + label: '自定义' | ||
| 93 | + }, | ||
| 94 | + { | ||
| 95 | + value: 'platform', | ||
| 96 | + label: '平台获取' | ||
| 97 | + } | ||
| 98 | +] | ||
| 99 | + | ||
| 100 | +const originationOption = ref([]) | ||
| 101 | + | ||
| 102 | +const videoOptions = ref([]) | ||
| 103 | + | ||
| 104 | +const getOriginationList = async () => { | ||
| 105 | + const res = await getOrganizationList() | ||
| 106 | + originationOption.value = res | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +const handleUpdateTreeValue = (value: string) => { | ||
| 110 | + props.optionData.dataset = '' | ||
| 111 | + getVideoLists(value) | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +const getVideoLists = async (organizationId: string) => { | ||
| 115 | + const res = await getVideoList({ organizationId }) | ||
| 116 | + videoOptions.value = res?.data?.map((item: any) => ({ label: item.name, value: item.videoUrl })) | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +const handleChecked = ({ target }: any) => { | ||
| 120 | + const { value } = target | ||
| 121 | + if (value === sourceTypeEnum.PLATFORM) { | ||
| 122 | + getOriginationList() | ||
| 123 | + } | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +onMounted(() => { | ||
| 127 | + if (props.optionData.sourceType === sourceTypeEnum.PLATFORM) { | ||
| 128 | + getOriginationList() | ||
| 129 | + if (props.optionData.organization) { | ||
| 130 | + getVideoLists(props.optionData.organization) | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | +}) | ||
| 134 | + | ||
| 59 | // 上传图片前置处理 | 135 | // 上传图片前置处理 |
| 60 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment | 136 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment |
| 61 | //@ts-ignore | 137 | //@ts-ignore |