From 3f3c239627f2cd99cdb28adf8bc99dfd3a0face3 Mon Sep 17 00:00:00 2001
From: Jerry Yan <792602257@qq.com>
Date: Thu, 5 Dec 2024 17:42:32 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BA=BA=E8=84=B8=E6=A3=80=E6=B5=8B=E9=80=BB?=
 =?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../ycwl/basic/mapper/pc/DeviceMapper.java    |   2 +
 .../model/pc/face/entity/FaceEntity.java      |   4 +
 .../faceSample/entity/FaceSampleEntity.java   |   9 ++
 .../pc/faceSample/req/FaceSampleReqQuery.java |   5 +
 .../pc/faceSample/resp/FaceSampleRespVO.java  |   5 +
 .../basic/model/task/resp/AddFaceRespVo.java  |   8 +
 .../model/task/resp/SearchFaceRespVo.java     |   8 +
 .../impl/task/TaskFaceServiceImpl.java        | 146 ++++++++++++++++++
 .../basic/service/task/TaskFaceService.java   |  13 ++
 src/main/resources/mapper/pc/DeviceMapper.xml |   5 +
 src/main/resources/mapper/pc/FaceMapper.xml   |   7 +-
 .../resources/mapper/pc/FaceSampleMapper.xml  |   7 +-
 12 files changed, 215 insertions(+), 4 deletions(-)
 create mode 100644 src/main/java/com/ycwl/basic/model/task/resp/AddFaceRespVo.java
 create mode 100644 src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java
 create mode 100644 src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java
 create mode 100644 src/main/java/com/ycwl/basic/service/task/TaskFaceService.java

diff --git a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java
index 569a22e..00e2aaa 100644
--- a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java
+++ b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java
@@ -21,4 +21,6 @@ public interface DeviceMapper {
     int deleteById(Long id);
     int update(DeviceAddOrUpdateReq deviceReqQuery);
     int updateStatus(Long id);
+
+    List<DeviceRespVO> listByScenicId(Long scenicId);
 }
diff --git a/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java b/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java
index f428caa..9db8b04 100644
--- a/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java
+++ b/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java
@@ -16,6 +16,10 @@ import java.util.Date;
 public class FaceEntity {
     @TableId
     private Long id;
+    /**
+     * 人脸得分
+     */
+    private float score;
     /**
      * 会员id
      */
diff --git a/src/main/java/com/ycwl/basic/model/pc/faceSample/entity/FaceSampleEntity.java b/src/main/java/com/ycwl/basic/model/pc/faceSample/entity/FaceSampleEntity.java
index 7f8dc23..25ac0b9 100644
--- a/src/main/java/com/ycwl/basic/model/pc/faceSample/entity/FaceSampleEntity.java
+++ b/src/main/java/com/ycwl/basic/model/pc/faceSample/entity/FaceSampleEntity.java
@@ -15,10 +15,19 @@ import java.util.Date;
 public class FaceSampleEntity {
     @TableId
     private Long id;
+    /**
+     * 景区ID
+     */
+    private Long scenicId;
     /**
      * 来源设备
      */
     private Long deviceId;
+    /**
+     * 样本ID
+     */
+    private Long sourceId;
+    private float score;
     /**
      * 人脸照片
      */
diff --git a/src/main/java/com/ycwl/basic/model/pc/faceSample/req/FaceSampleReqQuery.java b/src/main/java/com/ycwl/basic/model/pc/faceSample/req/FaceSampleReqQuery.java
index 6ab0884..0dd67c9 100644
--- a/src/main/java/com/ycwl/basic/model/pc/faceSample/req/FaceSampleReqQuery.java
+++ b/src/main/java/com/ycwl/basic/model/pc/faceSample/req/FaceSampleReqQuery.java
@@ -16,6 +16,11 @@ import java.util.Date;
 @Data
 @ApiModel("人脸样本查询参数")
 public class FaceSampleReqQuery extends BaseQueryParameterReq {
+    /**
+     * 景区ID
+     */
+    @ApiModelProperty("景区ID")
+    private Long scenicId;
     /**
      * 来源设备
      */
diff --git a/src/main/java/com/ycwl/basic/model/pc/faceSample/resp/FaceSampleRespVO.java b/src/main/java/com/ycwl/basic/model/pc/faceSample/resp/FaceSampleRespVO.java
index 69f48d8..b3d7ea1 100644
--- a/src/main/java/com/ycwl/basic/model/pc/faceSample/resp/FaceSampleRespVO.java
+++ b/src/main/java/com/ycwl/basic/model/pc/faceSample/resp/FaceSampleRespVO.java
@@ -16,6 +16,11 @@ import java.util.Date;
 @ApiModel("人脸样本响应参数")
 public class FaceSampleRespVO {
     private Long id;
+    /**
+     * 景区ID
+     */
+    @ApiModelProperty("景区ID")
+    private Long scenicId;
     /**
      * 来源设备
      */
diff --git a/src/main/java/com/ycwl/basic/model/task/resp/AddFaceRespVo.java b/src/main/java/com/ycwl/basic/model/task/resp/AddFaceRespVo.java
new file mode 100644
index 0000000..6afc14e
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/model/task/resp/AddFaceRespVo.java
@@ -0,0 +1,8 @@
+package com.ycwl.basic.model.task.resp;
+
+import lombok.Data;
+
+@Data
+public class AddFaceRespVo {
+    private float score;
+}
diff --git a/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java b/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java
new file mode 100644
index 0000000..e9302ed
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java
@@ -0,0 +1,8 @@
+package com.ycwl.basic.model.task.resp;
+
+import lombok.Data;
+
+@Data
+public class SearchFaceRespVo {
+    private float score;
+}
diff --git a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java
new file mode 100644
index 0000000..d665c4a
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java
@@ -0,0 +1,146 @@
+package com.ycwl.basic.service.impl.task;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.facebody.model.v20191230.AddFaceEntityRequest;
+import com.aliyuncs.facebody.model.v20191230.AddFaceRequest;
+import com.aliyuncs.facebody.model.v20191230.AddFaceResponse;
+import com.aliyuncs.facebody.model.v20191230.DeleteFaceEntityRequest;
+import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest;
+import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse;
+import com.ycwl.basic.mapper.pc.DeviceMapper;
+import com.ycwl.basic.mapper.pc.FaceMapper;
+import com.ycwl.basic.mapper.pc.FaceSampleMapper;
+import com.ycwl.basic.mapper.pc.ScenicMapper;
+import com.ycwl.basic.model.pc.face.entity.FaceEntity;
+import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
+import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
+import com.ycwl.basic.model.pc.faceSample.req.FaceSampleReqQuery;
+import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
+import com.ycwl.basic.model.task.resp.AddFaceRespVo;
+import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
+import com.ycwl.basic.service.task.TaskFaceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.profile.DefaultProfile;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class TaskFaceServiceImpl implements TaskFaceService {
+    @Autowired
+    private FaceMapper faceMapper;
+    @Autowired
+    private FaceSampleMapper faceSampleMapper;
+    @Autowired
+    private ScenicMapper scenicMapper;
+    private static final String DATE_FORMAT="yyyyMMddHHmmssSSS";
+    @Autowired
+    private DeviceMapper deviceMapper;
+
+    private IAcsClient getClient() {
+        DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai","LTAIDySvOV8yC7VZ","RgO5bwRnHrsyDak0IaLEF6iTRo7469");
+        IAcsClient client = new DefaultAcsClient(profile);
+        return client;
+    }
+    @Override
+    public SearchFaceRespVo searchFace(Long scenicId, Long faceId) {
+        FaceRespVO faceRespVO = faceMapper.getById(faceId);
+        IAcsClient client = getClient();
+        SearchFaceRequest request = new SearchFaceRequest();
+        request.setDbName(scenicId.toString());
+        request.setImageUrl(faceRespVO.getFaceUrl());
+        request.setLimit(100);
+        request.setQualityScoreThreshold(80F);
+        try {
+            SearchFaceResponse response = client.getAcsResponse(request);
+            List<SearchFaceResponse.Data.MatchListItem> matchList = response.getData().getMatchList();
+            if (matchList.isEmpty()) {
+                return null;
+            }
+            SearchFaceRespVo respVo = new SearchFaceRespVo();
+            FaceEntity faceEntity = new FaceEntity();
+            faceEntity.setId(faceId);
+            faceEntity.setMatchResult(JSON.toJSONString(matchList));
+            faceEntity.setScore(matchList.get(0).getQualitieScore());
+            List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> faceItems = matchList.get(0).getFaceItems().stream()
+                    .filter(faceItemsItem -> faceItemsItem.getConfidence() > 50).collect(Collectors.toList());
+            faceEntity.setMatchSampleIds(
+                    faceItems.stream()
+                            .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData)
+                            .collect(Collectors.joining(","))
+            );
+            faceMapper.update(faceEntity);
+            respVo.setScore(matchList.get(0).getQualitieScore());
+            return respVo;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public AddFaceRespVo addFaceSample(Long faceSampleId) {
+        FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId);
+        AddFaceEntityRequest request = new AddFaceEntityRequest();
+        request.setDbName(faceSampleRespVO.getScenicId().toString());
+        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+        String entityId = faceSampleRespVO.getDeviceId().toString() + "_" + sdf.format(faceSampleRespVO.getCreateAt());
+        request.setEntityId(entityId);
+        IAcsClient client = getClient();
+        try {
+            client.getAcsResponse(request);
+        } catch (ClientException e) {
+            return null;
+        }
+        AddFaceRequest addFaceRequest = new AddFaceRequest();
+        addFaceRequest.setDbName(faceSampleRespVO.getScenicId().toString());
+        addFaceRequest.setEntityId(entityId);
+        addFaceRequest.setImageUrl(faceSampleRespVO.getFaceUrl());
+        addFaceRequest.setExtraData(faceSampleId.toString());
+        AddFaceRespVo respVo = new AddFaceRespVo();
+        try {
+            AddFaceResponse acsResponse = client.getAcsResponse(addFaceRequest);
+            FaceSampleEntity faceSampleEntity = new FaceSampleEntity();
+            faceSampleEntity.setId(faceSampleId);
+            faceSampleEntity.setScore(acsResponse.getData().getQualitieScore());
+            faceSampleEntity.setUpdateAt(new Date());
+            faceSampleMapper.update(faceSampleEntity);
+            respVo.setScore(acsResponse.getData().getQualitieScore());
+        } catch (ClientException e) {
+            return null;
+        }
+        return respVo;
+    }
+
+    @Override
+    public void batchDeleteFace(Long scenicId) {
+        FaceSampleReqQuery query = new FaceSampleReqQuery();
+        query.setDeviceId(scenicId);
+        faceSampleMapper.list(query);
+        Date thatDay = DateUtil.offsetDay(new Date(), -3);
+        Date dayStart = DateUtil.beginOfDay(thatDay);
+        Date dayEnd = DateUtil.endOfDay(thatDay);
+        query.setStartTime(dayStart);
+        query.setEndTime(dayEnd);
+        IAcsClient client = getClient();
+        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+        faceSampleMapper.list(query).forEach(faceSampleEntity -> {
+            String entityId = faceSampleEntity.getDeviceId().toString() + "_" + sdf.format(faceSampleEntity.getCreateAt());
+            DeleteFaceEntityRequest request = new DeleteFaceEntityRequest();
+            request.setDbName(scenicId.toString());
+            request.setEntityId(entityId);
+            try {
+                client.getAcsResponse(request);
+            } catch (ClientException e) {
+                return;
+            }
+        });
+    }
+}
diff --git a/src/main/java/com/ycwl/basic/service/task/TaskFaceService.java b/src/main/java/com/ycwl/basic/service/task/TaskFaceService.java
new file mode 100644
index 0000000..76a2eaf
--- /dev/null
+++ b/src/main/java/com/ycwl/basic/service/task/TaskFaceService.java
@@ -0,0 +1,13 @@
+package com.ycwl.basic.service.task;
+
+import com.ycwl.basic.model.task.resp.AddFaceRespVo;
+import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
+
+public interface TaskFaceService {
+
+    SearchFaceRespVo searchFace(Long scenicId, Long faceId);
+
+    AddFaceRespVo addFaceSample(Long faceSampleId);
+
+    void batchDeleteFace(Long scenicId);
+}
diff --git a/src/main/resources/mapper/pc/DeviceMapper.xml b/src/main/resources/mapper/pc/DeviceMapper.xml
index f0ffd5d..9be8f4e 100644
--- a/src/main/resources/mapper/pc/DeviceMapper.xml
+++ b/src/main/resources/mapper/pc/DeviceMapper.xml
@@ -53,4 +53,9 @@
                  left join scenic s on d.scenic_id = s.id
         where d.id = #{id}
     </select>
+    <select id="listByScenicId" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO">
+        select d.id, d.name, no, d.status, create_at, d.update_at
+        from device d
+        where d.scenic_id = #{scenicId}
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/pc/FaceMapper.xml b/src/main/resources/mapper/pc/FaceMapper.xml
index 3e273d4..9fc6cb3 100644
--- a/src/main/resources/mapper/pc/FaceMapper.xml
+++ b/src/main/resources/mapper/pc/FaceMapper.xml
@@ -2,8 +2,8 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ycwl.basic.mapper.pc.FaceMapper">
     <insert id="add">
-        insert into face(id, member_id, face_url, match_sample_ids, first_match_rate, match_result)
-        values (#{id}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult})
+        insert into face(id, score, member_id, face_url, match_sample_ids, first_match_rate, match_result)
+        values (#{id}, #{score}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult})
     </insert>
     <update id="update">
         update face
@@ -11,6 +11,9 @@
             <if test="memberId!= null ">
                 member_id = #{memberId},
             </if>
+            <if test="score!= null ">
+                score = #{score},
+            </if>
             <if test="faceUrl!= null and faceUrl!= ''">
                 face_url = #{faceUrl},
             </if>
diff --git a/src/main/resources/mapper/pc/FaceSampleMapper.xml b/src/main/resources/mapper/pc/FaceSampleMapper.xml
index 3ad9cb7..7315c6a 100644
--- a/src/main/resources/mapper/pc/FaceSampleMapper.xml
+++ b/src/main/resources/mapper/pc/FaceSampleMapper.xml
@@ -42,9 +42,12 @@
         </if>
     </delete>
     <select id="list" resultType="com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO">
-        select id, device_id, face_url, match_sample_ids, first_match_rate, match_result,`status`
+        select id, scenic_id, device_id, face_url, match_sample_ids, first_match_rate, match_result,`status`
         from face_sample
         <where>
+            <if test="scenicId!= null and scenicId!= ''">
+                and device_id = #{deviceId}
+            </if>
             <if test="deviceId!= null and deviceId!= ''">
                 and device_id = #{deviceId}
             </if>
@@ -69,7 +72,7 @@
         </where>
     </select>
     <select id="getById" resultType="com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO">
-        select id, device_id, face_url, match_sample_ids, first_match_rate, match_result,`status`
+        select id, scenic_id, device_id, face_url, match_sample_ids, first_match_rate, match_result,`status`
         from face_sample
         where id = #{id}
     </select>