|
|
@@ -1,14 +1,16 @@
|
|
|
<template>
|
|
|
<a-card title="空间管理" >
|
|
|
-
|
|
|
<table-pro
|
|
|
:service="SpaceController.page"
|
|
|
+ :serviceParams="{spaceName}"
|
|
|
:columns="columns"
|
|
|
@add="openModal"
|
|
|
ref="tableProDom"
|
|
|
>
|
|
|
<template v-slot:search >
|
|
|
- <a-space><InputTsx placeholder="请输入空间名称进行搜索" /> <a-button type="primary">搜索</a-button> </a-space>
|
|
|
+ <a-space><InputTsx v-model:value="spaceName" placeholder="请输入空间名称进行搜索" />
|
|
|
+ <a-button type="primary" @click="search" >搜索</a-button>
|
|
|
+ </a-space>
|
|
|
</template>
|
|
|
<template v-slot:render="{column, record}" >
|
|
|
<template v-if="column.key === 'status'" >
|
|
|
@@ -163,10 +165,31 @@
|
|
|
</a-radio-group>
|
|
|
</a-col>
|
|
|
</a-row>
|
|
|
- <!-- <a-row class="content-item" v-show="spaceState.config.thumbnail.enabled" >
|
|
|
- <a-col span="4" >截图周期: </a-col>
|
|
|
- <a-col><a-input-number id="inputNumber" :min="1" v-model:value="spaceState.config.thumbnail.interval" /> 秒 </a-col>
|
|
|
- </a-row> -->
|
|
|
+ <a-row class="content-item" style="align-items: start" v-show="spaceState.aiConfig.enabled" >
|
|
|
+ <a-col :span="4" style="display: flex;align-items: start;" >业务技能: </a-col>
|
|
|
+ <a-col :span="20" >
|
|
|
+ <a-row :gutter="[8, 8]">
|
|
|
+ <a-col :span="24" v-for="item in state.aiType" :key="item.code">
|
|
|
+ <!-- v-model:checked="true" -->
|
|
|
+ <a-row :gutter="[8, 8]" >
|
|
|
+ <a-col>
|
|
|
+ {{item.name}}
|
|
|
+ </a-col>
|
|
|
+ <a-col>
|
|
|
+ <div v-for="operator in state.aiListMap.get(item.code)" :key="operator.id" >
|
|
|
+ <a-checkbox @change="(e) => changeAiChecked(e.target.checked, item, operator)">{{operator.aiName}}</a-checkbox>
|
|
|
+ <div class="ai-config" v-if="operator.enable" >
|
|
|
+ <a-space><span>生效时间:</span> <a-time-range-picker v-model:value="operator.effectiveTime" /></a-space>
|
|
|
+ <a-space style="margin: 10px 0;"><span> 置信度:</span> <a-input-number v-model:value="operator.confidence" :max="100" :min="0" />%-100%</a-space>
|
|
|
+ <a-space><span>抽帧间隔:</span> <a-input-number :min="0" v-model:value="operator.interval" />ms</a-space>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
</a-col>
|
|
|
</a-row>
|
|
|
</div>
|
|
|
@@ -179,10 +202,12 @@
|
|
|
|
|
|
import { StepModal } from '@/components/StepModal'
|
|
|
import { InputTsx } from '@/components/MicroComponents/index'
|
|
|
-import { ref, reactive } from 'vue'
|
|
|
+import { ref, reactive, onMounted } from 'vue'
|
|
|
import { Form } from 'ant-design-vue'
|
|
|
-import { SpaceController } from '@/controller'
|
|
|
+import { OperatorController, SpaceController } from '@/controller'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
+import dayjs, { Dayjs } from 'dayjs'
|
|
|
+import { vueLanguage } from '@codemirror/lang-vue'
|
|
|
|
|
|
const useForm = Form.useForm
|
|
|
|
|
|
@@ -192,6 +217,8 @@ const steps = [{ title: '空间基本信息' }, { title: '空间配置' }]
|
|
|
|
|
|
const step = ref(0)
|
|
|
|
|
|
+const spaceName = ref('')
|
|
|
+
|
|
|
const visible = ref<boolean>(false)
|
|
|
|
|
|
const tableProDom = ref()
|
|
|
@@ -269,6 +296,14 @@ const spaceState = reactive<CVS.space>({
|
|
|
|
|
|
})
|
|
|
|
|
|
+const state = reactive<{
|
|
|
+ aiType: {code: string, name: string}[]
|
|
|
+ aiListMap: Map<string, (CVS.Operator & {effectiveTime: Dayjs[], interval: number, confidence: number, enable: boolean})[]>
|
|
|
+ }>({
|
|
|
+ aiType: [],
|
|
|
+ aiListMap: new Map()
|
|
|
+ })
|
|
|
+
|
|
|
const { resetFields, validate, validateInfos } = useForm(spaceState, {
|
|
|
spaceName: [{ required: true, message: '请填写空间名称' }],
|
|
|
type: [{ required: true }]
|
|
|
@@ -288,8 +323,25 @@ const openModal = async (record = { spaceId: '' }) => {
|
|
|
const closeModal = () => visible.value = false
|
|
|
|
|
|
const submit = async () => {
|
|
|
- spaceState.spaceId ? await SpaceController.update(spaceState) : await SpaceController.add(spaceState)
|
|
|
+ const configuration = Array.from(state.aiListMap, ([key, value]) => ([...value])).flat(2).filter(item => item.enable).map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ effectiveTimeStart: dayjs(item.effectiveTime[0]).format('HH:mm:ss'),
|
|
|
+ effectiveTimeEnd: dayjs(item.effectiveTime[1]).format('HH:mm:ss')
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ spaceState.spaceId
|
|
|
+ ? await SpaceController.update(spaceState)
|
|
|
+ : await SpaceController.add({
|
|
|
+ ...spaceState,
|
|
|
+ aiConfig: {
|
|
|
+ ...spaceState,
|
|
|
+ configuration: configuration
|
|
|
+ }
|
|
|
+ })
|
|
|
closeModal()
|
|
|
+ tableProDom.value.reload()
|
|
|
}
|
|
|
|
|
|
const changeStatus = async (record: CVS.space) => {
|
|
|
@@ -301,16 +353,52 @@ const pushCvsDevicePage = (record: CVS.space) => {
|
|
|
router.push({ path: '/cvs/video/device', query: { spaceId: record.spaceId } })
|
|
|
}
|
|
|
|
|
|
+const changeAiChecked = (value, type: {code: string, name: string}, operator: CVS.Operator) => {
|
|
|
+ const operatorList = state.aiListMap.get(type.code)!.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ enable: item.id === operator.id ? value : item.enable
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.aiListMap.set(type.code, operatorList)
|
|
|
+}
|
|
|
+
|
|
|
+const search = () => {
|
|
|
+ tableProDom.value.reload({ page: 1 })
|
|
|
+}
|
|
|
+
|
|
|
const stepNext = () => {
|
|
|
validate().then(() => {
|
|
|
step.value++
|
|
|
}).catch(() => {})
|
|
|
}
|
|
|
|
|
|
-const preNext = () => {
|
|
|
- step.value--
|
|
|
+const preNext = () => step.value--
|
|
|
+
|
|
|
+const getOperatorType = async () => state.aiType = await OperatorController.type()
|
|
|
+
|
|
|
+const getOperatorList = async () => {
|
|
|
+ const operatorList = await OperatorController.list()
|
|
|
+ state.aiType.forEach(item => {
|
|
|
+ state.aiListMap.set(item.code, operatorList.filter(operator => item.code === operator.aiModelType).map(_ => {
|
|
|
+ return {
|
|
|
+ ..._,
|
|
|
+ enable: false,
|
|
|
+ confidence: 60,
|
|
|
+ interval: 10,
|
|
|
+ effectiveTime: [dayjs('00:00:00', 'HH:mm:ss'), dayjs('23:59:59', 'HH:mm:ss')],
|
|
|
+ effectiveTimeStart: dayjs('00:00:00', 'HH:mm:ss'),
|
|
|
+ effectiveTimeEnd: dayjs('23:59:59', 'HH:mm:ss')
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
+onMounted(async () => {
|
|
|
+ await getOperatorType()
|
|
|
+ getOperatorList()
|
|
|
+})
|
|
|
+
|
|
|
</script>
|
|
|
<style lang='less' scoped >
|
|
|
.section {
|
|
|
@@ -326,6 +414,13 @@ const preNext = () => {
|
|
|
margin-bottom: 20px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
+ .ai-config {
|
|
|
+ width: 360px;
|
|
|
+ height: 120px;
|
|
|
+ border: 1px solid #ebebeb;
|
|
|
+ margin-top: 5px;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|