Browse Source

feat: 任务

lvkun996 2 năm trước cách đây
mục cha
commit
6ede282455

+ 2 - 2
src/api/cvs/aiboxCloud.ts

@@ -110,7 +110,7 @@ export const addTaskArea = (clientId: string, data: any) => {
 }
 
 export const getAig = (clientId: string) => {
-  return request({
+  return request<CVS.AiBox.Aig[]>({
     url: `/aiBox/control/aig/${clientId}`,
     method: 'GET',
     Headers: {
@@ -146,7 +146,7 @@ export const getPLan = (clientId: string) => {
   })
 }
 
-export const addPLan = (clientId: string, data: any) => {
+export const addPlan = (clientId: string, data: any) => {
   return request({
     url: `/aiBox/control/plan/${clientId}`,
     method: 'POST',

+ 47 - 21
src/controller/cvs/aiboxCloudController.ts

@@ -1,7 +1,8 @@
 
 // aibox云端
 
-import { addFlow, getFlow, getTask, updateFlow, delFlow, addTask, updateTask, delTask, startTask, stopTask, getPLan, addPLan, delPLan, getAig } from '@/api/cvs/aiboxCloud'
+import { getSys } from '@/api/cvs/aibox'
+import { addFlow, getFlow, getTask, updateFlow, delFlow, addTask, updateTask, delTask, startTask, stopTask, getPLan, addPlan, delPLan, getAig, getTime, calibrationTime, getNet, getMeta } from '@/api/cvs/aiboxCloud'
 import { message } from 'ant-design-vue'
 
 export class AiboxCloudController {
@@ -74,8 +75,9 @@ export class AiboxCloudController {
   }
 
   static async plan () {
-    const data = await getPLan(AiboxCloudController.clientId)
-    const _data = JSON.parse(JSON.parse(data.data).data)
+    const data: any = await getPLan(AiboxCloudController.clientId)
+
+    const _data = JSON.parse(data.data).data
     return {
       ...data,
       data: _data ? _data.map(item => JSON.parse(item)) : []
@@ -83,31 +85,55 @@ export class AiboxCloudController {
   }
 
   static async addPlan (data: any) {
-    const { msg, code } = await addPLan(AiboxCloudController.clientId, data)
-    code === 200 ? message.success('新增成功') : message.error(msg)
-  }
-
-  static async updatePlan (data: any) {
-    const { msg, code } = await addPLan(AiboxCloudController.clientId, data)
+    const { msg, code } = await addPlan(AiboxCloudController.clientId, data)
     code === 200 ? message.success('新增成功') : message.error(msg)
   }
 
   static async delPlan (num: number) {
-    const { code, msg } = await delPLan(AiboxCloudController.clientId, num)
+    const { code, msg, data } = await delPLan(AiboxCloudController.clientId, num)
+
     code === 200 ? message.success('删除成功') : message.error(msg)
   }
 
   static async aig () {
-    const data = await getAig(AiboxCloudController.clientId)
-    console.log(JSON.parse(JSON.parse(data.data).data).data)
-
-    // const _data = JSON.parse(JSON.parse(data.data).data).map(item => {
-    //   const targetTask = curTask.taskAbility.find(task => item.aigonum === task.aigonum)
-    //   return {
-    //     ...item,
-    //     isSelect: curTask.taskAbility.map(task => task.aigonum).includes(item.aigonum),
-    //     setparam: targetTask && targetTask.setparam ? targetTask.setparam : item.setparam
-    //   }
-    // })
+    const data: any = await getAig(AiboxCloudController.clientId)
+    return JSON.parse(JSON.parse(data.data).data).data
+  }
+
+  static async time () {
+    const data: any = await getTime(AiboxCloudController.clientId)
+    return JSON.parse(JSON.parse(data.data).data).data
+  }
+
+  static async calibrationTime () {
+    await calibrationTime(AiboxCloudController.clientId, String(Math.floor(new Date().getTime() / 1000)))
+    message.success('校验成功')
+  }
+
+  static async net () {
+    const data: any = await getNet(AiboxCloudController.clientId)
+    const _data = JSON.parse(data.data).data
+    return {
+      ...data,
+      data: _data ? _data.map(item => JSON.parse(item)) : []
+    }
+  }
+
+  static async meta () {
+    const data: any = await getMeta(AiboxCloudController.clientId)
+    const _data = JSON.parse(data.data).data
+    return {
+      ...data,
+      data: _data ? _data.map(item => JSON.parse(item)) : []
+    }
+  }
+
+  static async sys () {
+    const data: any = await getSys(AiboxCloudController.clientId)
+    const _data = JSON.parse(data.data).data
+    return {
+      ...data,
+      data: _data ? _data.map(item => JSON.parse(item)) : []
+    }
   }
 }

+ 0 - 32
src/pages/cvs/edge/abilityList.ts

@@ -1,32 +0,0 @@
-export const abilityList = [
-  { value: '01', label: '明烟明火检测' },
-  { value: '02', label: '反光衣检测' },
-  { value: '03', label: '安全帽检测' },
-  { value: '04', label: '无消防器材' },
-  { value: '05', label: '街道垃圾检测' },
-  { value: '06', label: '垃圾桶满溢检测' },
-  { value: '07', label: '占道经营检测' },
-  { value: '08', label: '小动物检测' },
-  { value: '09', label: '电瓶车进电梯识别' },
-  { value: '10', label: '区域车辆禁停' },
-  { value: '11', label: '非机动车停放' },
-  { value: '12', label: '打架检测' },
-  { value: '13', label: '人员摔倒监测' },
-  { value: '14', label: '人数监控' },
-  { value: '15', label: '人流统计' },
-  { value: '16', label: '越线监测' },
-  { value: '17', label: '区域入侵' },
-  { value: '18', label: '人员拥挤检测' },
-  { value: '19', label: '长袖检测' },
-  { value: '20', label: '工服检测' },
-  { value: '21', label: '进入检测' },
-  { value: '22', label: '离开检测' },
-  { value: '23', label: '出现检测' },
-  { value: '24', label: '翻越围栏' },
-  { value: '25', label: '离岗检测' },
-  { value: '26', label: '睡岗检测' },
-  { value: '27', label: '口罩检测' },
-  { value: '28', label: '抽烟打电话' },
-  { value: '29', label: '人脸识别' },
-  { value: '30', label: '人脸抓拍' }
-]

+ 1 - 0
src/pages/cvs/edge/aiTask.vue

@@ -42,6 +42,7 @@
     :open="state.visible"
     @cancel='state.visible = false'
     @ok='submit'
+    footer
   >
     <add-form ref="addFormRef" :opra-state="state.opraState"  :item-data="state.taskState" />
   </RealView>

+ 37 - 75
src/pages/cvs/edge/components/add.vue

@@ -66,83 +66,26 @@
     >
       <a-checkbox-group :value="taskState.taskAbility" style="width: 100%" @change="onChangeAbility">
         <a-row>
-          <a-col :span="8" v-for="item in abilityList" :key="item.value" >
-            <a-checkbox :value="item.value">{{item.label}}</a-checkbox>
+          <a-col :span="8" v-for="item in aigList" :key="item.aigonum" >
+            <a-checkbox :value="item.aigonum">{{item.aigoname}}</a-checkbox>
           </a-col>
         </a-row>
       </a-checkbox-group>
     </a-form-item>
     <a-form-item
-      label="区域车辆禁停配置"
-      v-bind="validateInfos.taskCarConf"
-      v-if="taskState.taskAbility.includes('10')"
+      v-for="item in selectAig"
+      :key="item.setname"
+      :label="item.setname"
     >
-      <a-input-number addon-before="停靠时长(分)" v-model:value="taskState.taskCarConf" />
-    </a-form-item>
-    <a-form-item
-      label="拥挤度设置"
-      v-bind="validateInfos.taskCongestionConf"
-      v-if="taskState.taskAbility.includes('18')"
-    >
-      <a-input-number addon-after="人"  v-model:value="taskState.taskCongestionConf" />
-    </a-form-item>
-    <a-form-item
-      label="离岗检测配置"
-      v-bind="validateInfos.taskDepartureTime"
-      v-if="taskState.taskAbility.includes('25')"
-    >
-    <a-input-group size="large">
-      <a-row :gutter="8">
-        <a-col :span="8">
-          <a-input-number  addon-before="超时时间(秒)"  v-model:value="taskState.taskDepartureTime" />
-        </a-col>
-        <a-col :span="8">
-          <a-input-number  addon-before="要求在岗人数"  v-model:value="taskState.taskDeparturePeople" />
-        </a-col>
-      </a-row>
-    </a-input-group>
-    </a-form-item>
-    <a-form-item
-      label="工服选择"
-      v-bind="validateInfos.taskWork"
-      v-if="taskState.taskAbility.includes('20')"
-    >
-    <a-select
-        v-model:value="taskState.taskWork"
-      >
-        <a-select-option
-          v-for="item in state.workDataSource"
-          :key="item.workclothesName"
-          :value="item.workclothesName"
-        >
-          {{item.workclothesName}}
-        </a-select-option>
-      </a-select>
-    </a-form-item>
-    <a-form-item
-      label="人脸识别配置"
-      v-bind="validateInfos.taskSimilarityThreshold"
-      v-if="taskState.taskAbility.includes('29')"
-    >
-    <a-input-group size="large">
-      <a-row :gutter="8">
-        <a-col :span="8">
-          <a-input-number  v-model:value="taskState.taskSimilarityThreshold" addon-before="相似度阈值"/>
-        </a-col>
-        <a-col :span="8">
-          <a-input-number  v-model:value="taskState.taskStrangerThreshold" addon-before="陌生人阈值"/>
-        </a-col>
-      </a-row>
-    </a-input-group>
+      <a-input-number v-model:value="item.argvalue" ></a-input-number>
     </a-form-item>
   </a-form>
   </a-card>
 </template>
 <script lang='ts'  setup >
-import { onMounted, reactive, watch } from 'vue'
+import { computed, onMounted, reactive, ref, watch } from 'vue'
 import { Form, message } from 'ant-design-vue'
 import { AiboxCloudController } from '@/controller'
-import { abilityList } from '../abilityList'
 
 const IProps = defineProps<{
   opraState: 'add' | 'update',
@@ -167,6 +110,8 @@ const taskState = reactive({
   taskStrangerThreshold: 0.45
 })
 
+const selectAig = computed(() => aigList.value.filter(item => item.isSelect && item.setparam).map(_ => _.setparam).flat(2))
+
 const useForm = Form.useForm
 
 const { resetFields, validate, validateInfos } = useForm(taskState, reactive({
@@ -188,10 +133,6 @@ const submit = () => {
   })
 }
 
-defineExpose({
-  submit
-})
-
 watch(
   () => IProps.opraState,
   () => {
@@ -208,29 +149,50 @@ const onChangeAbility = (record: string[]) => {
     message.error('最多选择三个算法')
     return
   }
+  aigList.value.forEach(item => {
+    if (record.includes(item.aigonum)) item.isSelect = true
+    else item.isSelect = false
+  })
   taskState.taskAbility = record
 }
 
+const aigList = ref<CVS.AiBox.Aig[]>([])
+
 const getFlow = async () => {
   const { data } = await AiboxCloudController.flow()
   state.videDataSource = data
 }
 
 const getPlan = async () => {
-  const { data } = await PlanController.page()
+  const { data } = await AiboxCloudController.plan()
   state.planDataSource = data
 }
 
-const getOtherWork = async () => {
-  const { data } = await OtherController.otherArg('work')
-  state.workDataSource = data
+// const getOtherWork = async () => {
+//   const { data } = await OtherController.otherArg('work')
+//   state.workDataSource = data
+// }
+
+const geiAig = async () => {
+  const data = await AiboxCloudController.aig()
+  console.log('aigList:', data)
+  aigList.value = data.map(item => {
+    return {
+      ...item,
+      isSelect: false,
+      setParam: item.setparam
+    }
+  })
 }
 
 onMounted(() => {
   getFlow()
-  // getPlan()
-  // getOtherWork()
-  AiboxCloudController.aig()
+  getPlan()
+  geiAig()
+})
+
+defineExpose({
+  submit
 })
 
 </script>

+ 309 - 1
src/pages/cvs/edge/plan.vue

@@ -1,9 +1,317 @@
 <template>
 <a-card title="计划模板" >
-
+  <table-pro
+    :service="AiboxCloudController.plan"
+    :columns="columns"
+    ref="tableProDom"
+    @add="openModal"
+  >
+    <template #render="{ column, record }">
+        <template v-if="column.key === 'planUse'">
+          <a-space>
+            <a-tag :color="planUseMap.get(record.planUse)?.color" >{{planUseMap.get(record.planUse)?.label}}</a-tag>
+          </a-space>
+        </template>
+        <template v-if="column.key === 'action'">
+          <a-popconfirm
+            title="确定要删除这计划吗"
+            ok-text="Yes"
+            cancel-text="No"
+            @confirm="delPlan(record.planNum)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </template>
+      </template>
+  </table-pro>
 </a-card>
+
+<modal-pro
+  style="width: 800px;"
+  label="新增工作计划"
+  :open="state.visible"
+  @cancel="state.visible = false"
+  destroyOnClose
+  @ok="onsubmitSchedule"
+>
+  <a-row  >
+    <a-col  :span="4">计划名称:</a-col>
+    <a-col ><a-input v-model:value="state.scheduleName"></a-input></a-col>
+  </a-row>
+  <a-row style="margin-top: 20px;" >
+    <table border="" style="user-select: none;" >
+      <thead>
+        <tr>
+          <td  width="100" :rowSpan="2" :colSpan="0" > 星期/时间</td>
+          <td  colSpan="12" style='text-align: center' > 00:00-12:00</td>
+          <td  colSpan="12" style='text-align: center' > 12:00-24:00</td>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td ></td>
+          <td
+            v-for="(item, index) in new Array(24).fill(1)"
+            :key="index"
+            width="25"
+            :col-span="1"
+          >
+            {{index >= 10 ? index: "0" + index}}
+          </td>
+        </tr>
+        <tr
+          :key="i"
+          v-for="(item , i) in new Array(7).fill(1)"
+        >
+         <th > 星期{{calcWeek(String(i + 1))}} </th>
+         <td
+            :col-span="1"
+            v-for="(item, index) in new Array(24).fill(1)"
+            :key="index"
+            :time="JSON.stringify({
+              week: String(i + 1),
+              hour: calcTime(index)
+            })"
+            @mousedown="onMouseDown"
+            @mouseenter="onMouseEnter"
+            @mouseup="onMouseUp"
+            style="cursor: pointer"
+          ></td>
+       </tr>
+      </tbody>
+    </table>
+    <a-row style="margin-top: 16px; width: 100%" :gutter="[8, 8]" >
+      <a-col> <a-row> <div style="width: 15px;height: 30px; border: 1px solid #ccc; margin-right: 5px" ></div> 未选</a-row> </a-col>
+      <a-col> <a-row> <div style="width: 15px;height: 30px; background-color: skyblue; margin-right: 5px"  > </div> 已选</a-row> </a-col>
+      <a-row  style="margin-top: 20px; width: 100%" >
+        <a-col :span="24" :key="item.week" v-for="item in state.selectTime" >
+          <a-row :gutter="[8, 8]">
+            <a-col :span="4" >星期{{calcWeek(item.week)}}:</a-col>
+            <a-col :span="20" >
+              <a-row :guttr="[8, 2]" >
+                <a-col style="margin-right: 5px;" v-for="_ in item.desc" :key="_" >{{_}}</a-col>
+              </a-row>
+            </a-col>
+          </a-row>
+        </a-col>
+      </a-row>
+    </a-row>
+  </a-row>
+</modal-pro>
 </template>
 <script lang='ts'  setup >
+import { AiboxCloudController } from '@/controller'
+import { message } from 'ant-design-vue'
+import { ref, reactive, onMounted, watch, onUnmounted } from 'vue'
+
+const columns = [
+  {
+    title: '模版编号',
+    dataIndex: 'planNum',
+    key: 'planNum'
+  },
+  {
+    title: '模版状态',
+    dataIndex: 'planUse',
+    key: 'planUse'
+  },
+  {
+    title: '模板名称',
+    dataIndex: 'planName',
+    key: 'planName'
+  },
+  {
+    title: '模板时间',
+    dataIndex: 'planTime',
+    key: 'planTime'
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    key: 'action'
+  }
+]
+
+const weekMap = new Map([
+  ['1', '一'],
+  ['2', '二'],
+  ['3', '三'],
+  ['4', '四'],
+  ['5', '五'],
+  ['6', '六'],
+  ['7', '天']
+])
+const calcWeek = (week: string) => weekMap.get(week)
+
+const calcTime = (index: number) => index < 10 ? '0' + index : index
+
+const calcLtTen = (time: number) => time < 10 ? `0${time}` : time
+
+const tableProDom = ref()
+
+const initSelectTime = [
+  { week: '1', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '2', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '3', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '4', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '5', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '6', time: [], desc: [], value: '000000000000000000000000' },
+  { week: '7', time: [], desc: [], value: '000000000000000000000000' }
+]
+
+const planUseMap = new Map([
+  [0, { color: 'volcano', label: '未使用' }],
+  [1, { color: 'green', label: '使用中' }]
+])
+
+const state = reactive({
+  loading: false,
+  visible: false,
+  selectVisible: false, // 是否开始选择
+  dataSource: [],
+  selectTime: JSON.parse(JSON.stringify(initSelectTime)),
+  scheduleName: ''
+})
+
+const delPlan = async (planNum: number) => {
+  await AiboxCloudController.delPlan(planNum)
+  tableProDom.value.reload()
+}
+
+watch(
+  () => state.selectVisible,
+  () => {
+    const $r = state.selectTime.map(item => {
+      if (!item.time.length) {
+        item.desc = []
+        return item
+      }
+
+      const sortArr = item.time.sort((a, b) => a - b)
+
+      let len = 0
+
+      let start = sortArr[len]
+
+      const r = [[start]]
+
+      let col = 0
+
+      const _value = item.value.split('')
+
+      _value[Number(start)] = '1'
+
+      while (len < sortArr.length - 1) {
+        if (Number(start) + 1 !== Number(sortArr[len + 1])) {
+          col++
+          r.push([])
+        }
+        start = sortArr[len + 1]
+        r[col].push(start)
+        _value[Number(start)] = '1'
+
+        len++
+      }
+
+      item.value = _value.join('')
+
+      item.desc = r.map(v => {
+        const isTwentyThree = Number(v[v.length - 1]) === 23 ? -1 : Number(v[v.length - 1])
+
+        if (v.length !== 1) {
+          return `${calcLtTen(Number(v[0]))}: 00 ~ ${calcLtTen(isTwentyThree + 1)}: 00`
+        } else {
+          return `${calcLtTen(Number(v[0]))}: 00 ~ ${calcLtTen(isTwentyThree + 1)}: 00`
+        }
+      })
+
+      return item
+    })
+
+    state.selectTime = $r
+
+    // tableProDom.value.reload()
+  }
+)
+
+const onMouseUp = () => {
+  state.selectVisible = false
+}
+
+const onMouseEnter = (e: MouseEvent) => {
+  if (!state.selectVisible) return
+  e.target.style.backgroundColor = e.target.style.backgroundColor ? '' : 'skyblue'
+  const cusAttr = JSON.parse(Array.from(e.target.attributes).find(item => item.name === 'time').nodeValue)
+  const $r = state.selectTime.map(item => {
+    if (item.week === cusAttr.week) {
+      if (e.target.style.backgroundColor) {
+        item.time.push(cusAttr.hour)
+      } else {
+        item.time = item.time.filter(_ => _ !== cusAttr.hour)
+      }
+      item.time = Array.from(new Set([...item.time]))
+    }
+    return item
+  })
+  state.selectTime = $r
+}
+
+const onMouseDown = (e) => {
+  const cusAttr = JSON.parse(Array.from(e.target.attributes).find(item => item.name === 'time').nodeValue)
+
+  e.target.style.backgroundColor = e.target.style.backgroundColor ? '' : 'skyblue'
+  const $r = state.selectTime.map(item => {
+    if (item.week === cusAttr.week) {
+      if (e.target.style.backgroundColor) {
+        item.time.push(cusAttr.hour)
+      } else {
+        item.time = item.time.filter(_ => _ !== cusAttr.hour)
+      }
+
+      item.time = Array.from(new Set([...item.time]))
+    }
+    return item
+  })
+
+  state.selectTime = $r
+  state.selectVisible = true
+}
+
+const onsubmitSchedule = async () => {
+  if (state.scheduleName === '' || state.scheduleName === undefined) {
+    message.warn('请填写计划名称')
+    return
+  }
+  const summary = state.selectTime.map((item, index) => item.desc.length ? `星期${calcWeek(String(index + 1))} ${item.desc}` : '').filter(_ => _)
+
+  const $par = {
+    operation: 1,
+    planName: state.scheduleName,
+    planTime: JSON.stringify(summary),
+    planValue: state.selectTime.map((item, index) => item.value).join('')
+  }
+
+  await AiboxCloudController.addPlan($par)
+
+  state.scheduleName = ''
+  state.selectTime = JSON.parse(JSON.stringify(initSelectTime))
+
+  state.visible = false
+  tableProDom.value.reload()
+}
+
+const openModal = () => {
+  state.selectTime = JSON.parse(JSON.stringify(initSelectTime))
+  state.visible = true
+}
+
+onUnmounted(() => {
+  document.removeEventListener('mouseup', () => {})
+})
+
+onMounted(async () => {
+  document.addEventListener('mouseup', () => state.selectVisible = false)
+})
 
 </script>
 <style lang='less' scoped >

+ 11 - 0
src/type/cvs.d.ts

@@ -239,6 +239,17 @@ declare namespace CVS {
       taskSimilarityThreshold: string,
     }
 
+    interface Aig {
+      aigonum: string
+      aigoname: string
+      isSelect: boolean
+      setparam: {
+        argtype: string
+        setname: string
+        argvalue: string
+      }[]
+    }
+
   }
 
   namespace Nodes {