Browse Source

1. 文件读取接口制作
2. ai库控制接口制作

kindring 2 năm trước cách đây
mục cha
commit
0aced4adba

+ 1 - 0
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java

@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import com.genersoft.iot.vmp.vmanager.gb28181.device.DeviceQuery;
+import com.genersoft.iot.vmp.vmanager.gb28181.aiLib.AiControl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;

+ 3 - 1
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java

@@ -92,7 +92,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                     .antMatchers("/swagger-resources/**")
                     .antMatchers("/v3/api-docs/**")
                     .antMatchers("/favicon.ico")
+                    .antMatchers("/libImages/**")
                     .antMatchers("/js/**");
+
             List<String> interfaceAuthenticationExcludes = userSetting.getInterfaceAuthenticationExcludes();
             for (String interfaceAuthenticationExclude : interfaceAuthenticationExcludes) {
                 if (interfaceAuthenticationExclude.split("/").length < 4 ) {
@@ -129,7 +131,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         http.headers().contentTypeOptions().disable();
         http.authorizeRequests()
                 // 放行接口
-                .antMatchers("/api/user/login","/index/hook/**").permitAll()
+                .antMatchers("/api/user/login","/index/hook/**","/aiLib/**").permitAll()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()
                 // 异常处理(权限拒绝、登录失效等)

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

@@ -70,7 +70,9 @@ public interface IVideoManagerStorage {
 	 */
 	public List<AiLib> queryLibraryList();
 
+	public AiLib getLibraryInfo(int libraryId);
 	public int addAiLib(Integer arithmetic,String libraryName);
+	public int editLib(int libraryId,AiLib aiLib);
 
 	/**
 	 * 添加数据库子项
@@ -145,8 +147,10 @@ public interface IVideoManagerStorage {
 	 */
 	public PageInfo<Device> queryVideoDeviceList(int page, int count);
 
-
+	public PageInfo<AiLib> searchAiLibItems(int page,int count,int libraryId,String key);
 	public PageInfo<AiLib> searchAiLib(int page,int count,String key,Integer arithmetic);
+
+
 	/**
 	 * 获取多个设备
 	 *

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

@@ -67,6 +67,16 @@ public interface HfyDevAiMapper {
     @Select("select * from ai_library ")
     List<AiLib> getAiLibraryList();
 
+
+    @Select(value = {" <script>" +
+            "select * from lib_item where" +
+            " libraryId = ${libraryId}" +
+            " <if test=\"key != null and key != ''\">and (itemName like '%${key}%' or itemNo like '%${key}%')</if>" +
+            " " +
+            " </script>"})
+    List<AiLib> searchAiLibItem(String key,int libraryId);
+
+
     @Select(value = {" <script>" +
             "select * from ai_library where" +
             " libraryId != 0" +

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

@@ -277,6 +277,12 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 	public List<AiLib> queryLibraryList(){
 		return HfyDevAiMapper.getAiLibraryList();
 	}
+	public AiLib getLibraryInfo(int libraryId){
+		List<AiLib> aiLibArr = HfyDevAiMapper.getAiLibraryByLibId(libraryId);
+		if(aiLibArr.isEmpty()){throw new ControllerException(ErrorCode.ERROR400.getCode(),"无法找到lib库");}
+		return aiLibArr.stream().findFirst().get();
+	}
+
 	public int addAiLib(Integer arithmetic,String libraryName){
 		// 判断算法是否为
 		//if(arithmetic==null){ throw new ControllerException(ErrorCode.ERROR400.getCode(),"请输入算法类型"); }
@@ -287,6 +293,26 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 		aiLib.setLibraryName(libraryName);
 		return HfyDevAiMapper.createAiLibrary(aiLib);
 	}
+	public int editLib(int libraryId,AiLib aiLib){
+		List<AiLib> aiLibArr = HfyDevAiMapper.getAiLibraryByLibId(libraryId);
+		if(aiLibArr.isEmpty()){throw new ControllerException(ErrorCode.ERROR400.getCode(),"无法找到lib库");}
+		AiLib libData = aiLibArr.stream().findFirst().get();
+		if(aiLib.getLibraryName() == "" &&
+				aiLib.getTotal() == 0 &&
+				aiLib.getVersion() == ""){
+			throw new ControllerException(ErrorCode.ERROR400.getCode(),"没有修改项");
+		}
+		AiLib changeAiLibData = new AiLib();
+		changeAiLibData.setLibraryId(libraryId);
+		if(aiLib.getVersion() != ""){
+			changeAiLibData.setVersion(aiLib.getVersion());
+		}else{
+			changeAiLibData.setVersion(libData.getVersion());
+		}
+		if(aiLib.getTotal() != 0){changeAiLibData.setTotal(aiLib.getTotal());}
+		if(aiLib.getLibraryName() != ""){changeAiLibData.setLibraryName(aiLib.getLibraryName());}
+		return HfyDevAiMapper.updateAiLibrary(changeAiLibData);
+	}
 	/**
 	 * 添加数据库子项
 	 * @param libraryId
@@ -450,6 +476,12 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 		return new PageInfo<>(all);
 	}
 
+	public PageInfo<AiLib> searchAiLibItems(int page,int count,int libraryId,String key){
+		PageHelper.startPage(page, count);
+		List<AiLib> all = HfyDevAiMapper.searchAiLibItem(key,libraryId);
+		return new PageInfo<>(all);
+	}
+
 	public PageInfo<AiLib> searchAiLib(int page,int count,String key,Integer arithmetic){
 		PageHelper.startPage(page, count);
 		List<AiLib> all = HfyDevAiMapper.searchAiLib(key,arithmetic);

+ 48 - 0
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/aiLib/AiControl.java

@@ -0,0 +1,48 @@
+package com.genersoft.iot.vmp.vmanager.gb28181.aiLib;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+
+@Tag(name = "ai控制项")
+@CrossOrigin
+@RestController
+@RequestMapping("/aiLib")
+public class AiControl {
+    private final static Logger logger = LoggerFactory.getLogger(AiControl.class);
+
+    @Operation(summary = "获取lib图片数据")
+    @GetMapping("/libImg/{fileName}")
+    public void download(HttpServletResponse response,@PathVariable String fileName) throws Exception{
+        String basePath = "libImages";
+        logger.info("尝试读取文件,fileName:" + fileName);
+        File file = new File(basePath+ File.separator +fileName);
+        if (!file.exists() || !file.isFile()){
+            logger.info("文件不存在,fileName:" + fileName);
+            return;
+        }
+        InputStream inputStream = new FileInputStream(basePath+ File.separator +fileName);
+        response.reset();
+        response.setContentType("application/octet-stream");
+        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+        ServletOutputStream outputStream = response.getOutputStream();
+        byte[] b = new byte[1024];
+        int len;
+        try {
+            while((len = inputStream.read(b)) > 0) {
+                outputStream.write(b, 0, len);
+            }
+        } finally {
+            inputStream.close();
+        }
+    }
+}

+ 14 - 4
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceConfig.java

@@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 
+import com.genersoft.iot.vmp.vmanager.bean.AiLib;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -139,13 +140,22 @@ public class DeviceConfig {
 	}
 
 	@Operation(summary = "新增ai库")
-	@Parameter(name = "arithmetic" ,description = "算法",required = true)
-	@Parameter(name = "libraryName" ,description = "lib库名称",required = true)
+	@Parameter(name = "aiLib" ,description = "算法数据",required = true)
 	@PostMapping("/addLib")
-	public int addLib(@RequestBody Integer arithmetic,@RequestBody String libraryName){
-		return storager.addAiLib(arithmetic,libraryName);
+	public int addLib(@RequestBody AiLib aiLib){
+		return storager.addAiLib(aiLib.getArithmetic(),aiLib.getLibraryName());
 	}
 
+	@Operation(summary = "编辑ai库")
+	@Parameter(name = "libraryId", description = "libId" ,required = true)
+	@Parameter(name = "aiLib" ,description = "要修改的数据",required = true)
+	@PostMapping("/editLib/{libraryId}")
+	public int editLib(@PathVariable int libraryId,@RequestBody AiLib aiLib){
+		if (logger.isDebugEnabled()) {
+			logger.debug("ai库子项数据查询");
+		}
+		return storager.editLib(libraryId,aiLib);
+	}
 	/**
 	 * 设备配置查询请求API接口
 	 * @param deviceId 设备ID

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

@@ -148,21 +148,44 @@ public class DeviceQuery {
 	@GetMapping("/aiLibrary")
 	public List<AiLib> aiLibrary(){
 		if (logger.isDebugEnabled()) {
-			logger.debug("设备ai数据查询");
+			logger.debug("lib库列表查询");
 		}
 		return storager.queryLibraryList();
 	}
+
+	@Operation(summary = "ai库具体信息获取")
+	@Parameter(name = "libraryId", description = "lib库id", required = true)
+	@GetMapping("/libInfo/{libraryId}")
+	public AiLib getAiLibrary(@PathVariable int libraryId){
+		if (logger.isDebugEnabled()) {
+			logger.debug("获取lib库数据");
+		}
+		return storager.getLibraryInfo(libraryId);
+	}
+
+	@Operation(summary = "ai数据库子项搜索")
+	@Parameter(name = "page", description = "当前页", required = true)
+	@Parameter(name = "count", description = "每页查询数量", required = true)
+	@Parameter(name = "libraryId", description = "算法id", required = true)
+	@Parameter(name = "key", description = "搜索关键字", required = false)
+	@GetMapping("/libItems")
+	public PageInfo<AiLib> searchAiLibraryItems(int page,int count,int libraryId,String key){
+		if (logger.isDebugEnabled()) {
+			logger.debug("设备ai数据查询");
+		}
+		return storager.searchAiLibItems(page,count,libraryId,key);
+	}
+
 	@Operation(summary = "ai数据库搜索")
 	@Parameter(name = "page", description = "当前页", required = true)
 	@Parameter(name = "count", description = "每页查询数量", required = true)
 	@Parameter(name = "key", description = "搜索关键字", required = false)
-	@Parameter(name = "arithmetic", description = "搜索关键字", required = false)
+	@Parameter(name = "arithmetic", description = "算法", required = false)
 	@GetMapping("/libs")
 	public PageInfo<AiLib> searchAiLibrary(int page,int count,String key,Integer arithmetic){
 		if (logger.isDebugEnabled()) {
 			logger.debug("设备ai数据查询");
 		}
-
 		return storager.searchAiLib(page,count,key,arithmetic);
 	}
 

+ 4 - 0
web_src/config/index.js

@@ -18,6 +18,10 @@ module.exports = {
           '^/debug': '/'
         }
       },
+      '/aiLib':{
+        target: 'http://localhost:29001',
+        changeOrigin: true,
+      },
       '/static/snap': {
         target: 'http://localhost:29001',
         changeOrigin: true,

+ 249 - 0
web_src/src/components/editLib.vue

@@ -0,0 +1,249 @@
+<template>
+  <div id="aiConfig w-full" style="width:100%">
+    <div class="page-header">
+      <div class="page-title flex align-center">
+        <el-button icon="el-icon-top" size="mini" style="font-size: 20px; color: #000;" type="text" @click="toBack" ></el-button>
+        <el-divider direction="vertical"></el-divider>
+        <span v-if="!isEdit">        {{ libData.libraryName }}</span>
+        <el-input v-else-if="isEdit" v-model="libraryName">
+          <el-button slot="append" :loading="isLoading" @click="changeLibraryName">确认</el-button>
+        </el-input>
+      </div>
+      <div class="page-header-btn">
+        <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>
+    <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" >
+          <el-button slot="append"
+                     style="width: 80px;"
+                     icon="el-icon-search"
+                     type="primary"
+                     :loading="isLoading"
+                     @click="searchLibList">搜索</el-button>
+        </el-input>
+      </div>
+      <el-table :data="itemList" style="width: 100%;font-size: 12px;" header-row-class-name="table-header">
+        <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}的照片`"/>
+          </template>
+        </el-table-column>
+        <el-table-column prop="itemName"
+                         :label="(libData.arithmetic === aiTypes.face)?'人员名称':'名称'"
+                         min-width="160"></el-table-column>
+        <el-table-column prop="itemNo" label="号码" ></el-table-column>
+        <el-table-column v-if="libData.arithmetic === aiTypes.face" prop="idCard" label="身份证号" min-width="160"></el-table-column>
+        <el-table-column v-else-if="libData.arithmetic === aiTypes.face" prop="carNo" label="车牌号" min-width="160"></el-table-column>
+        <el-table-column label="操作" >
+          <template slot-scope="scope">
+            <el-button size="medium" @click="editLibItemHandle(scope.row)">编辑</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        style="float: right"
+        @size-change="handleSizeChange"
+        @current-change="currentChange"
+        :current-page="currentPage"
+        :page-size="count"
+        :page-sizes="[15, 25, 35, 50]"
+        layout="total, sizes, prev, pager, next"
+        :total="total"
+      ></el-pagination>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import aiMap from "@/map/ai";
+import handle from "@/until/handle";
+
+export default {
+  name: "editLib",
+  data(){
+    return {
+      aiTypes: aiMap.aiTypes,
+      isLoading: false,
+      isEdit: false,
+      libraryId: this.$route.params.libraryId,
+      libData: {},
+      libraryName: '',
+      itemList: {},
+      currentPage: 1,
+      count: 15,
+      total: 1,
+      lastPage: 1,
+      key: '',
+      searchKey: '',
+    }
+  },
+  async mounted(){
+    await this.loadLibInfo();
+    await this.searchLibList();
+  },
+  methods:{
+    async loadLibInfo(){
+      this.isLoading = true;
+      let [err,res] = await handle(this.$axios.get(`/api/device/query/libInfo/${this.libraryId}/`));
+      this.isLoading = false;
+      console.log(res);
+      if(err){
+        console.error(err);
+        return this.$message.error(err.message);
+      }
+      let result = res.data;
+      if(result.code === 0){
+        this.libData = result.data;
+      }
+    },
+    async loadLibItems(searchParam){
+      this.isLoading = true;
+      this.searchKey = searchParam.key;
+      this.searchArithmetic = searchParam.lib;
+      searchParam.libraryId = this.libraryId;
+      let [err,res] = await handle(this.$axios({
+        method: 'get',
+        url: `/api/device/query/libItems`,
+        params: searchParam
+      }))
+      this.isLoading = false;
+      if(err){
+        console.error(err);
+        this.$message.error(err.message);
+        return;
+      }
+      console.log('------------');
+      console.log(res)
+      let result = res.data;
+      if(res.data.code === 0){
+        this.total = result.data.total;
+        this.itemList = result.data.list;
+      }
+    },
+    searchLibList(){
+      // 按搜索按钮进行搜索.
+      let searchParam = {
+        page: 1,
+        count: this.count,
+        key: this.key
+      }
+      this.loadLibItems(searchParam);
+    },
+    toBack(){
+      this.$router.back();
+      this.beforeUrl = "/aiLib"
+    },
+    editMode(){
+      if(!this.isEdit){
+        this.libraryName = this.libData.libraryName;
+        this.isEdit = true;
+      }else {
+        this.isEdit = false;
+      }
+
+    },
+    async changeLibraryName(){
+      this.isLoading = true;
+      let data = {
+        libraryName: this.libraryName,
+      }
+      let [err,res] = await handle(this.$axios.post(`/api/device/query/editLib/${this.libraryId}`,data));
+      this.isLoading = false;
+      console.log(res);
+      if(err){
+        console.error(err);
+        return this.$message.error(err.message);
+      }
+      let result = res.data;
+      if(result.code === 0){
+        this.libData.libraryName = data.libraryName;
+      }
+    },
+    async submitData(){
+      let data = {};
+      data.arithmetic = this.aiTypeVal;
+      data.libraryName = this.libraryName;
+      this.isLoading = true;
+      let [err,res] = await handle(this.$axios.post(
+        '/api/device/config/addLib',data));
+      this.isLoading = false;
+      if(err){
+        console.error(err)
+        this.$message({
+          showClose: true,
+          message: err,
+          type: 'error'
+        });
+        return;
+      }
+      console.log(res);
+      this.$message.success("创建成功!!!");
+      this.init();
+    },
+    editLibItemHandle(row){
+      console.log('编辑员工');
+    },
+    changePage(){
+      // 使用当前配置进行搜索
+      let searchParam = {
+        page: this.currentPage,
+        count: this.count,
+        key: this.searchKey,
+      }
+      this.loadLibItems(searchParam);
+    },
+    currentChange: function (val) {
+      this.currentPage = val;
+      this.changePage();
+    },
+    handleSizeChange: function (val) {
+      this.count = val;
+      this.changePage();
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+.box-center{
+  width:100%;
+  height: auto;
+}
+.box-center{
+  width: 100%;
+  height: auto;
+  padding: 10px 5px;
+  box-sizing: border-box;
+}
+.box-center .line{
+  width: 100%;
+  height: 35px;
+  display: flex;
+  margin-bottom: 10px;
+}
+.box-center .line .label{
+  width: 20%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.box-center .line .input{
+  width: 80%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  padding-left: 8px;
+  border-left: 1px solid grey;
+}
+.personImg{
+  width: auto;
+  height: 120px;
+}
+</style>

+ 6 - 1
web_src/src/router/index.js

@@ -25,7 +25,7 @@ import wasmPlayer from '../components/common/jessibuca.vue'
 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
 import aiLib from "@/components/AiLib";
 import createLib from "@/components/CreateLib";
-
+import editLib from "@/components/editLib";
 const originalPush = VueRouter.prototype.push
 VueRouter.prototype.push = function push(location) {
   return originalPush.call(this, location).catch(err => err)
@@ -88,6 +88,11 @@ export default new VueRouter({
           name: 'createConfig',
           component: createConfig,
         },
+        {
+          path: '/libEdit/:libraryId',
+          name: 'libEdit',
+          component: editLib,
+        },
         {
           path: '/devEditAi/:aiId',
           name: 'devAiEdit',