kindring 2 жил өмнө
parent
commit
d57f1a1a9e

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java

@@ -136,7 +136,7 @@ public class DeviceServiceImpl implements IDeviceService {
         // 刷新过期任务
         String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
 //      // 设备过期时间多增加3秒
-        dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), (device.getExpires() * 1000) + 5000);
+        dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), ((device.getExpires() * 1000) * 2 ) + 5);
     }
 
     @Override

+ 2 - 2
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java

@@ -59,9 +59,9 @@ public interface IVideoManagerStorage {
 	 * 获取所有的ai配置项
 	 * @return
 	 */
-	public List<AiConfig> queryAiConfigList();
+	public List<AiConfig> queryAiConfigList(int arithmetic);
 
-	public List<AiConfig> devUseAiConfig(String deviceId,int configId);
+	public int devUseAiConfig(String deviceId,int configId);
 	/**
 	 * 获取数据库中所有的ai库
 	 * @return

+ 2 - 2
src/main/java/com/genersoft/iot/vmp/storager/dao/HfyDevAiMapper.java

@@ -15,8 +15,8 @@ public interface HfyDevAiMapper {
             "left Join dev_ai_config as dc on dc.configId = c.configId " +
             "where dc.deviceId = #{deviceId}")
     List<AiConfig> getDevAiConfigByDeviceId(String deviceId);
-    @Select("select * from ai_configs")
-    List<AiConfig> getAiConfigList();
+    @Select("select * from ai_configs where arithmetic = ${arithmetic}")
+    List<AiConfig> getAiConfigList(int arithmetic);
 
     @Insert("insert into ai_config(" +
             "libraryId," +

+ 10 - 2
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java

@@ -238,8 +238,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 		return HfyDevAiMapper.getDevAiConfigByDeviceId(deviceId);
 	}
 
-	public List<AiConfig> queryAiConfigList() {
-		return HfyDevAiMapper.getAiConfigList();
+	public List<AiConfig> queryAiConfigList(int arithmetic) {
+		return HfyDevAiMapper.getAiConfigList(arithmetic);
+	}
+
+
+	public int devUseAiConfig(String deviceId,int configId) {
+		AiConfig aiConfig = new AiConfig();
+		aiConfig.setConfigId(configId);
+		aiConfig.setDeviceId(deviceId);
+		return HfyDevAiMapper.devUseConfig(aiConfig);
 	}
 
 	/**

+ 4 - 3
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@@ -97,19 +97,20 @@ public class DeviceQuery {
 	}
 
 	@Operation(summary = "获取所有ai配置")
+	@Parameter(name = "arithmetic", description = "对应算法", required = true)
 	@GetMapping("/aiConfigs")
-	public List<AiConfig> aiConfigList(){
+	public List<AiConfig> aiConfigList(@RequestParam int arithmetic){
 		if (logger.isDebugEnabled()) {
 			logger.debug("查询所有的ai配置列表");
 		}
-		return storager.queryAiConfigList();
+		return storager.queryAiConfigList(arithmetic);
 	}
 
 	@Operation(summary = "设备使用ai配置")
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "configId", description = "配置id", required = true)
 	@GetMapping("/useAi/{deviceId}/{configId}")
-	public List<AiConfig> devUseConfig(@PathVariable String deviceId,@PathVariable int configId){
+	public int devUseConfig(@PathVariable String deviceId,@PathVariable int configId){
 		if (logger.isDebugEnabled()) {
 			logger.debug("设备使用ai配置");
 		}

+ 27 - 0
web_src/src/assets/index.css

@@ -15,3 +15,30 @@
 .space-between{
   justify-content: space-between;
 }
+
+.el-dialog{
+  display: flex;
+  display: -ms-flex; /* 兼容IE */
+  flex-direction: column;
+  -ms-flex-direction: column; /* 兼容IE */
+  margin:0 !important;
+  position:absolute;
+  top:50%;
+  left:50%;
+  transform:translate(-50%,-50%);
+  max-height:calc(100% - 30px);
+  max-width:calc(100% - 30px);
+  transition: all 1s;
+}
+.el-dialog .el-dialog__body{
+  max-height: 100%;
+  flex: 1;
+  -ms-flex: 1 1 auto; /* 兼容IE */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.el-dialog__wrapper {
+  /*隐藏ie和edge中遮罩的滚动条*/
+  overflow: hidden;
+}

+ 206 - 37
web_src/src/components/aiConfig.vue

@@ -7,61 +7,202 @@
       ai订阅配置
     </div>
     <div class="page-header-btn">
-      <el-tooltip class="item" effect="dark" content="添加算法" placement="left-start">
-        <el-button icon="el-icon-plus" circle size="mini" @click="showArithmeticDialog" ></el-button>
-      </el-tooltip>
+<!--      <el-tooltip class="item" effect="dark" content="添加算法" placement="left-start">-->
+<!--        <el-button icon="el-icon-plus" circle size="mini" @click="showArithmeticDialog" ></el-button>-->
+<!--      </el-tooltip>-->
     </div>
   </div>
-  <add-arithmetic ref="addArithmeticDialog" ></add-arithmetic>
+  <add-arithmetic ref="addArithmeticDialog" @select="selectConfigHandle" ></add-arithmetic>
   <el-container v-loading="isLoading" style="min-height: 82vh;flex-direction: column;" >
-    <el-card class="box-card" v-for="item in useAiList" :key="item.arithmetic">
+    <el-card  class="box-card">
       <div slot="header" class="card-header flex space-between align-center" >
-        <span>{{ toArithmetic(item.arithmetic).text }}</span>
+        <span>{{toArithmetic(aiTypes.face).text}}</span>
 
         <el-button-group>
-          <el-button icon="el-icon-edit" @click="showEditAi(item.id)">调整算法</el-button>
-          <el-button icon="el-icon-delete" type="danger">关闭该算法</el-button>
+          <el-button icon="el-icon-edit" @click="showArithmeticDialog(aiTypes.face)">更改配置</el-button>
         </el-button-group>
       </div>
 
-      <div class="ai-info">
 
+      <div class="ai-info" v-if="arithmetic[aiTypes.face].configId">
+              <div class="info-item">
+                <div class="label">检验类型:</div>
+                <div class="text">{{toTriggerType(arithmetic[aiTypes.face].triggerType).text}}</div>
+              </div>
+
+              <div class="info-item">
+                <div class="label">触发相似度:</div>
+                <div class="text">{{arithmetic[aiTypes.face].score}}%</div>
+              </div>
+
+              <div class="info-item">
+                <div class="label">使用数据库:</div>
+                <div class="text">{{ toAiData(arithmetic[aiTypes.face].libraryId).libraryName }}</div>
+              </div>
+              <div class="info-item">
+                <div class="label">数据库版本:</div>
+                <div class="text">{{ toAiData(arithmetic[aiTypes.face].libraryId).version }}</div>
+              </div>
+              <div class="info-item">
+                <div class="label">名单数量:</div>
+                <div class="text">{{ toAiData(arithmetic[aiTypes.face].libraryId).total }}</div>
+              </div>
+              <div class="info-item">
+                <div class="label">资源路径:</div>
+                <div class="text">{{ arithmetic[aiTypes.face].resourcePath }}</div>
+              </div>
+              <div class="info-item">
+                <div class="label">多媒体资源上传地址:</div>
+                <div class="text">{{ arithmetic[aiTypes.face].uploadUrl }}</div>
+              </div>
+              <div class="info-item">
+                <div class="label">报警推送回调地址:</div>
+                <div class="text">{{ arithmetic[aiTypes.face].pushUrl }}</div>
+              </div>
+            </div>
+      <div class="ai-info-not" v-else-if="!arithmetic[aiTypes.face].configId">
+          未启用{{toArithmetic(aiTypes.face).text}}
+        <el-button @click="showArithmeticDialog(aiTypes.face)">选择{{toArithmetic(aiTypes.face).text}}配置</el-button>
+      </div>
+    </el-card>
+
+    <el-card  class="box-card">
+      <div slot="header" class="card-header flex space-between align-center" >
+        <span>{{toArithmetic(aiTypes.carPlate).text}}</span>
+
+        <el-button-group>
+          <el-button icon="el-icon-edit" @click="showArithmeticDialog(aiTypes.carPlate)">更改配置</el-button>
+        </el-button-group>
+      </div>
+      <div class="ai-info" v-if="arithmetic[aiTypes.carPlate].configId">
         <div class="info-item">
           <div class="label">检验类型:</div>
-          <div class="text">{{toTriggerType(item.triggerType).text}}</div>
+          <div class="text">{{toTriggerType(arithmetic[aiTypes.carPlate].triggerType).text}}</div>
         </div>
 
         <div class="info-item">
           <div class="label">触发相似度:</div>
-          <div class="text">{{item.score}}%</div>
+          <div class="text">{{arithmetic[aiTypes.carPlate].score}}%</div>
         </div>
 
         <div class="info-item">
           <div class="label">使用数据库:</div>
-          <div class="text">{{ toAiData(item.libraryId).libraryName }}</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.carPlate].libraryId).libraryName }}</div>
         </div>
         <div class="info-item">
           <div class="label">数据库版本:</div>
-          <div class="text">{{ toAiData(item.libraryId).version }}</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.carPlate].libraryId).version }}</div>
         </div>
         <div class="info-item">
           <div class="label">名单数量:</div>
-          <div class="text">{{ toAiData(item.libraryId).total }}</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.carPlate].libraryId).total }}</div>
         </div>
         <div class="info-item">
           <div class="label">资源路径:</div>
-          <div class="text">{{ item.resourcePath }}</div>
+          <div class="text">{{ arithmetic[aiTypes.carPlate].resourcePath }}</div>
         </div>
         <div class="info-item">
           <div class="label">多媒体资源上传地址:</div>
-          <div class="text">{{ item.uploadUrl }}</div>
+          <div class="text">{{ arithmetic[aiTypes.carPlate].uploadUrl }}</div>
         </div>
         <div class="info-item">
           <div class="label">报警推送回调地址:</div>
-          <div class="text">{{ item.pushUrl }}</div>
+          <div class="text">{{ arithmetic[aiTypes.carPlate].pushUrl }}</div>
         </div>
       </div>
+      <div class="ai-info-not" v-if="!arithmetic[aiTypes.carPlate].configId">
+        未启用{{toArithmetic(aiTypes.carPlate).text}}
+        <el-button @click="showArithmeticDialog(aiTypes.carPlate)">选择{{toArithmetic(aiTypes.carPlate).text}}配置</el-button>
+      </div>
     </el-card>
+
+    <el-card  class="box-card">
+      <div slot="header" class="card-header flex space-between align-center" >
+        <span>{{toArithmetic(aiTypes.fire).text}}</span>
+
+        <el-button-group>
+          <el-button icon="el-icon-edit" @click="showArithmeticDialog(aiTypes.fire)">更改配置</el-button>
+        </el-button-group>
+      </div>
+      <div class="ai-info" v-if="arithmetic[aiTypes.fire].configId">
+        <div class="info-item">
+          <div class="label">检验类型:</div>
+          <div class="text">{{toTriggerType(arithmetic[aiTypes.fire].triggerType).text}}</div>
+        </div>
+
+        <div class="info-item">
+          <div class="label">触发相似度:</div>
+          <div class="text">{{arithmetic[aiTypes.fire].score}}%</div>
+        </div>
+
+        <div class="info-item">
+          <div class="label">使用数据库:</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.fire].libraryId).libraryName }}</div>
+        </div>
+        <div class="info-item">
+          <div class="label">数据库版本:</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.fire].libraryId).version }}</div>
+        </div>
+        <div class="info-item">
+          <div class="label">名单数量:</div>
+          <div class="text">{{ toAiData(arithmetic[aiTypes.fire].libraryId).total }}</div>
+        </div>
+        <div class="info-item">
+          <div class="label">资源路径:</div>
+          <div class="text">{{ arithmetic[aiTypes.fire].resourcePath }}</div>
+        </div>
+        <div class="info-item">
+          <div class="label">多媒体资源上传地址:</div>
+          <div class="text">{{ arithmetic[aiTypes.fire].uploadUrl }}</div>
+        </div>
+        <div class="info-item">
+          <div class="label">报警推送回调地址:</div>
+          <div class="text">{{ arithmetic[aiTypes.fire].pushUrl }}</div>
+        </div>
+      </div>
+      <div class="ai-info-not" v-if="!arithmetic[aiTypes.fire].configId">
+        未启用{{toArithmetic(aiTypes.face).text}}
+        <el-button @click="showArithmeticDialog(aiTypes.fire)">选择{{toArithmetic(aiTypes.fire).text}}配置</el-button>
+      </div>
+    </el-card>
+
+
+<!--      <div class="ai-info">-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">检验类型:</div>-->
+<!--          <div class="text">{{toTriggerType(item.triggerType).text}}</div>-->
+<!--        </div>-->
+
+<!--        <div class="info-item">-->
+<!--          <div class="label">触发相似度:</div>-->
+<!--          <div class="text">{{item.score}}%</div>-->
+<!--        </div>-->
+
+<!--        <div class="info-item">-->
+<!--          <div class="label">使用数据库:</div>-->
+<!--          <div class="text">{{ toAiData(item.libraryId).libraryName }}</div>-->
+<!--        </div>-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">数据库版本:</div>-->
+<!--          <div class="text">{{ toAiData(item.libraryId).version }}</div>-->
+<!--        </div>-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">名单数量:</div>-->
+<!--          <div class="text">{{ toAiData(item.libraryId).total }}</div>-->
+<!--        </div>-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">资源路径:</div>-->
+<!--          <div class="text">{{ item.resourcePath }}</div>-->
+<!--        </div>-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">多媒体资源上传地址:</div>-->
+<!--          <div class="text">{{ item.uploadUrl }}</div>-->
+<!--        </div>-->
+<!--        <div class="info-item">-->
+<!--          <div class="label">报警推送回调地址:</div>-->
+<!--          <div class="text">{{ item.pushUrl }}</div>-->
+<!--        </div>-->
+<!--      </div>-->
   </el-container>
 </div>
 </template>
@@ -70,12 +211,14 @@
 import aiMap from "../map/ai"
 import {toNumber} from "../until/typeTool";
 import AddArithmetic from "./dialog/addArithmetic";
+import handle from "@/until/handle";
 
 export default {
   name: "aiConfig",
   components: {AddArithmetic},
   data(){
     return {
+      aiTypes: aiMap.aiTypes,
       deviceId: this.$route.params.deviceId,
       isLoading: false,
       arithmeticEnum:aiMap.arithmeticEnum,
@@ -84,6 +227,12 @@ export default {
       ],
       useAiList: [
       ],
+      // 匹配的算法
+      arithmetic:{
+        [aiMap.aiTypes.face]:{},
+        [aiMap.aiTypes.carPlate]:{},
+        [aiMap.aiTypes.fire]:{},
+      }
     }
   },
   async mounted(){
@@ -106,31 +255,32 @@ export default {
         this.beforeUrl = "/deviceList"
       }
     },
-    loadAiLib(){
+    async loadAiLib(){
       this.isLoading = true;
       let that = this;
-      return this.$axios({
+      let [err,res] = await handle(this.$axios({
         method: 'get',
-        url: '/api/device/query/aiLibrary'
-      }).then((res) => {
-        // console.log("获取ai数据结果:" + JSON.stringify(res));
-        this.isLoading = false;
-        // console.log(res);
-        let data = res.data;
-        if(data.code === 0 ){
-          that.aiList = data.data;
-        }else{
-          console.log(res);
-          console.error("未知的返回结果!")
-        }
-      }).catch((e) => {
-        console.error(e)
+        url: `/api/device/query/aiLibrary`
+      }))
+      this.isLoading = false;
+      if (err){
+        console.error(err)
         that.$message({
           showClose: true,
-          message: e,
+          message: err,
           type: 'error'
         });
-      });
+        return;
+      }
+      let data = res.data;
+      if(data.code === 0 ){
+        //
+
+        that.aiList = data.data;
+      }else{
+        console.log(res);
+        console.error("未知的返回结果!")
+      }
     },
     loadDeviceAi(){
       this.isLoading = true;
@@ -144,6 +294,21 @@ export default {
         // console.log(res);
         let data = res.data;
         if(data.code === 0 ){
+          data.data.forEach(ai=>{
+            console.log(ai)
+            if(toNumber(ai.arithmetic) === toNumber(aiMap.aiTypes.face)){
+              console.log('人脸')
+              this.arithmetic[aiMap.aiTypes.face] = ai;
+            } else if(toNumber(ai.arithmetic) === toNumber(aiMap.aiTypes.carPlate)){
+              console.log('车牌')
+              this.arithmetic[aiMap.aiTypes.carPlate] = ai;
+            }else if(toNumber(ai.arithmetic) === toNumber(aiMap.aiTypes.fire)){
+              console.log('火情')
+              this.arithmetic[aiMap.aiTypes.fire] = ai;
+            }else{
+              console.error("未知的ai类型");
+            }
+          })
           that.useAiList = data.data;
         }else{
           console.log(res);
@@ -158,11 +323,15 @@ export default {
         });
       });
     },
+    async selectConfigHandle(configId){
+      console.log("-*----"+configId);
+
+    },
     showEditAi(id){
       this.$router.push(`/devEditAi/${id}`);
     },
-    showArithmeticDialog(){
-      this.$refs.addArithmeticDialog.showDialog(this.deviceId);
+    showArithmeticDialog(arithemtic){
+      this.$refs.addArithmeticDialog.showDialog(arithemtic,this.deviceId,this.aiList,this.arithmetic[arithemtic]);
     }
 
   }

+ 84 - 26
web_src/src/components/dialog/addArithmetic.vue

@@ -1,36 +1,76 @@
 <template>
   <div id="ptzControl " v-loading="isLoading">
-    <el-dialog title="为设备启用算法" top="0" :close-on-click-modal="false" :visible.sync="showThisDialog" @close="close()">
+    <el-dialog :title="`选择${aiTypeInfo.text}配置`" top="0" :close-on-click-modal="false" :visible.sync="showThisDialog" @close="close()">
+      <div id="shared" style="text-align: right; margin-top: 1rem;" v-if="aiConfigs.length">
+        <div :class="`config ${selectConfigId==item.configId?'config-select':''} ${useArithmetic.configId==item.configId?'config-disable':''}`" v-for="item in aiConfigs"  :key="item.configId" @click="selectConfig(item.configId)">
+          <div class="config-left">
+            {{item.configName}}
+          </div>
+          <div class="config-right">
 
+          </div>
+        </div>
+      </div>
+      <div id="shared2" style=" margin-top: 1rem;" v-else-if="loaded&&!aiConfigs.length">
+        无法找到{{aiTypeInfo.text}}的配置文件
+      </div>
+      <el-button-group>
+        <el-button @click="saveDevAiConfig">确认</el-button>
+      </el-button-group>
     </el-dialog>
   </div>
 </template>
 
 <script>
 import handle from "@/until/handle"
+import aiMap from "@/map/ai"
 export default {
   name: "addArithmetic",
   data(){
     return {
+      arithmetic: 1,// 类型
+      aiTypeInfo: {},
       deviceId: '',
+      libs: [],
+      useArithmetic: {},
       isLoading: false,
+      loaded: false,
       showThisDialog: false,
-      aiConfigs: []
+      aiConfigs: [],
+      selectConfigId: 0,
     }
   },
+  mounted() {
+  },
+  beforeDestroy() {
+    console.log('close ')
+  },
   methods:{
-    showDialog(deviceId){
+    initData(){
+      this.aiConfigs = [];
+      this.loaded = false;
+      this.selectConfigId=0;
+    },
+    async showDialog(arithmetic,deviceId,libs,useAiList){
+      this.initData();
+      this.aiTypeInfo = aiMap.toArithmetic(arithmetic);
+      this.arithmetic = arithmetic;
       this.showThisDialog = true;
       this.deviceId = deviceId;
+      this.libs = libs;
+      this.useArithmetic = useAiList;
+
       console.log(handle);
+      await this.loadAiConfigs();
     },
     async loadAiConfigs(){
       this.isLoading = true;
       let [err,res] = await handle(this.$axios({
         method: 'get',
-        url: '/api/device/query/aiLibrary'
+        url: `/api/device/query/aiConfigs?arithmetic=${this.arithmetic}`
       }))
       this.isLoading = false;
+      this.loaded = true;
       if(err){
         console.error(err)
         this.$message({
@@ -42,43 +82,61 @@ export default {
       }
 
       let data = res.data;
+      console.log(data);
       if(data.code === 0 ){
         this.aiConfigs = data.data;
       }else{
         console.log(res);
         console.error("未知的返回结果!")
       }
+    },
+    selectConfig(configId){
+      console.log(configId)
+      this.selectConfigId = configId;
+    },
+    saveDevAiConfig(){
+      if(!this.selectConfigId){
+        return this.$message.warning("请选择配置文件")
+      }
+      this.$emit('select',this.selectConfigId);
+      this.$nextTick(()=>{
+        this.showThisDialog = false;
+      })
     }
 
+
   }
 }
 </script>
 
-<style >
-.el-dialog{
+<style scoped>
+.config{
+  width: 96%;
+  height: auto;
+  padding: 15px 5px;
+  border-radius: 0.25rem;
+  margin-bottom: 10px;
+  box-shadow: 0 0 1px gray;
   display: flex;
-  display: -ms-flex; /* 兼容IE */
-  flex-direction: column;
-  -ms-flex-direction: column; /* 兼容IE */
-  margin:0 !important;
-  position:absolute;
-  top:50%;
-  left:50%;
-  transform:translate(-50%,-50%);
-  max-height:calc(100% - 30px);
-  max-width:calc(100% - 30px);
-  transition: all 1s;
+  justify-content: space-between;
 }
-.el-dialog .el-dialog__body{
-  max-height: 100%;
-  flex: 1;
-  -ms-flex: 1 1 auto; /* 兼容IE */
-  overflow-y: auto;
-  overflow-x: hidden;
+.config:hover{
+  background-color: #eff;
 }
 
-.el-dialog__wrapper {
-  /*隐藏ie和edge中遮罩的滚动条*/
-  overflow: hidden;
+.config-disable{
+  background-color:#eee;
+  cursor: not-allowed;
+}
+.config-select{
+  background-color: #eff;
+}
+.config-left{
+  width: 40%;
+  text-align: left;
+}
+.config-right{
+  display: flex;
+  width: 60%;
 }
 </style>

+ 2 - 1
参考文档/数据库扩展.md

@@ -29,7 +29,7 @@
 |-------| -- | --- |-----|
 | configId | int | pk | 配置id |
 | libraryId | int | tk | 图形库id |
-| arithmetic | int | 1-3 | 启用的算法.人脸,火情,车牌, |
+| arithmetic | int | 1-3 | 对应的算法.人脸,火情,车牌, |
 | triggerType | int | 1-3 | 触发类型 无限制,白名单,黑名单 |
 | refreshTime | int | 0-n | 刷新时间 单位秒 |
 | score | float | 0.0-100.0 | 检测阈值 |
@@ -42,3 +42,4 @@
 |-------| -- | --- |-----|
 | deviceId | int | tk | 设备id |
 | configId | int | tk | 配置id |
+| arithmetic | int | 1-3 | 对应的算法.人脸,火情,车牌, |