From 1aa1ae5e2b7962a2fd298da5a5ce8c21334907ee Mon Sep 17 00:00:00 2001
From: Jerry Yan <792602257@qq.com>
Date: Thu, 23 Jan 2025 09:31:56 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/mobile/AppFaceController.java  | 16 +++
 .../basic/controller/pc/SourceController.java |  4 +
 .../basic/controller/viid/ViidController.java |  8 +-
 .../com/ycwl/basic/mapper/FaceMapper.java     |  2 +
 .../com/ycwl/basic/mapper/SourceMapper.java   |  2 +
 .../ycwl/basic/model/wvp/WvpSyncReqVo.java    |  1 +
 .../basic/repository/DeviceRepository.java    | 14 ++-
 .../basic/repository/SourceRepository.java    |  4 +
 .../service/impl/pc/DeviceServiceImpl.java    |  2 +-
 .../service/impl/pc/FaceServiceImpl.java      | 97 +++++++++++--------
 .../service/impl/pc/SourceServiceImpl.java    | 17 ++++
 .../ycwl/basic/service/pc/FaceService.java    |  5 +
 .../ycwl/basic/service/pc/SourceService.java  |  1 +
 .../task/impl/TaskFaceServiceImpl.java        |  4 +-
 .../task/DownloadNotificationTasker.java      |  3 +-
 .../com/ycwl/basic/task/VideoPieceGetter.java | 56 ++++++-----
 src/main/resources/mapper/FaceMapper.xml      |  6 ++
 src/main/resources/mapper/SourceMapper.xml    |  5 +
 18 files changed, 171 insertions(+), 76 deletions(-)

diff --git a/src/main/java/com/ycwl/basic/controller/mobile/AppFaceController.java b/src/main/java/com/ycwl/basic/controller/mobile/AppFaceController.java
index ac289c7..f0033bf 100644
--- a/src/main/java/com/ycwl/basic/controller/mobile/AppFaceController.java
+++ b/src/main/java/com/ycwl/basic/controller/mobile/AppFaceController.java
@@ -11,6 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * @Author:longbinbin
  * @Date:2024/12/4 17:03
@@ -39,8 +41,22 @@ AppFaceController {
         return faceService.faceUpload(file,scenicId);
     }
 
+    @GetMapping("/scenic/{scenicId}/list")
+    public ApiResponse<List<FaceRespVO>> list(@PathVariable("scenicId") String scenicId) {
+        JwtInfo worker = JwtTokenUtil.getWorker();
+        Long userId = worker.getUserId();
+        List<FaceRespVO> list = faceService.listByUser(userId, scenicId);
+        return ApiResponse.success(list);
+    }
+
     @GetMapping("/{faceId}")
     public ApiResponse<FaceRespVO> getById(@PathVariable("faceId") Long faceId) {
         return faceService.getById(faceId);
     }
+
+    @PostMapping("/{faceId}/match")
+    public ApiResponse match(@PathVariable("faceId") Long faceId) {
+        faceService.matchFaceId(faceId);
+        return ApiResponse.success("");
+    }
 }
diff --git a/src/main/java/com/ycwl/basic/controller/pc/SourceController.java b/src/main/java/com/ycwl/basic/controller/pc/SourceController.java
index fb77f92..5d2d2f2 100644
--- a/src/main/java/com/ycwl/basic/controller/pc/SourceController.java
+++ b/src/main/java/com/ycwl/basic/controller/pc/SourceController.java
@@ -39,6 +39,10 @@ public class SourceController {
         JwtInfo worker = JwtTokenUtil.getWorker();
         return sourceService.getById(id, worker.getUserId());
     }
+    @PostMapping("/{id}/cutVideo")
+    public ApiResponse cutVideo(@PathVariable("id") Long id) {
+        return sourceService.cutVideo(id);
+    }
     @ApiOperation("添加视频源")
     @PostMapping("/add")
     public ApiResponse add(@RequestBody SourceEntity source) {
diff --git a/src/main/java/com/ycwl/basic/controller/viid/ViidController.java b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java
index 4ab5b82..d332563 100644
--- a/src/main/java/com/ycwl/basic/controller/viid/ViidController.java
+++ b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java
@@ -78,21 +78,22 @@ public class ViidController {
         DeviceIdObject deviceIdObject = req.getRegisterObject();
         log.info("注册的设备信息:{}", deviceIdObject);
         // 保存设备注册时间
-        DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceIdObject.getDeviceId());
+        String deviceId = deviceIdObject.getDeviceId();
+        DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceId);
         if (device == null) {
             device = new DeviceEntity();
             device.setName("未配置设备");
-            device.setNo(deviceIdObject.getDeviceId());
+            device.setNo(deviceId);
             device.setOnline(1);
         }
         device.setKeepaliveAt(new Date());
         device.setIpAddr(IpUtils.getIpAddr(request));
         if (device.getId() != null) {
             deviceMapper.updateEntity(device);
-            deviceRepository.clearDeviceCache(device.getId());
         } else {
             device.setId(SnowFlakeUtil.getLongId());
             deviceMapper.addEntity(device);
+            deviceRepository.clearDeviceCache(deviceId);
         }
         return new VIIDBaseResp(
                 new ResponseStatusObject(serverId, "/VIID/System/Register", "0", "注册成功", sdfTime.format(new Date()))
@@ -126,6 +127,7 @@ public class ViidController {
             device.setIpAddr(IpUtils.getIpAddr(request));
             device.setId(SnowFlakeUtil.getLongId());
             deviceMapper.addEntity(device);
+            deviceRepository.clearDeviceCache(deviceId);
         } else {
             deviceRepository.updateOnlineStatus(device.getId(), IpUtils.getIpAddr(request), 1, new Date());
         }
diff --git a/src/main/java/com/ycwl/basic/mapper/FaceMapper.java b/src/main/java/com/ycwl/basic/mapper/FaceMapper.java
index 9423505..f61dbd3 100644
--- a/src/main/java/com/ycwl/basic/mapper/FaceMapper.java
+++ b/src/main/java/com/ycwl/basic/mapper/FaceMapper.java
@@ -29,4 +29,6 @@ public interface FaceMapper {
     int finishedJourney(Long faceId);
 
     FaceRespVO findLastFaceByUserId(String userId);
+
+    List<FaceRespVO> listByScenicAndUserId(String scenicId, Long userId);
 }
diff --git a/src/main/java/com/ycwl/basic/mapper/SourceMapper.java b/src/main/java/com/ycwl/basic/mapper/SourceMapper.java
index 62162be..029803a 100644
--- a/src/main/java/com/ycwl/basic/mapper/SourceMapper.java
+++ b/src/main/java/com/ycwl/basic/mapper/SourceMapper.java
@@ -65,4 +65,6 @@ public interface SourceMapper {
     List<SourceEntity> listVideoByFaceRelation(Long memberId, Long faceId);
 
     List<SourceEntity> listImageByFaceRelation(Long memberId, Long faceId);
+
+    SourceEntity getEntity(Long id);
 }
diff --git a/src/main/java/com/ycwl/basic/model/wvp/WvpSyncReqVo.java b/src/main/java/com/ycwl/basic/model/wvp/WvpSyncReqVo.java
index 8a1ef58..d69625c 100644
--- a/src/main/java/com/ycwl/basic/model/wvp/WvpSyncReqVo.java
+++ b/src/main/java/com/ycwl/basic/model/wvp/WvpSyncReqVo.java
@@ -11,6 +11,7 @@ public class WvpSyncReqVo {
     public static class DeviceItem {
         String deviceNo;
         String channelNo;
+        String ip;
         Integer online;
         Date keepaliveAt;
     }
diff --git a/src/main/java/com/ycwl/basic/repository/DeviceRepository.java b/src/main/java/com/ycwl/basic/repository/DeviceRepository.java
index c82312f..c4ced9a 100644
--- a/src/main/java/com/ycwl/basic/repository/DeviceRepository.java
+++ b/src/main/java/com/ycwl/basic/repository/DeviceRepository.java
@@ -44,7 +44,7 @@ public class DeviceRepository {
         if (null != device) {
             redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceNo), JSONObject.toJSONString(device));
         } else {
-            redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceNo), "null", 60 * 60L, TimeUnit.SECONDS);
+            redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceNo), "null", 60L, TimeUnit.SECONDS);
         }
         return device;
     }
@@ -64,6 +64,18 @@ public class DeviceRepository {
         return deviceConfig;
     }
 
+    public boolean clearDeviceCache(String deviceNo) {
+        if (deviceNo == null) {
+            return true;
+        }
+        if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceNo))) {
+            DeviceEntity device = getDeviceByDeviceNo(deviceNo);
+            redisTemplate.delete(String.format(DEVICE_CACHE_KEY, device.getNo()));
+            clearDeviceCache(device.getId());
+        }
+        redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceNo));
+        return true;
+    }
     public boolean clearDeviceCache(Long deviceId) {
         if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceId))) {
             DeviceEntity device = getDevice(deviceId);
diff --git a/src/main/java/com/ycwl/basic/repository/SourceRepository.java b/src/main/java/com/ycwl/basic/repository/SourceRepository.java
index 477aed3..480a2bc 100644
--- a/src/main/java/com/ycwl/basic/repository/SourceRepository.java
+++ b/src/main/java/com/ycwl/basic/repository/SourceRepository.java
@@ -52,4 +52,8 @@ public class SourceRepository {
                 return false;
         }
     }
+
+    public SourceEntity getSource(Long id) {
+        return sourceMapper.getEntity(id);
+    }
 }
diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java
index 8df2b4d..f54027a 100644
--- a/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java
+++ b/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java
@@ -105,7 +105,7 @@ public class DeviceServiceImpl implements DeviceService {
                 if (device != null) {
                     device.setOnline(deviceItem.getOnline());
                     device.setKeepaliveAt(deviceItem.getKeepaliveAt());
-                    deviceRepository.updateOnlineStatus(device.getId(), null, 1, deviceItem.getKeepaliveAt());
+                    deviceRepository.updateOnlineStatus(device.getId(), deviceItem.getIp(), 1, deviceItem.getKeepaliveAt());
                 }
             }
         }
diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java
index ef53937..0d404a7 100644
--- a/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java
+++ b/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java
@@ -4,7 +4,6 @@ import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.ycwl.basic.biz.OrderBiz;
 import com.ycwl.basic.enums.StatisticEnum;
-import com.ycwl.basic.exception.BaseException;
 import com.ycwl.basic.mapper.FaceSampleMapper;
 import com.ycwl.basic.mapper.SourceMapper;
 import com.ycwl.basic.mapper.StatisticsMapper;
@@ -30,7 +29,6 @@ import com.ycwl.basic.task.VideoPieceGetter;
 import com.ycwl.basic.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -129,16 +127,8 @@ public class FaceServiceImpl implements FaceService {
         String suffix = originalFilename.split("\\.", 2)[1];
         String fileName = UUID.randomUUID().toString() + "." + suffix;
         String faceUrl = adapter.uploadFile(file, filePath, fileName);
-        SearchFaceRespVo scenicDbSearchResult = faceService.searchFace(scenicId, faceUrl);
-        if (scenicDbSearchResult == null) {
-            adapter.deleteFile(filePath, fileName);
-            throw new BaseException("人脸照片校验失败,请重新上传");
-        }
-        // 2、通过人脸查找用户库
         Long newFaceId = SnowFlakeUtil.getLongId();
-        FaceEntity faceEntity = new FaceEntity();
-        faceEntity.setScore(scenicDbSearchResult.getScore());
-        faceEntity.setMatchResult(scenicDbSearchResult.getSearchResultJson());
+        Long oldFaceId = null;
         SearchFaceRespVo userDbSearchResult = faceService.searchFace(USER_FACE_DB_NAME+scenicId, faceUrl);
         float strictScore = 0.6F;
         if (userDbSearchResult == null) {
@@ -152,24 +142,63 @@ public class FaceServiceImpl implements FaceService {
             faceService.addFaceSample(USER_FACE_DB_NAME+scenicId, newFaceId.toString(), faceUrl, newFaceId.toString());
         } else {
             // 有匹配结果,且能匹配旧的数据
-            Optional<Long> faceAny = userDbSearchResult.getSampleListIds().stream().filter(oldFaceId -> {
-                FaceEntity face = faceRepository.getFace(oldFaceId);
+            Optional<Long> faceAny = userDbSearchResult.getSampleListIds().stream().filter(_faceId -> {
+                FaceEntity face = faceRepository.getFace(_faceId);
                 if (face == null) {
                     return false;
                 }
                 return face.getScenicId().equals(scenicId);
             }).findAny();
             if (faceAny.isPresent()) {
-                Long oldFaceId = faceAny.get();
+                oldFaceId = faceAny.get();
                 FaceRespVO oldFace = faceMapper.getById(oldFaceId);
                 if (oldFace == null) {
                     faceService.deleteFaceSample(USER_FACE_DB_NAME+scenicId, oldFaceId.toString());
                     faceService.addFaceSample(USER_FACE_DB_NAME+scenicId, newFaceId.toString(), faceUrl, newFaceId.toString());
+                    oldFaceId = null;
                 } else {
-                    faceEntity.setId(oldFaceId);
+                    newFaceId = oldFaceId;
                 }
             }
         }
+        if (oldFaceId==null) {
+            //新增人脸
+            FaceEntity faceEntity = new FaceEntity();
+            faceEntity.setCreateAt(new Date());
+            faceEntity.setScenicId(scenicId);
+            faceEntity.setMemberId(userId);
+            faceEntity.setFaceUrl(faceUrl);
+            faceEntity.setId(newFaceId);
+            faceMapper.add(faceEntity);
+        }
+        StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
+        statisticsRecordAddReq.setMemberId(userId);
+        statisticsRecordAddReq.setType(StatisticEnum.UPLOAD_FACE.code);
+        statisticsRecordAddReq.setScenicId(scenicId);
+        statisticsRecordAddReq.setMorphId(newFaceId);
+        statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
+        FaceRecognizeResp resp = new FaceRecognizeResp();
+        resp.setUrl(faceUrl);
+        resp.setFaceId(newFaceId);
+        matchFaceId(newFaceId);
+        return ApiResponse.success(resp);
+    }
+
+    @Override
+    public List<FaceRespVO> listByUser(Long userId, String scenicId) {
+        return faceMapper.listByScenicAndUserId(scenicId, userId);
+    }
+
+    @Override
+    public SearchFaceRespVo matchFaceId(Long faceId) {
+        FaceEntity face = faceRepository.getFace(faceId);
+        if (face == null) {
+            return null;
+        }
+        SearchFaceRespVo scenicDbSearchResult = faceService.searchFace(face.getScenicId(), face.getFaceUrl());
+        FaceEntity faceEntity = new FaceEntity();
+        faceEntity.setScore(scenicDbSearchResult.getScore());
+        faceEntity.setMatchResult(scenicDbSearchResult.getSearchResultJson());
         if (scenicDbSearchResult.getFirstMatchRate() != null) {
             faceEntity.setFirstMatchRate(BigDecimal.valueOf(scenicDbSearchResult.getFirstMatchRate()));
         }
@@ -177,38 +206,20 @@ public class FaceServiceImpl implements FaceService {
             faceEntity.setMatchSampleIds(scenicDbSearchResult.getSampleListIds().stream().map(String::valueOf).collect(Collectors.joining(",")));
         }
         faceEntity.setCreateAt(new Date());
-        faceEntity.setScenicId(scenicId);
-        faceEntity.setMemberId(userId);
-        faceEntity.setFaceUrl(faceUrl);
+        faceEntity.setScenicId(face.getScenicId());
+        faceEntity.setMemberId(face.getMemberId());
+        faceEntity.setFaceUrl(face.getFaceUrl());
         List<Long> sampleListIds = scenicDbSearchResult.getSampleListIds();
-        if (faceEntity.getId()==null) {
-            //新增人脸
-            faceEntity.setId(newFaceId);
-            faceMapper.add(faceEntity);
-        } else {
-            //2、更新人脸
-            faceMapper.update(faceEntity);
-            faceRepository.clearFaceCache(faceEntity.getId());
-        }
-        StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
-        statisticsRecordAddReq.setMemberId(userId);
-        statisticsRecordAddReq.setType(StatisticEnum.UPLOAD_FACE.code);
-        statisticsRecordAddReq.setScenicId(scenicId);
-        statisticsRecordAddReq.setMorphId(faceEntity.getId());
-        statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
-        FaceRecognizeResp resp = new FaceRecognizeResp();
-        resp.setUrl(faceUrl);
-        resp.setFaceId(faceEntity.getId());
         if (sampleListIds != null && !sampleListIds.isEmpty()) {// 匹配原片:照片
             List<SourceEntity> sourceEntities = sourceMapper.listBySampleIds(sampleListIds);
             List<MemberSourceEntity> memberSourceEntityList = sourceEntities.stream().map(sourceEntity -> {
                 MemberSourceEntity memberSourceEntity = new MemberSourceEntity();
-                memberSourceEntity.setScenicId(scenicId);
-                memberSourceEntity.setFaceId(faceEntity.getId());
-                memberSourceEntity.setMemberId(userId);
+                memberSourceEntity.setScenicId(face.getScenicId());
+                memberSourceEntity.setFaceId(face.getId());
+                memberSourceEntity.setMemberId(face.getMemberId());
                 memberSourceEntity.setSourceId(sourceEntity.getId());
                 memberSourceEntity.setType(sourceEntity.getType());
-                IsBuyRespVO isBuy = orderBiz.isBuy(userId, scenicId, sourceEntity.getType(), sourceEntity.getId());
+                IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), sourceEntity.getType(), sourceEntity.getId());
                 if (isBuy.isBuy()) { // 如果用户买过
                     memberSourceEntity.setIsBuy(1);
                 } else if (isBuy.isFree()) { // 全免费逻辑
@@ -224,11 +235,13 @@ public class FaceServiceImpl implements FaceService {
                 VideoPieceGetter.Task task = new VideoPieceGetter.Task();
                 task.faceId = faceEntity.getId();
                 task.faceSampleIds = sampleListIds;
-                task.memberId = userId;
+                task.memberId = face.getMemberId();
                 VideoPieceGetter.addTask(task);
             }
         }
-        return ApiResponse.success(resp);
+        faceMapper.update(faceEntity);
+        faceRepository.clearFaceCache(faceEntity.getId());
+        return scenicDbSearchResult;
     }
 
 }
diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/SourceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/SourceServiceImpl.java
index 9330956..4e72225 100644
--- a/src/main/java/com/ycwl/basic/service/impl/pc/SourceServiceImpl.java
+++ b/src/main/java/com/ycwl/basic/service/impl/pc/SourceServiceImpl.java
@@ -6,12 +6,15 @@ import com.ycwl.basic.mapper.SourceMapper;
 import com.ycwl.basic.model.pc.source.entity.SourceEntity;
 import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
 import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
+import com.ycwl.basic.repository.SourceRepository;
 import com.ycwl.basic.service.pc.SourceService;
+import com.ycwl.basic.task.VideoPieceGetter;
 import com.ycwl.basic.utils.ApiResponse;
 import com.ycwl.basic.utils.SnowFlakeUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -22,6 +25,8 @@ import java.util.List;
 public class SourceServiceImpl implements SourceService {
     @Autowired
     private SourceMapper sourceMapper;
+    @Autowired
+    private SourceRepository sourceRepository;
 
     @Override
     public ApiResponse<PageInfo<SourceRespVO>> pageQuery(SourceReqQuery sourceReqQuery) {
@@ -71,4 +76,16 @@ public class SourceServiceImpl implements SourceService {
             return ApiResponse.fail("修改失败");
         }
     }
+
+    @Override
+    public ApiResponse cutVideo(Long id) {
+        SourceEntity source = sourceRepository.getSource(id);
+        if (Integer.valueOf(2).equals(source.getType())) {
+            // 下载切片
+            VideoPieceGetter.Task task = new VideoPieceGetter.Task();
+            task.faceSampleIds = Collections.singletonList(source.getFaceSampleId());
+            VideoPieceGetter.addTask(task);
+        }
+        return ApiResponse.success("任务已下发");
+    }
 }
diff --git a/src/main/java/com/ycwl/basic/service/pc/FaceService.java b/src/main/java/com/ycwl/basic/service/pc/FaceService.java
index b6700a4..32056ba 100644
--- a/src/main/java/com/ycwl/basic/service/pc/FaceService.java
+++ b/src/main/java/com/ycwl/basic/service/pc/FaceService.java
@@ -4,6 +4,7 @@ import com.github.pagehelper.PageInfo;
 import com.ycwl.basic.model.pc.face.entity.FaceEntity;
 import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
 import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
+import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
 import com.ycwl.basic.utils.ApiResponse;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -22,4 +23,8 @@ public interface FaceService {
     ApiResponse<Integer> deleteByIds(List<Long> ids);
 
     ApiResponse faceUpload(MultipartFile file, Long scrnicId);
+
+    List<FaceRespVO> listByUser(Long userId, String scenicId);
+    SearchFaceRespVo matchFaceId(Long faceId);
+
 }
diff --git a/src/main/java/com/ycwl/basic/service/pc/SourceService.java b/src/main/java/com/ycwl/basic/service/pc/SourceService.java
index b91ddaf..eb1998d 100644
--- a/src/main/java/com/ycwl/basic/service/pc/SourceService.java
+++ b/src/main/java/com/ycwl/basic/service/pc/SourceService.java
@@ -20,4 +20,5 @@ public interface SourceService {
     ApiResponse<Integer> deleteById(Long id);
     ApiResponse<Integer> update(SourceEntity source);
 
+    ApiResponse cutVideo(Long id);
 }
diff --git a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java
index b876cd0..ec1ada4 100644
--- a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java
+++ b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java
@@ -265,9 +265,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
             sampleStoreDay = 3;
         }
         Date thatDay = DateUtil.offsetDay(new Date(), -sampleStoreDay);
-        Date dayStart = DateUtil.beginOfDay(thatDay);
         Date dayEnd = DateUtil.endOfDay(thatDay);
-        query.setStartTime(dayStart);
         query.setEndTime(dayEnd);
         IAcsClient client = getClient();
         faceSampleMapper.list(query).forEach(faceSampleEntity -> {
@@ -279,6 +277,8 @@ public class TaskFaceServiceImpl implements TaskFaceService {
                 client.getAcsResponse(request);
             } catch (ClientException e) {
                 return;
+            } finally {
+                faceSampleMapper.deleteById(faceSampleEntity.getId());
             }
         });
     }
diff --git a/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java b/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java
index b91d193..3cc5f25 100644
--- a/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java
+++ b/src/main/java/com/ycwl/basic/task/DownloadNotificationTasker.java
@@ -48,7 +48,6 @@ public class DownloadNotificationTasker {
                     }
                     MemberRespVO member = memberMapper.getById(item.getMemberId());
                     MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
-                    TemplateRespVO template = templateRepository.getTemplate(item.getTemplateId());
                     // 发送模板消息
                     String templateId = scenicRepository.getVideoDownloadTemplateId(item.getScenicId());
                     if (StringUtils.isBlank(templateId)) {
@@ -57,7 +56,7 @@ public class DownloadNotificationTasker {
                     }
                     log.info("发送模板消息");
                     ScenicEntity scenic = scenicRepository.getScenic(item.getScenicId());
-                    String title = "您在【" + template.getName() + "】的专属影像";
+                    String title = "您在【" + scenic.getName() + "】的专属影像";
                     String page = "pages/videoSynthesis/buy?scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId() + "&id=" + item.getVideoId();
                     /**
                      * 景区 {{thing1.DATA}}
diff --git a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java
index 12a7c59..ed41f67 100644
--- a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java
+++ b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java
@@ -118,7 +118,7 @@ public class VideoPieceGetter {
                         DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId());
 
                         SourceEntity source = sourceMapper.querySameVideo(faceSample.getId(), device.getId());
-                        IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, task.getFaceId());
+
                         if (source == null) {
                             BigDecimal cutPre = BigDecimal.valueOf(5L);
                             BigDecimal cutPost = BigDecimal.valueOf(4L);
@@ -177,12 +177,6 @@ public class VideoPieceGetter {
                             SourceEntity sourceEntity = new SourceEntity();
                             sourceEntity.setId(SnowFlakeUtil.getLongId());
                             sourceEntity.setCreateTime(faceSample.getCreateAt());
-                            MemberSourceEntity videoSource = new MemberSourceEntity();
-                            videoSource.setMemberId(task.getMemberId());
-                            videoSource.setType(1);
-                            videoSource.setFaceId(task.getFaceId());
-                            videoSource.setScenicId(faceSample.getScenicId());
-                            videoSource.setSourceId(sourceEntity.getId());
                             if (imgSource != null) {
                                 sourceEntity.setUrl(imgSource.getUrl());
                                 sourceEntity.setPosJson(imgSource.getPosJson());
@@ -192,26 +186,14 @@ public class VideoPieceGetter {
                             sourceEntity.setScenicId(faceSample.getScenicId());
                             sourceEntity.setDeviceId(faceSample.getDeviceId());
                             sourceEntity.setType(1);
-                            if (isBuy.isBuy()) { // 如果用户买过
-                                videoSource.setIsBuy(1);
-                            } else if (isBuy.isFree()) { // 全免费逻辑
-                                videoSource.setIsBuy(1);
-                            } else {
-                                videoSource.setIsBuy(0);
-                            }
-                            sourceMapper.add(sourceEntity);
-                            sourceMapper.addRelation(videoSource);
-                        } else {
-                            // 有原视频
-                            int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
-                            if (count <= 0) {
-                                // 没有关联
+                            if (task.memberId != null && task.faceId != null) {
                                 MemberSourceEntity videoSource = new MemberSourceEntity();
-                                videoSource.setId(SnowFlakeUtil.getLongId());
-                                videoSource.setScenicId(faceSample.getScenicId());
-                                videoSource.setFaceId(task.getFaceId());
                                 videoSource.setMemberId(task.getMemberId());
                                 videoSource.setType(1);
+                                videoSource.setFaceId(task.getFaceId());
+                                videoSource.setScenicId(faceSample.getScenicId());
+                                videoSource.setSourceId(sourceEntity.getId());
+                                IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, task.getFaceId());
                                 if (isBuy.isBuy()) { // 如果用户买过
                                     videoSource.setIsBuy(1);
                                 } else if (isBuy.isFree()) { // 全免费逻辑
@@ -219,9 +201,33 @@ public class VideoPieceGetter {
                                 } else {
                                     videoSource.setIsBuy(0);
                                 }
-                                videoSource.setSourceId(source.getId());
                                 sourceMapper.addRelation(videoSource);
                             }
+                            sourceMapper.add(sourceEntity);
+                        } else {
+                            // 有原视频
+                            if (task.memberId != null && task.faceId != null) {
+                                int count = sourceMapper.hasRelationTo(task.getMemberId(), source.getId(), 1);
+                                if (count <= 0) {
+                                // 没有关联
+                                    IsBuyRespVO isBuy = orderBiz.isBuy(task.getMemberId(), faceSample.getScenicId(), 1, task.getFaceId());
+                                    MemberSourceEntity videoSource = new MemberSourceEntity();
+                                    videoSource.setId(SnowFlakeUtil.getLongId());
+                                    videoSource.setScenicId(faceSample.getScenicId());
+                                    videoSource.setFaceId(task.getFaceId());
+                                    videoSource.setMemberId(task.getMemberId());
+                                    videoSource.setType(1);
+                                    if (isBuy.isBuy()) { // 如果用户买过
+                                        videoSource.setIsBuy(1);
+                                    } else if (isBuy.isFree()) { // 全免费逻辑
+                                        videoSource.setIsBuy(1);
+                                    } else {
+                                        videoSource.setIsBuy(0);
+                                    }
+                                    videoSource.setSourceId(source.getId());
+                                    sourceMapper.addRelation(videoSource);
+                                }
+                            }
                         }
                         if (templatePlaceholder != null) {
                             if (templatePlaceholder.contains(faceSample.getDeviceId().toString())) {
diff --git a/src/main/resources/mapper/FaceMapper.xml b/src/main/resources/mapper/FaceMapper.xml
index b9eab10..a86fe57 100644
--- a/src/main/resources/mapper/FaceMapper.xml
+++ b/src/main/resources/mapper/FaceMapper.xml
@@ -94,4 +94,10 @@
         from face
         where id = #{id}
     </select>
+    <select id="listByScenicAndUserId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO">
+        select id, face_url, create_at, update_at
+        from face
+        where member_id = #{userId} and scenic_id = #{scenicId}
+        order by update_at desc
+    </select>
 </mapper>
diff --git a/src/main/resources/mapper/SourceMapper.xml b/src/main/resources/mapper/SourceMapper.xml
index 380468f..da79e3d 100644
--- a/src/main/resources/mapper/SourceMapper.xml
+++ b/src/main/resources/mapper/SourceMapper.xml
@@ -176,4 +176,9 @@
             left join source s on ms.source_id = s.id
         where ms.face_id = #{faceId} and ms.member_id = #{memberId} and ms.type = 2
     </select>
+    <select id="getEntity" resultType="com.ycwl.basic.model.pc.source.entity.SourceEntity">
+        select *
+        from source
+        where id = #{id}
+    </select>
 </mapper>