Browse Source

1. 编辑子项数据制作70%
2. ai报警界面待制作

kindring 2 years ago
parent
commit
86a78ee740

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

@@ -101,6 +101,13 @@ public interface IVideoManagerStorage {
 	 */
 	public List<AiConfig> queryItemByLibraryId(int libraryId);
 
+	/**
+	 * 获取item信息
+	 * @param itemId
+	 * @return
+	 */
+	public AiLib queryItemInfoByItemId(int itemId);
+
 	/**
 	 * 获取某个设备的通道列表
 	 *

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

@@ -77,6 +77,7 @@ public interface HfyDevAiMapper {
     List<AiLib> searchAiLibItem(String key,int libraryId);
 
 
+
     @Select(value = {" <script>" +
             "select * from ai_library where" +
             " libraryId != 0" +
@@ -117,6 +118,9 @@ public interface HfyDevAiMapper {
     @Select("select * from lib_item where libraryId = #{libraryId}")
     List<AiConfig> getLibItemByLibraryId(int libraryId);
 
+    @Select("select * from lib_item where itemId = #{itemId}")
+    List<AiLib> queryItemInfoByItemId(int itemId);
+
     @Insert("insert into lib_item(" +
             "libraryId," +
             "itemType," +

+ 5 - 0
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java

@@ -417,6 +417,11 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 		return HfyDevAiMapper.getLibItemByLibraryId(libraryId);
 	}
 
+	public AiLib queryItemInfoByItemId(int itemId){
+		List<AiLib> aiLibItemArr = HfyDevAiMapper.queryItemInfoByItemId(itemId);
+		if(aiLibItemArr.isEmpty()){throw new ControllerException(ErrorCode.ERROR400.getCode(),"无法找到该数据,请检查id");}
+		return aiLibItemArr.stream().findFirst().get();
+	}
 	@Override
 	public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count) {
 		// 获取到所有正在播放的流

+ 11 - 0
src/main/java/com/genersoft/iot/vmp/vmanager/bean/AiLib.java

@@ -34,6 +34,17 @@ public class AiLib {
     private String idCard;
     @Schema(description = "车牌号")
     private String carNo;
+    @Schema(description = "子项id")
+    private String itemId;
+    public String getItemId() {
+        return itemId;
+    }
+
+    public void setItemId(String itemId) {
+        this.itemId = itemId;
+    }
+
+
     public int getItemType() {
         return itemType;
     }

+ 10 - 0
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@@ -199,6 +199,16 @@ public class DeviceQuery {
 		return storager.queryItemByLibraryId(libraryId);
 	}
 
+	@Operation(summary = "ai库子项具体数据查询")
+	@Parameter(name = "itemId", description = "设备国标编号", required = true)
+	@GetMapping("/itemInfo/{itemId}")
+	public AiLib getLibItemInfo(@PathVariable int itemId){
+		if (logger.isDebugEnabled()) {
+			logger.debug("ai库子项数据查询");
+		}
+		return storager.queryItemInfoByItemId(itemId);
+	}
+
 	// allowEmptyValue
 
 

+ 108 - 0
web_src/src/components/common/SImg.vue

@@ -0,0 +1,108 @@
+<template>
+  <div class="imgBox">
+    <el-image v-show="showRaw" :src="rawImage" alt="21" class="baseImg"/>
+    <img v-show="!showRaw" ref="showImg" src="" alt="" class="showImg"/>
+    <input class="fileInput"
+           type="file"
+           accept="image/png, image/jpeg"
+           ref="fileInput"
+           @change="fileChangeHandle">
+    <div class="closeBtn" @click="clearSelect">x</div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "ImgSelect",
+  props:{
+    rawImage:{default:''}
+  },
+  data(){
+    return {
+      //
+      showRaw: true,
+    }
+  },
+  mounted(){
+    console.log(this.showRaw);
+  },
+  methods:{
+    fileChangeHandle(){
+      let files = this.$refs.fileInput.files;
+      console.log(files);
+      console.log('1234');
+      let imgFile = files[0];
+      if(!imgFile){
+        this.showRaw = true;
+        return this.$message.warning('未选择图片')}
+      // 检查格式
+      let imageTypeReg = /^image\//;
+      if(!imageTypeReg.test(imgFile.type)){
+        this.$refs.fileInput.files = null;
+        this.showRaw = true;
+        return this.$message.warning('未受支持的格式')
+      }
+      // 发送change事件
+      this.$emit("imgChange",imgFile);
+      this.showRaw = false;
+      // 设置预览图
+      this.$refs.showImg.file = imgFile;
+      let reader = new FileReader();
+      reader.onload = (function(aImg) {
+        return function(e) { aImg.src = e.target.result; }; })
+      (this.$refs.showImg);
+      reader.readAsDataURL(imgFile);
+    },
+    clearSelect(){
+      this.showRaw = true;
+      this.$emit("imgChange")
+    }
+  }
+}
+</script>
+
+<style scoped>
+.imgBox{
+  width: 100%;
+  height: 100%;
+  min-width: 50px;
+  min-height: 50px;
+  position: relative;
+  display: flex;
+  justify-content: center;
+  box-shadow: 0 0 3px lightgray;
+}
+.imgBox .showImg,.fileInput,.baseImg{
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  display: block;
+}
+.imgBox .fileInput{
+  left: 0;
+  top: 0;
+}
+.imgBox .showImg,.baseImg{
+  height: 100%;
+  width: auto;
+  max-width: 100%;
+}
+.imgBox .fileInput{
+  opacity: 0;
+}
+.imgBox .closeBtn{
+  width: 25px;
+  height: 25px;
+  border-radius: 50%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: absolute;
+  right: 5px;
+  top: 5px;
+  color: red;
+  cursor: pointer;
+  box-shadow: 1px 1px 2px gray;
+}
+
+</style>

+ 185 - 0
web_src/src/components/dialog/editLibItem.vue

@@ -0,0 +1,185 @@
+<template>
+  <div v-loading="isLoading">
+    <el-dialog :title="isEdit?`编辑[${rawData.itemName}]信息`:`新增子项`" top="0" :close-on-click-modal="false" :visible.sync="showThisDialog" >
+      <div class="line">
+        <div class="label">
+          {{arithmetic === aiTypes.face? "员工姓名":"车辆名称"}}
+        </div>
+        <div class="input">
+          <el-input v-model="itemName"></el-input>
+        </div>
+      </div>
+
+      <div class="line img-line" v-if="arithmetic === aiTypes.face">
+        <div class="label">
+          员工照片
+        </div>
+        <div class="input">
+          <div class="" style="width: 100px;height: 100px">
+            <s-img :raw-image="'/aiLib/libImg/'+rawData.imageUrl"
+                   @imgChange="imgChangeHandle"
+            ></s-img>
+          </div>
+        </div>
+      </div>
+
+      <div class="line">
+        <div class="label">
+          {{arithmetic === aiTypes.face? "员工工号":"车牌号"}}
+        </div>
+        <div class="input">
+          <el-input v-model="itemNo"></el-input>
+        </div>
+      </div>
+
+      <div class="line">
+        <div class="label">
+          {{arithmetic === aiTypes.face? "身份证":"车牌号"}}
+        </div>
+        <div class="input">
+          <el-input v-if="arithmetic === aiTypes.face" v-model="idCard"></el-input>
+          <el-input v-if="arithmetic === aiTypes.carPlate" v-model="carNo"></el-input>
+        </div>
+      </div>
+      <el-divider></el-divider>
+      <el-button-group>
+        <el-button @click="resetData" type="danger">重置</el-button>
+        <el-button v-if="!isEdit" type="primary" @click="addHandle">添加数据</el-button>
+        <el-button v-else-if="isEdit" type="primary" @click="editHandle">编辑数据</el-button>
+      </el-button-group>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import aiMap from "@/map/ai"
+import handle from "@/until/handle";
+import SImg from "@/components/common/SImg";
+export default {
+  name: "editLibItem",
+  components: {SImg},
+  data(){
+    return {
+      aiTypes: aiMap.aiTypes,
+      isLoading:false,
+      showThisDialog:false,
+      arithmetic: 0,
+      isEdit: false,
+      rawData: {},
+      itemId: '',
+      itemName: '',
+      itemNo: '',
+      itemType: '',
+      trait: '',
+      imageUrl: '',
+      carNo: '',
+      idCard: ''
+    }
+  },
+  methods:{
+    init(){
+      this.arithmetic = 0;
+      this.itemName= '';
+    },
+    async openEditDialog(libraryId,arithmetic,itemId){
+      this.isEdit = true;
+      this.libraryId = libraryId;
+      this.arithmetic = arithmetic;
+      this.itemId = itemId;
+      await this.loadLibItemData();
+      this.showDialog();
+    },
+    openAddDialog(libraryId,arithmetic){
+      this.libraryId = libraryId;
+      this.arithmetic = arithmetic;
+      this.isEdit = false;
+      this.showDialog();
+    },
+    showDialog(){
+      this.showThisDialog = true;
+    },
+    resetData(){
+      this.itemName = this.rawData.itemName;
+      this.imageUrl = "";
+      this.uploadFile = null;
+      this.itemNo = this.rawData.itemNo;
+      this.itemType = this.rawData.itemType;
+      this.trait = this.rawData.trait;
+      this.carNo = this.rawData.carNo;
+    },
+    async loadLibItemData(){
+      this.isLoading = true;
+      let url = `/api/device/query/itemInfo/${this.itemId}`
+      let [err,res] = await handle(this.$axios(
+        {
+          method: 'get',
+          url: url
+        }
+      ));
+      this.isLoading = false;
+      if(err){
+        console.error(err);
+        console.error(res);
+        this.$message.error(err.message);
+        return;
+      }
+      console.log('------------');
+      console.log(res)
+      let result = res.data;
+      if(res.data.code === 0){
+        this.rawData = result.data;
+        this.resetData();
+      }
+
+    },
+    imgChangeHandle(file){
+      if(file){
+        console.log('修改图片')
+        this.uploadFile = file;
+        console.log(file);
+      }else{
+        console.log('不修改图片')
+        this.imageUrl = "";
+        this.uploadFile = null;
+      }
+    },
+    addHandle(){
+
+    },
+    editHandle(){
+      // 获取编辑项
+
+    }
+  },
+
+}
+</script>
+
+<style scoped>
+.line{
+  width: 100%;
+  height: 35px;
+  display: flex;
+  margin-bottom: 10px;
+
+}
+.img-line{
+  height: 120px;
+}
+.line .label{
+  width: 20%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.line .input{
+  width: 80%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  padding-left: 8px;
+  border-left: 1px solid grey;
+}
+</style>

+ 18 - 1
web_src/src/components/editLib.vue

@@ -10,10 +10,13 @@
         </el-input>
       </div>
       <div class="page-header-btn">
+        <el-button icon="el-icon-plus" size="mini" style="font-size: 16px; color: #000;" type="text" :loading="isLoading" @click="addLibItemHandle" >
+          添加子项</el-button>
         <el-button icon="el-icon-edit" size="mini" style="font-size: 16px; color: #000;" type="text" :loading="isLoading" @click="editMode" >
           {{ isEdit?'取消编辑':'编辑' }}</el-button>
       </div>
     </div>
+    <edit-lib-item ref="editLibItem"></edit-lib-item>
     <el-container v-loading="isLoading" style="width:100%;min-height: 82vh;flex-direction: column;" >
       <div class="">
         <el-input class="ml-5 input-with-select" placeholder="输入工人信息片段" v-model="key" >
@@ -29,7 +32,7 @@
         <el-table-column prop="itemId" label="id" ></el-table-column>
         <el-table-column v-if="libData.arithmetic === aiTypes.face" prop="imageUrl" label="照片" min-width="160">
           <template slot-scope="scope">
-            <img class="personImg" :src="`/aiLib/libImg/${scope.row.imageUrl}`" :alt="`${scope.row.itemName}的照片`"/>
+            <el-image class="personImg" :src="`/aiLib/libImg/${scope.row.imageUrl}`" :alt="`${scope.row.itemName}的照片`"/>
           </template>
         </el-table-column>
         <el-table-column prop="itemName"
@@ -61,9 +64,11 @@
 <script>
 import aiMap from "@/map/ai";
 import handle from "@/until/handle";
+import EditLibItem from "@/components/dialog/editLibItem";
 
 export default {
   name: "editLib",
+  components: {EditLibItem},
   data(){
     return {
       aiTypes: aiMap.aiTypes,
@@ -186,6 +191,18 @@ export default {
     },
     editLibItemHandle(row){
       console.log('编辑员工');
+      console.log(row);
+      this.$refs.editLibItem.openEditDialog(
+        this.libraryId,
+        this.libData.arithmetic,
+        row.itemId,
+      )
+    },
+    addLibItemHandle(){
+      this.$refs.editLibItem.openAddDialog(
+        this.libraryId,
+        this.libData.arithmetic,
+      )
     },
     changePage(){
       // 使用当前配置进行搜索

+ 19 - 4
参考文档/数据库扩展.md

@@ -50,8 +50,23 @@
 | arithmetic | int | 1-3 | 对应的算法.人脸,火情,车牌, |
 
 ### ai告警库 ai_alarm
-| 字段    | 类型  | 可选值 | 备注  |
-|-------|-----| --- |-----|
-
-
+| 字段         | 类型  | 可选值 | 备注                  |
+|------------|-----| --- |---------------------|
+| alarmId    | pk | |                     |
+| arithmetic | int | 1-3 | 算法                  |
+| mediaPath  | varchar | 255 | 资源地址                |
+| alarmState | int | 1-5 | 告警状态 1 未读, 2忽略,3已处理 |  
+| createTime | varchar | 255 | 报警时间, 时间戳           |
+| operationTime | varchar | 255 | 操作时间,时间戳            |
 
+### ai告警库 ai_alarm_item
+| 字段       | 类型 | 可选值 | 备注  |
+|----------|--| --- |---------------------|
+| itemId   | int | pk | id |
+| alarmId  | int | tk | id |
+|score | float | 0-100 | 相似度 |
+|x1 | float | n | 位置x1 |
+|x2 | float | n | 位置x2 |
+|y1 | float | n | 位置y1 |
+|y2 | float | n | 位置y2 |
+| info | Varchar | | 文字信息 |