diff --git a/bonus-business/pom.xml b/bonus-business/pom.xml
index dad51f9..5cd9196 100644
--- a/bonus-business/pom.xml
+++ b/bonus-business/pom.xml
@@ -64,6 +64,27 @@
8.0.33
+
+
+ org.apache.commons
+ commons-imaging
+ 1.0-alpha2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
com.bonus
@@ -79,6 +100,11 @@
httpclient
4.5.13
+
+ org.apache.httpcomponents
+ httpmime
+ 4.5.13
+
com.fasterxml.jackson.core
jackson-core
@@ -134,7 +160,15 @@
false
${project.artifactId}
-
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 9
+ 9
+
+
${project.artifactId}
diff --git a/bonus-business/src/main/java/com/bonus/business/controller/robot/PersonFaceController.java b/bonus-business/src/main/java/com/bonus/business/controller/robot/PersonFaceController.java
new file mode 100644
index 0000000..10536f9
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/controller/robot/PersonFaceController.java
@@ -0,0 +1,139 @@
+package com.bonus.business.controller.robot;
+
+import com.bonus.business.service.IPersonFaceService;
+import com.bonus.business.service.IRobotService;
+import com.bonus.business.vo.*;
+import com.bonus.common.core.controller.BaseController;
+import com.bonus.common.core.domain.AjaxResult;
+import com.bonus.common.core.page.TableDataInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author fly
+ * 人脸下发开发
+ */
+@RestController
+@RequestMapping("/robot/person/")
+@Slf4j
+public class PersonFaceController extends BaseController {
+
+ @Resource
+ private IPersonFaceService service;
+
+
+ /**
+ * 新增智能库
+ * @param vo
+ * @return
+ */
+ @PostMapping("addIntelligentLibrary")
+ public AjaxResult addIntelligentLibrary(@RequestBody IntelligentLibraryVo vo) {
+ return service.addIntelligentLibrary(vo);
+ }
+
+ /**
+ * 查询智能库
+ * @param vo
+ * @return
+ */
+ @PostMapping("queryIntelligentLibrary")
+ public AjaxResult queryIntelligentLibrary(@RequestBody IntelligentLibraryVo vo) {
+ return service.queryIntelligentLibrary(vo);
+ }
+
+ /**
+ * 更新智能库
+ * @param vo
+ * @return
+ */
+ @PostMapping("updateIntelligentLibrary")
+ public AjaxResult updateIntelligentLibrary(@RequestBody IntelligentLibraryVo vo) {
+ return service.updateIntelligentLibrary(vo);
+ }
+
+ /**
+ * 删除智能库
+ * @param vo
+ * @return
+ */
+ @PostMapping("removeIntelligentLibrary")
+ public AjaxResult removeIntelligentLibrary(@RequestBody IntelligentLibraryVo vo) {
+ return service.removeIntelligentLibrary(vo);
+ }
+
+ /**
+ * 查询人员信息
+ * @param vo
+ * @return
+ */
+ @PostMapping("queryPerson")
+ public AjaxResult queryPerson(@RequestBody PersonVo vo) {
+ return service.queryPerson(vo);
+ }
+
+ /**
+ * 添加人员信息
+ * @param vo
+ * @return
+ */
+ @PostMapping("addPerson")
+ public AjaxResult addPerson(@RequestBody PersonVo vo) {
+ return service.addPerson(vo);
+ }
+
+ /**
+ * 删除人员信息
+ * @param vo
+ * @return
+ */
+ @PostMapping("removePerson")
+ public AjaxResult removePerson(@RequestBody PersonVo vo) {
+ return service.removePerson(vo);
+ }
+
+ /**
+ * 查询人员照片
+ * @param vo
+ * @return
+ */
+ @PostMapping("queryPersonImage")
+ public AjaxResult queryPersonImage(@RequestBody PersonImageVo vo) {
+ return service.queryPersonImage(vo);
+ }
+
+ /**
+ * 添加人员照片
+ * @param vo
+ * @return
+ */
+ @PostMapping("addPersonImage")
+ public AjaxResult addPersonImage(@RequestBody PersonImageVo vo) {
+ return service.addPersonImage(vo);
+ }
+
+ /**
+ * 删除人员照片
+ * @param vo
+ * @return
+ */
+ @PostMapping("removePersonImage")
+ public AjaxResult removePersonImage(@RequestBody PersonImageVo vo) {
+ return service.removePersonImage(vo);
+ }
+
+ /**
+ * 查看人员照片
+ * @param vo
+ * @return
+ */
+ @PostMapping("viewPersonImage")
+ public AjaxResult viewPersonImage(@RequestBody PersonImageVo vo) {
+ return service.viewPersonImage(vo);
+ }
+
+}
diff --git a/bonus-business/src/main/java/com/bonus/business/mapper/PersonFaceMapper.java b/bonus-business/src/main/java/com/bonus/business/mapper/PersonFaceMapper.java
new file mode 100644
index 0000000..4823a20
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/mapper/PersonFaceMapper.java
@@ -0,0 +1,22 @@
+package com.bonus.business.mapper;
+
+import com.bonus.business.vo.*;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author fly
+ */
+@Mapper
+public interface PersonFaceMapper {
+
+
+ /**
+ * 查询需要下发人员信息
+ * @param list
+ * @return
+ */
+ List selectPerson(List list);
+}
diff --git a/bonus-business/src/main/java/com/bonus/business/robot/util/DigestAuthClient.java b/bonus-business/src/main/java/com/bonus/business/robot/util/DigestAuthClient.java
new file mode 100644
index 0000000..351d121
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/robot/util/DigestAuthClient.java
@@ -0,0 +1,187 @@
+package com.bonus.business.robot.util;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.http.entity.ContentType;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.io.File;
+
+public class DigestAuthClient {
+
+ private final String username;
+ private final String password;
+ private final CloseableHttpClient httpClient;
+
+ public DigestAuthClient(String username, String password) {
+ this.username = username;
+ this.password = password;
+ this.httpClient = HttpClients.createDefault();
+ }
+
+ public String get(String url) throws Exception {
+ return sendRequest(new HttpGet(url), null);
+ }
+
+ public String post(String url, String jsonBody) throws Exception {
+ HttpPost post = new HttpPost(url);
+ if (jsonBody != null) {
+ StringEntity entity = new StringEntity(jsonBody, StandardCharsets.UTF_8);
+ post.setEntity(entity);
+ post.setHeader("Content-Type", "application/json");
+ }
+ return sendRequest(post, jsonBody);
+ }
+
+ private String sendRequest(HttpRequestBase request, String body) throws Exception {
+ CloseableHttpResponse response = httpClient.execute(request);
+ try {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode == 401) {
+ String wwwAuth = response.getFirstHeader("WWW-Authenticate").getValue();
+ if (wwwAuth.startsWith("Digest ")) {
+ String realm = extractValue(wwwAuth, "realm");
+ String nonce = extractValue(wwwAuth, "nonce");
+ String opaque = extractValue(wwwAuth, "opaque");
+ String qop = extractValue(wwwAuth, "qop");
+ String uri = new URI(request.getURI().toString()).getPath();
+ String method = request.getMethod();
+ // 客户端参数
+ String nc = "00000001";
+ String cnonce = generateCnonce();
+ // HA1 & HA2
+ String ha1 = md5(username + ":" + realm + ":" + password);
+ String ha2 = md5(method + ":" + uri);
+ String responseValue = md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
+ String authHeader = String.format(
+ "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\"," +
+ " qop=%s, nc=%s, cnonce=\"%s\", response=\"%s\", opaque=\"%s\"",
+ username, realm, nonce, uri, qop, nc, cnonce, responseValue, opaque);
+ request.setHeader("Authorization", authHeader);
+ // 再次发送请求
+ response = httpClient.execute(request);
+ }
+ }
+ HttpEntity entity = response.getEntity();
+ String responseBody = entity != null ? EntityUtils.toString(entity, StandardCharsets.UTF_8) : "";
+ System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
+ System.out.println("Response Body: " + responseBody);
+ return responseBody;
+ } finally {
+ response.close();
+ }
+ }
+
+
+ /**
+ * 发送带有文件和表单数据的 POST 请求。
+ *
+ * @param url 请求 URL
+ * @param formData 表单数据
+ * @param files 文件列表
+ * @return 响应内容
+ * @throws Exception 如果发生错误
+ */
+ public String postWithFiles(String url, Map formData, File[] files) throws IOException {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost(url);
+
+ MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+
+ // 添加表单字段
+ if (formData != null && !formData.isEmpty()) {
+ for (Map.Entry entry : formData.entrySet()) {
+ builder.addTextBody(entry.getKey(), entry.getValue());
+ }
+ }
+ // 添加文件
+ // 替换原来的 addBinaryBody 调用,使用如下方式:
+ if (files != null) {
+ for (File file : files) {
+ FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY, file.getName());
+ builder.addPart("image_data", fileBody);
+ }
+ }
+ // 构建请求实体
+ HttpEntity entity = builder.build();
+ httpPost.setEntity(entity);
+ // 发送请求并获取响应
+ try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+ return EntityUtils.toString(response.getEntity());
+ }
+ }
+
+ /**
+ * 发送带有 image/jpeg 文件和表单字段的 POST 请求。
+ */
+ public String postImageWithFormData(String url, Map formData, File[] images) throws Exception {
+ HttpPost httpPost = new HttpPost(url);
+
+ MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+
+ // 添加表单字段
+ if (formData != null && !formData.isEmpty()) {
+ for (Map.Entry entry : formData.entrySet()) {
+ builder.addTextBody(entry.getKey(), entry.getValue());
+ }
+ }
+
+ // 添加图片文件
+ if (images != null) {
+ for (File image : images) {
+ builder.addBinaryBody(
+ "image_data", // 表单字段名
+ image, // 文件对象
+ ContentType.create("image/jpeg"), // 内容类型
+ image.getName() // 文件名
+ );
+ }
+ }
+
+ // 构建请求实体并设置到 POST 请求中
+ HttpEntity entity = builder.build();
+ httpPost.setEntity(entity);
+ httpPost.setHeader("Content-Type", entity.getContentType().getValue());
+
+ // ✅ 使用 sendRequest 方法发送请求,复用认证、日志、错误处理等逻辑
+ return sendRequest(httpPost, null);
+ }
+
+ private String extractValue(String authHeader, String key) {
+ int start = authHeader.indexOf(key + "=\"") + key.length() + 2;
+ int end = authHeader.indexOf("\"", start);
+ return (start >= key.length() + 2 && end > start) ? authHeader.substring(start, end) : null;
+ }
+
+ private String generateCnonce() {
+ return IdUtils.simpleuuid().replaceAll("-", "").substring(0, 16);
+ }
+
+ private static String md5(String input) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ for (byte b : digest) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ public void close() throws IOException {
+ httpClient.close();
+ }
+}
\ No newline at end of file
diff --git a/bonus-business/src/main/java/com/bonus/business/robot/util/IntelligentLibraryUtil.java b/bonus-business/src/main/java/com/bonus/business/robot/util/IntelligentLibraryUtil.java
new file mode 100644
index 0000000..578c0b9
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/robot/util/IntelligentLibraryUtil.java
@@ -0,0 +1,233 @@
+package com.bonus.business.robot.util;
+
+import cn.hutool.json.JSONUtil;
+import com.bonus.business.vo.IntelligentLibraryVo;
+import com.bonus.business.vo.PersonImageVo;
+import com.bonus.business.vo.PersonVo;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class IntelligentLibraryUtil {
+ private static final String LOGIN_URL = "http://112.31.70.193:9633/api/v2/auth";
+ private static final String BASE_URL = "http://112.31.70.193:9633/api/v2/group";
+ private static final String DIGEST_USER = "admin";
+ private static final String DIGEST_PWD = "123456";
+
+ /**
+ * 手动补充数据
+ * Digest认证的Get请求
+ * @return 响应内容
+ */
+ public static String digestGetLogin(){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ // 发送 GET 请求
+ String result = client.get(LOGIN_URL);
+ System.out.println("最终响应内容:" + result);
+ client.close();
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ private static String md5(String input) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] messageDigest = md.digest(input.getBytes());
+ StringBuilder hexString = new StringBuilder();
+ for (byte b : messageDigest) {
+ String h = Integer.toHexString(0xFF & b);
+ while (h.length() < 2)
+ h = "0" + h;
+ hexString.append(h);
+ }
+ return hexString.toString();
+ }
+
+ // 智能库相关
+ public static String queryLibrary(IntelligentLibraryVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ return client.get(BASE_URL); // 使用DigestAuthClient发送GET请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String addLibrary(IntelligentLibraryVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/add", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String updateLibrary(IntelligentLibraryVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/set", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String removeLibrary(IntelligentLibraryVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/remove", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ // 人员相关
+ public static String queryPerson(PersonVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ String url = BASE_URL + "/label"; // 构造请求URL
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(url, jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String addPerson(PersonVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/label/add", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String updatePerson(PersonVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/label/set", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String removePerson(PersonVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/label/remove", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ // 图片相关
+ public static String queryPersonImage(PersonImageVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ String url = BASE_URL + "/label/slice/" + param.getSlice_index(); // 构造请求URL
+ return client.get(url); // 使用DigestAuthClient发送GET请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String addPersonImage(PersonImageVo param){
+ try {
+ // Convert image to required format and size
+ File[] imageData = convertImageUrlToFile(param.getImagePath(), 1080, 800);
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ // 定义需要添加的表单数据
+ Map formData = new HashMap<>();
+ formData.put("label_index", String.valueOf(param.getLabel_index()));
+ formData.put("groupname", param.getGroupname());
+ return client.postImageWithFormData(BASE_URL + "/label/slice/add",formData,imageData);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage();
+ }
+ }
+
+ public static File[] convertImageUrlToFile(String imageUrl, int width, int height) throws IOException {
+ // 从给定的 URL 获取图像数据
+ try (InputStream inputStream = new URL(imageUrl).openStream()) {
+ byte[] originalImageData = inputStream.readAllBytes();
+ // 转换图像数据
+ BufferedImage originalImage = javax.imageio.ImageIO.read(new ByteArrayInputStream(originalImageData));
+ BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2d = resizedImage.createGraphics();
+ g2d.drawImage(originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
+ g2d.dispose();
+ // 创建临时文件并将调整大小后的图像写入其中
+ File tempFile = File.createTempFile("resized-", ".jpg");
+ tempFile.deleteOnExit(); // 程序退出时删除临时文件
+ try (FileOutputStream fos = new FileOutputStream(tempFile)) {
+ ImageIO.write(resizedImage, "jpg", fos);
+ }
+ return new File[]{tempFile};
+ }
+ }
+
+ public static String removePersonImage(PersonImageVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(param);
+ // 将参数转换为JSON字符串
+ return client.post(BASE_URL + "/label/slice/remove", jsonBody); // 使用DigestAuthClient发送POST请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+
+ public static String viewPersonImage(PersonImageVo param){
+ try {
+ DigestAuthClient client = new DigestAuthClient(DIGEST_USER, md5(DIGEST_PWD));
+ String url = BASE_URL + "/label/slice/view/" + param.getSlice_index(); // 构造请求URL
+ return client.get(url); // 使用DigestAuthClient发送GET请求
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "Error: " + e.getMessage(); // 捕获异常并返回错误信息
+ }
+ }
+}
diff --git a/bonus-business/src/main/java/com/bonus/business/service/IPersonFaceService.java b/bonus-business/src/main/java/com/bonus/business/service/IPersonFaceService.java
new file mode 100644
index 0000000..fa637f6
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/service/IPersonFaceService.java
@@ -0,0 +1,89 @@
+package com.bonus.business.service;
+
+import com.bonus.business.vo.*;
+import com.bonus.common.core.domain.AjaxResult;
+
+import java.util.List;
+
+/**
+ * 人脸业务处理接口层
+ */
+public interface IPersonFaceService {
+
+ /**
+ * 查询人员信息
+ * @param vo
+ * @return
+ */
+ AjaxResult queryPerson(PersonVo vo);
+
+ /**
+ * 添加人员信息
+ * @param vo
+ * @return
+ */
+ AjaxResult addPerson(PersonVo vo);
+
+ /**
+ * 删除人员信息
+ * @param vo
+ * @return
+ */
+ AjaxResult removePerson(PersonVo vo);
+
+ /**
+ * 查询人员照片
+ * @param vo
+ * @return
+ */
+ AjaxResult queryPersonImage(PersonImageVo vo);
+
+ /**
+ * 添加人员照片
+ * @param vo
+ * @return
+ */
+ AjaxResult addPersonImage(PersonImageVo vo);
+
+ /**
+ * 删除人员照片
+ * @param vo
+ * @return
+ */
+ AjaxResult removePersonImage(PersonImageVo vo);
+
+ /**
+ * 查看人员照片
+ * @param vo
+ * @return
+ */
+ AjaxResult viewPersonImage(PersonImageVo vo);
+
+ /**
+ * 添加智能库
+ * @param vo
+ * @return
+ */
+ AjaxResult addIntelligentLibrary(IntelligentLibraryVo vo);
+
+ /**
+ * 查询智能库
+ * @param vo
+ * @return
+ */
+ AjaxResult queryIntelligentLibrary(IntelligentLibraryVo vo);
+
+ /**
+ * 更新智能库
+ * @param vo
+ * @return
+ */
+ AjaxResult updateIntelligentLibrary(IntelligentLibraryVo vo);
+
+ /**
+ * 删除智能库
+ * @param vo
+ * @return
+ */
+ AjaxResult removeIntelligentLibrary(IntelligentLibraryVo vo);
+}
\ No newline at end of file
diff --git a/bonus-business/src/main/java/com/bonus/business/service/impl/PersonFaceServiceImpl.java b/bonus-business/src/main/java/com/bonus/business/service/impl/PersonFaceServiceImpl.java
new file mode 100644
index 0000000..a05522f
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/service/impl/PersonFaceServiceImpl.java
@@ -0,0 +1,223 @@
+package com.bonus.business.service.impl;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson2.JSONArray;
+import com.bonus.business.mapper.PersonFaceMapper;
+import com.bonus.business.mapper.RobotMapper;
+import com.bonus.business.robot.util.IntelligentLibraryUtil;
+import com.bonus.business.robot.util.QxUtils;
+import com.bonus.business.robot.util.XmlUtils;
+import com.bonus.business.robot.util.XxmSendUtils;
+import com.bonus.business.robot.video.QxVideotape;
+import com.bonus.business.robot.video.TVideoConfigUtil;
+import com.bonus.business.service.IPersonFaceService;
+import com.bonus.business.service.IRobotService;
+import com.bonus.business.vo.*;
+import com.bonus.common.core.domain.AjaxResult;
+import com.bonus.common.utils.DateUtils;
+import com.bonus.common.utils.StringUtils;
+import com.bonus.common.utils.uuid.UUID;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author fly
+ */
+@Service
+@Slf4j
+public class PersonFaceServiceImpl implements IPersonFaceService {
+
+ @Resource
+ public PersonFaceMapper mapper;
+
+ @Override
+ /**
+ * 添加智能库
+ * @param vo 智能库信息对象
+ * @return 返回操作结果
+ */
+ public AjaxResult addIntelligentLibrary(IntelligentLibraryVo vo) {
+ String result = IntelligentLibraryUtil.addLibrary(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 查询智能库
+ * @param vo 智能库查询条件对象
+ * @return 返回查询结果
+ */
+ public AjaxResult queryIntelligentLibrary(IntelligentLibraryVo vo) {
+ String result = IntelligentLibraryUtil.queryLibrary(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 更新智能库
+ * @param vo 智能库更新信息对象
+ * @return 返回操作结果
+ */
+ public AjaxResult updateIntelligentLibrary(IntelligentLibraryVo vo) {
+ String result = IntelligentLibraryUtil.updateLibrary(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 删除智能库
+ * @param vo 智能库删除条件对象
+ * @return 返回操作结果
+ */
+ public AjaxResult removeIntelligentLibrary(IntelligentLibraryVo vo) {
+ String result = IntelligentLibraryUtil.removeLibrary(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 查询人员信息
+ * @param vo 人员查询条件对象
+ * groupname:库名称
+ * name:人员名称
+ * idCard:身份证号
+ * @return 返回查询结果
+ */
+ public AjaxResult queryPerson(PersonVo vo) {
+ String result = null;
+ result = IntelligentLibraryUtil.queryPerson(vo);
+ return AjaxResult.success(result);
+ }
+
+ /**
+ * 添加人员信息(修改)
+ * @param vo 人员信息对象
+ * @return 返回操作结果
+ */
+ @Override
+ public AjaxResult addPerson(PersonVo vo) {
+ try {
+ if(vo.getIds() == null && vo.getIds().isEmpty()){
+ List list = mapper.selectPerson(vo.getIds());
+ // List list = new ArrayList<>();
+// list.add(vo);
+ if (list.isEmpty()) {
+ return AjaxResult.error("未查询到人员信息");
+ }
+ int m = 0;
+ int n = 0;
+ StringBuilder sb = new StringBuilder();
+ for (PersonVo personVo : list) {
+ personVo.setGroupname("robotV1");
+ String result = IntelligentLibraryUtil.addPerson(personVo);
+ JSONObject entries = JSONUtil.parseObj(result);
+ if(entries.getInt("code") == 0){
+ personVo.setIndex(entries.getInt("label_index"));
+ }else if(entries.getInt("code") == 7){
+ //人员重复,调用修改
+ personVo.setIndex(entries.getInt("label_index"));
+ String result2 = IntelligentLibraryUtil.updatePerson(vo);
+ JSONObject entries2 = JSONUtil.parseObj(result2);
+ if(entries2.getInt("code") == 0){
+
+ }else{
+ sb.append(personVo.getName()).append(":").append(entries.getStr("message")).append("\n");
+ }
+ } else{
+
+ sb.append(personVo.getName()).append(":").append(entries.getStr("message")).append("\n");
+ }
+ //调用添加照片
+ if(personVo.getIndex()>0){
+ PersonImageVo personImageVo = new PersonImageVo();
+ personImageVo.setGroupname("robotV1");
+ personImageVo.setLabel_index(personVo.getIndex());
+ personImageVo.setImagePath(personVo.getImage());
+ String result3 = IntelligentLibraryUtil.addPersonImage(personImageVo);
+ JSONObject entries3 = JSONUtil.parseObj(result3);
+ if(entries3.getInt("code") == 0){
+ m++;
+ }else{
+ sb.append(personVo.getName()).append(":").append(entries.getStr("message")).append("\n");
+ }
+ }else{
+ n++;
+ sb.append(personVo.getName()).append(":").append("人员信息添加失败").append("\n");
+ }
+ }
+ String result = "成功下发人员" + m + "条,失败" + n + "条数据;失败原因:"+ sb;
+ return AjaxResult.success(result);
+ }else{
+ return AjaxResult.error("请选择下发人员信息");
+ }
+ } catch (Exception e) {
+ log.error(e.toString(),e);
+ return AjaxResult.error("过程异常:"+e.getMessage());
+ }
+
+ }
+
+ @Override
+ /**
+ * 删除人员信息
+ * @param vo 人员删除条件对象
+ * @return 返回操作结果
+ */
+ public AjaxResult removePerson(PersonVo vo) {
+ String result = IntelligentLibraryUtil.removePerson(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 查询人员照片
+ * @param vo 人员照片查询条件对象
+ * @return 返回查询结果
+ */
+ public AjaxResult queryPersonImage(PersonImageVo vo) {
+ String result = IntelligentLibraryUtil.queryPersonImage(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 添加人员照片
+ * @param vo 人员照片信息对象
+ * @return 返回操作结果
+ */
+ public AjaxResult addPersonImage(PersonImageVo vo) {
+ String result = IntelligentLibraryUtil.addPersonImage(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 删除人员照片
+ * @param vo 人员照片删除条件对象
+ * @return 返回操作结果
+ */
+ public AjaxResult removePersonImage(PersonImageVo vo) {
+ String result = IntelligentLibraryUtil.removePersonImage(vo);
+ return AjaxResult.success(result);
+ }
+
+ @Override
+ /**
+ * 查看人员照片
+ * @param vo 人员照片查看条件对象
+ * @return 返回查看结果
+ */
+ public AjaxResult viewPersonImage(PersonImageVo vo) {
+ String result = IntelligentLibraryUtil.viewPersonImage(vo);
+ return AjaxResult.success(result);
+ }
+
+}
\ No newline at end of file
diff --git a/bonus-business/src/main/java/com/bonus/business/vo/IntelligentLibraryVo.java b/bonus-business/src/main/java/com/bonus/business/vo/IntelligentLibraryVo.java
new file mode 100644
index 0000000..b6102ed
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/vo/IntelligentLibraryVo.java
@@ -0,0 +1,21 @@
+package com.bonus.business.vo;
+
+import lombok.Data;
+
+/**
+ * 智能库参数
+ */
+@Data
+public class IntelligentLibraryVo {
+
+ /** 智能库索引,必填 */
+ private int index;
+ /** 智能库名称,必填,长度1-128个字节 */
+ private String name;
+ /** 智能库类型,必填,face人脸库 vehicle车辆库 */
+ private String type;
+ /** 库中数据脱敏(0)或明文(1),默认0,选填 */
+ private String security_level;
+
+}
+
diff --git a/bonus-business/src/main/java/com/bonus/business/vo/PersonImageVo.java b/bonus-business/src/main/java/com/bonus/business/vo/PersonImageVo.java
new file mode 100644
index 0000000..7d6872c
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/vo/PersonImageVo.java
@@ -0,0 +1,24 @@
+package com.bonus.business.vo;
+
+import lombok.Data;
+
+
+/**
+ * 人员图片参数
+ */
+@Data
+public class PersonImageVo {
+ /** 人员索引,必填 */
+ private int label_index;
+ /** 智能库名字,必填 */
+ private String groupname;
+ /** 图片路径,必填(本地文件路径) */
+ private String imagePath;
+ /** 人员详情的数量,选填 */
+ private Integer rows;
+ /** 图片ID,必填 */
+ private int image_id;
+ /** 图片分片索引,必填 */
+ private int slice_index;
+
+}
diff --git a/bonus-business/src/main/java/com/bonus/business/vo/PersonVo.java b/bonus-business/src/main/java/com/bonus/business/vo/PersonVo.java
new file mode 100644
index 0000000..78f63c2
--- /dev/null
+++ b/bonus-business/src/main/java/com/bonus/business/vo/PersonVo.java
@@ -0,0 +1,69 @@
+package com.bonus.business.vo;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+
+/**
+ * 人员参数
+ */
+@Data
+public class PersonVo {
+
+ private List ids;
+
+ /**
+ * 人员索引或者车牌索引,必填
+ */
+ private Integer index;
+ /**
+ * 智能库类型,必填,face:人脸库、vehicle:车牌库
+ */
+ private String type;
+ /**
+ * 人员名字,必填,长度1-64个字节
+ */
+ private String name;
+ /**
+ * 智能库名字,必填,长度1-64个字节
+ */
+ private String groupname;
+ /**
+ * 人员性别,必填,1:男;0:女
+ */
+ private Integer gender;
+ /**
+ * 人员出生日期,格式"2020-06-03"
+ */
+ private String birthday;
+ /**
+ * 籍贯,默认空
+ */
+ @JsonProperty("native")
+ private String nativePlace;
+ /**
+ * 手机号,默认空
+ */
+ private String phones;
+ /**
+ * 人员身份证信息,必填,长度1-255个字节
+ */
+ @JsonProperty("id_card")
+ private String idCard;
+ /**
+ * 人员类型索引
+ */
+ @JsonProperty("types_index")
+ private String typesIndex;
+ /**
+ * 卡号,选填,默认为空
+ */
+ private String cardid;
+
+ private String image;
+}
+
+
diff --git a/bonus-business/src/main/resources/mapper/robot/PersonFaceMapper.xml b/bonus-business/src/main/resources/mapper/robot/PersonFaceMapper.xml
new file mode 100644
index 0000000..2304e0e
--- /dev/null
+++ b/bonus-business/src/main/resources/mapper/robot/PersonFaceMapper.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
\ No newline at end of file