Преглед изворни кода

file-service 添加一个 CameraPhoto 类, 表示相册中的照片

reghao пре 1 месец
родитељ
комит
e2e1e911e8

+ 2 - 0
common/src/main/java/cn/reghao/tnb/common/util/ConstantId.java

@@ -9,6 +9,8 @@ package cn.reghao.tnb.common.util;
 public class ConstantId {
     public static final long START_USER_ID = 10001L;
     public static final long ANONYMOUS_USER_ID = -1L;
+    public static final int PAGE_SIZE = 12;
+    public static final int MAX_PAGES = 100;
     public static final String AVATAR_URL = "//picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
     public static final String CAPTCHA_CODE = "tnb23";
     public static final String VERIFY_CODE = "220233";

+ 13 - 24
common/src/main/java/cn/reghao/tnb/common/util/StringUtil.java

@@ -42,35 +42,24 @@ public class StringUtil {
     }
 
     public static String getTimeStr(int duration) {
-        int hour = duration/3600;
-        int minute = 0;
-        int second = 0;
+        int hour = duration / 3600;
+        int minute = (duration % 3600) / 60;
+        int second = duration % 60;
+
         if (hour > 0) {
-            int i = duration%3600;
-            minute = i/60;
-            if (minute > 0) {
-                second = i%60;
-            } else {
-                second = i;
-            }
+            // 小时大于 0,返回 hh:mm:ss
+            return String.format("%s:%s:%s", getStr(hour), getStr(minute), getStr(second));
         } else {
-            minute = duration/60;
-            if (minute > 0) {
-                second = duration%60;
-            } else {
-                second = duration;
-            }
+            // 小时为 0,只返回 mm:ss
+            return String.format("%s:%s", getStr(minute), getStr(second));
         }
-
-        return String.format("%s:%s:%s", getStr(hour), getStr(minute), getStr(second));
     }
 
-    private static String getStr(int value) {
-        if (value < 10) {
-            return String.format("0%s", value);
-        } else {
-            return ""+value;
-        }
+    /**
+     * 辅助方法:确保数值为两位字符串,如 5 变为 "05"
+     */
+    private static String getStr(int num) {
+        return String.format("%02d", num);
     }
 
     public static String getObjectName(String objectUrl) {

+ 3 - 1
file/file-service/src/main/java/cn/reghao/tnb/file/app/util/PhotoExif.java

@@ -9,6 +9,7 @@ import com.drew.metadata.Metadata;
 import com.drew.metadata.Tag;
 import com.drew.metadata.exif.ExifIFD0Directory;
 import com.drew.metadata.exif.GpsDirectory;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.ImageWriteException;
 import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
@@ -24,6 +25,7 @@ import java.util.Collection;
  * @author reghao
  * @date 2023-09-06 14:25:18
  */
+@Slf4j
 public class PhotoExif {
     public static void getExifInfo(File file) throws ImageProcessingException, IOException {
         Metadata metadata = ImageMetadataReader.readMetadata(file);
@@ -117,7 +119,7 @@ public class PhotoExif {
                 }
             }
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("{}", e.getMessage());
         }
 
         return camPhoto;

+ 16 - 0
file/file-service/src/main/java/cn/reghao/tnb/file/app/zdisk/db/mapper/CameraPhotoMapper.java

@@ -0,0 +1,16 @@
+package cn.reghao.tnb.file.app.zdisk.db.mapper;
+
+import cn.reghao.jutil.jdk.web.db.BaseMapper;
+import cn.reghao.tnb.file.app.zdisk.model.po.CameraPhoto;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2024-09-07 12:01:54
+ */
+@Mapper
+public interface CameraPhotoMapper extends BaseMapper<CameraPhoto> {
+    List<CameraPhoto> findByFileIds(List<String> list);
+}

+ 54 - 0
file/file-service/src/main/java/cn/reghao/tnb/file/app/zdisk/model/po/CameraPhoto.java

@@ -0,0 +1,54 @@
+package cn.reghao.tnb.file.app.zdisk.model.po;
+
+import cn.reghao.jutil.jdk.web.db.BaseObject;
+import cn.reghao.tnb.content.api.dto.CamPhoto;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2024-09-07 12:01:03
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class CameraPhoto extends BaseObject<Integer> {
+    private String fileId;
+    private String manufacturer;
+    private String model;
+    private String software;
+    private LocalDateTime shotAt;
+    private BigDecimal longitude;
+    private BigDecimal latitude;
+    private Boolean geoValid;
+    private Integer areaCode;
+    private Double duration;
+
+    public CameraPhoto(String fileId, CamPhoto camPhoto) {
+        this.fileId = fileId;
+        this.manufacturer = camPhoto.getManufacturer();
+        this.model = camPhoto.getModel();
+        this.software = camPhoto.getSoftware();
+        Double lng = camPhoto.getLongitude();
+        if (lng != null && lng != 0.0) {
+            this.longitude = BigDecimal.valueOf(camPhoto.getLongitude());
+            this.geoValid = true;
+        } else {
+            this.geoValid = false;
+        }
+
+        Double lat = camPhoto.getLatitude();
+        if (lat != null && lat != 0.0) {
+            this.latitude = BigDecimal.valueOf(camPhoto.getLatitude());
+            this.geoValid = true;
+        } else {
+            this.geoValid = false;
+        }
+        this.areaCode = 0;
+        this.duration = 0.0D;
+    }
+}

+ 15 - 3
file/file-service/src/main/java/cn/reghao/tnb/file/app/zdisk/model/vo/PhotoItem.java

@@ -2,6 +2,7 @@ package cn.reghao.tnb.file.app.zdisk.model.vo;
 
 import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import cn.reghao.oss.api.constant.ObjectType;
+import cn.reghao.tnb.file.app.zdisk.model.po.CameraPhoto;
 import cn.reghao.tnb.file.app.zdisk.model.po.DiskFile;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -26,11 +27,22 @@ public class PhotoItem {
         this.fileId = diskFile.getFileId();
         this.filename = diskFile.getFilename();
         this.type = ObjectType.getDescByCode(diskFile.getFileType()).toLowerCase();
-        this.type = ObjectType.Video.name().toLowerCase();
-        this.url = "//picx.zhimg.com/v2-8ca5db58f0436482878e429b58c5f171_r.jpg";
-        this.videoUrl = "//vdn6.vzuu.com/HD/ebc58e72-af2c-11e8-a08a-0242ac112a08.mp4?pkey=AAV8mYhgmIFeBMVEaD-fMj0hDSteKP-FlUXZhYeP5tcC1fRTVE0WdgQOtTNCCnNmA-zX2b5YVMwudoCKu9QuG3MN&bu=1513c7c2&c=avc.0.0&expiration=1778489737&f=mp4&pu=da4bec50&v=ks6&pp=ChMxNDAxNjIzODY1NzM5NTc5MzkyGGMiC2ZlZWRfY2hvaWNlMhMxMzY5MDA1NjA4NTk5OTA0MjU3PXu830Q%3D&pf=Web&pt=zhihu";
+        this.url = "";
+        this.videoUrl = "";
         this.duration = "";
         this.size = sizeStr;
         this.updateTime = DateTimeConverter.format(diskFile.getUpdateTime());
     }
+
+    public PhotoItem(DiskFile diskFile, String sizeStr, String url, String videoUrl,
+                     CameraPhoto cameraPhoto, String durationStr) {
+        this.fileId = diskFile.getFileId();
+        this.filename = diskFile.getFilename();
+        this.type = ObjectType.getDescByCode(diskFile.getFileType()).toLowerCase();
+        this.url = url;
+        this.videoUrl = videoUrl;
+        this.duration = durationStr;
+        this.size = sizeStr;
+        this.updateTime = DateTimeConverter.format(cameraPhoto.getShotAt());
+    }
 }

+ 51 - 29
file/file-service/src/main/java/cn/reghao/tnb/file/app/zdisk/service/DiskAlbumService.java

@@ -6,7 +6,12 @@ import cn.reghao.jutil.jdk.converter.ByteType;
 import cn.reghao.jutil.jdk.web.db.Page;
 import cn.reghao.jutil.jdk.web.db.PageList;
 import cn.reghao.jutil.jdk.web.result.Result;
+import cn.reghao.tnb.common.util.ConstantId;
+import cn.reghao.tnb.common.util.StringUtil;
+import cn.reghao.tnb.file.app.zdisk.db.mapper.CameraPhotoMapper;
 import cn.reghao.tnb.file.app.zdisk.model.constant.AlbumType;
+import cn.reghao.tnb.file.app.zdisk.model.po.CameraPhoto;
+import cn.reghao.tnb.file.app.zdisk.model.query.DiskQuery;
 import cn.reghao.tnb.file.app.zdisk.model.vo.DiskAlbumDetail;
 import cn.reghao.tnb.file.app.zdisk.model.vo.DiskAlbumInfo;
 import cn.reghao.tnb.file.app.zdisk.model.vo.DiskFileDetail;
@@ -40,24 +45,23 @@ import java.util.stream.Collectors;
 public class DiskAlbumService {
     @DubboReference(check = false, retries = 0, timeout = 60_000)
     private AccountQuery accountQuery;
-    @DubboReference(check = false, timeout = 60_000)
-    private OssService ossService;
 
-    private final int channelCode = 111;
+    private final OssService ossService;
     private final int albumMaxFiles = 1000;
-    private final int pageSize = 12;
     private final DiskFileMapper diskFileMapper;
     private final DiskAlbumMapper diskAlbumMapper;
     private final DiskAlbumRepository diskAlbumRepository;
     private final DiskFileService diskFileService;
-    private DiskShareService diskShareService;
+    private final DiskShareService diskShareService;
     private final IdService idService;
     private final ByteConverter byteConverter;
+    private final CameraPhotoMapper cameraPhotoMapper;
 
-    public DiskAlbumService(DiskFileMapper diskFileMapper, DiskAlbumMapper diskAlbumMapper,
+    public DiskAlbumService(OssService ossService, DiskFileMapper diskFileMapper, DiskAlbumMapper diskAlbumMapper,
                             DiskAlbumRepository diskAlbumRepository, DiskFileService diskFileService,
                             DiskShareService diskShareService, IdService idService,
-                            ByteConverter byteConverter) {
+                            ByteConverter byteConverter, CameraPhotoMapper cameraPhotoMapper) {
+        this.ossService = ossService;
         this.diskFileMapper = diskFileMapper;
         this.diskAlbumMapper = diskAlbumMapper;
         this.diskAlbumRepository = diskAlbumRepository;
@@ -65,6 +69,7 @@ public class DiskAlbumService {
         this.diskShareService = diskShareService;
         this.idService = idService;
         this.byteConverter = byteConverter;
+        this.cameraPhotoMapper = cameraPhotoMapper;
     }
 
     public void createAlbum(AlbumCreate albumCreate) {
@@ -294,7 +299,7 @@ public class DiskAlbumService {
         }
 
         int total = diskAlbumMapper.countDiskAlbumFile(albumId);
-        Page page = new Page(pageNumber, pageSize);
+        Page page = new Page(pageNumber, ConstantId.PAGE_SIZE);
         List<DiskAlbumFile> diskAlbumFileList = diskAlbumMapper.findDiskAlbumFileByPage(page, albumId);
         List<String> sha256sumList = diskAlbumFileList.stream().map(DiskAlbumFile::getSha256sum).collect(Collectors.toList());
         if (sha256sumList.isEmpty()) {
@@ -315,7 +320,7 @@ public class DiskAlbumService {
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
 
-        PageList<DiskFileDetail> pageList = PageList.pageList(pageNumber, pageSize, total, diskFileDetailList);
+        PageList<DiskFileDetail> pageList = PageList.pageList(pageNumber, ConstantId.PAGE_SIZE, total, diskFileDetailList);
         return new DiskAlbumDetail(diskAlbum, pageList);
     }
 
@@ -328,7 +333,7 @@ public class DiskAlbumService {
      */
     public PageList<DiskFileDetail> getAlbumExcludeFiles(int fileType, int pageNumber) {
         long loginUser = UserContext.getUserId();
-        Page page = new Page(pageNumber, pageSize);
+        Page page = new Page(pageNumber, ConstantId.PAGE_SIZE);
         List<DiskFile> diskFileList = diskFileMapper.findSha256sumGroupByPage(page, fileType, loginUser);
         int total = diskFileMapper.countSha256sumGroupByDiskQuery(fileType, loginUser).size();
 
@@ -342,31 +347,48 @@ public class DiskAlbumService {
                 log.error("{}", e.getMessage());
             }
         }
-        return PageList.pageList(pageNumber, pageSize, total, list);
+        return PageList.pageList(pageNumber, ConstantId.PAGE_SIZE, total, list);
     }
 
     public PageList<PhotoItem> getPhotoItems(int pageNumber) {
-        long albumId = 101102L;
         long loginUser = UserContext.getUserId();
-        Page page = new Page(pageNumber, pageSize);
-
-        int total = diskAlbumMapper.countDiskAlbumFile(albumId);
-        List<DiskAlbumFile> diskAlbumFiles = diskAlbumMapper.findDiskAlbumFileByPage(page, albumId);
-        List<String> sha256sumList = diskAlbumFiles
-                .stream()
-                .map(DiskAlbumFile::getSha256sum)
-                .collect(Collectors.toList());
+        Page page = new Page(pageNumber, ConstantId.PAGE_SIZE);
+        String path = "/我的相册";
+        DiskQuery diskQuery = new DiskQuery.Builder()
+                .owner(loginUser)
+                .path(path)
+                .build();
+        int total = diskFileMapper.countByDiskQuery(diskQuery);
+        List<DiskFile> diskFileList = diskFileMapper.findDiskQueryByPage(page, diskQuery);
+        List<String> fileIds = diskFileList.stream().map(DiskFile::getFileId).toList();
+        if (fileIds.isEmpty()) {
+            return PageList.empty();
+        }
 
-        List<PhotoItem> list = new ArrayList<>();
-        if (!sha256sumList.isEmpty()) {
-            list = diskFileMapper.findSha256sumGroup(sha256sumList).stream()
-                    .map(diskFile -> {
-                        String sizeStr = byteConverter.convert(ByteType.Bytes, diskFile.getSize());
-                        return new PhotoItem(diskFile, sizeStr);
-                    })
-                    .toList();
+        List<CameraPhoto> cameraPhotoList = cameraPhotoMapper.findByFileIds(fileIds);
+        if (cameraPhotoList.size() != fileIds.size()) {
+            return PageList.empty();
         }
 
-        return PageList.pageList(pageNumber, pageSize, total, list);
+        Map<String, CameraPhoto> groupMap = cameraPhotoList.stream().collect(
+                Collectors.groupingBy(CameraPhoto::getFileId,
+                        Collectors.collectingAndThen(Collectors.toList(), List::getFirst)));
+        List<PhotoItem> list = diskFileList.stream().map(diskFile -> {
+            String fileId = diskFile.getFileId();
+            String sizeStr = byteConverter.convert(ByteType.Bytes, diskFile.getSize());
+            String objectUrl = ossService.getSignedUrl(fileId, null);
+            String url = "";
+            String videoUrl = "";
+            if (diskFile.getFileType() == ObjectType.Image.getCode()) {
+                url = objectUrl;
+            } else {
+                videoUrl = objectUrl;
+            }
+
+            CameraPhoto cameraPhoto = groupMap.get(fileId);
+            String durationStr = StringUtil.getTimeStr(cameraPhoto.getDuration().intValue());
+            return new PhotoItem(diskFile, sizeStr, url, videoUrl, cameraPhoto, durationStr);
+        }).toList();
+        return PageList.pageList(pageNumber, ConstantId.PAGE_SIZE, total, list);
     }
 }

+ 22 - 0
file/file-service/src/main/resources/mapper/disk/CameraPhotoMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.tnb.file.app.zdisk.db.mapper.CameraPhotoMapper">
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert ignore into disk_camera_photo
+        (`file_id`,`manufacturer`,`model`,`software`,`shot_at`,`geo`,`geo_valid`,`area_code`,`duration`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.fileId},#{item.manufacturer},#{item.model},#{item.software},#{item.shotAt},point(#{item.longitude},#{item.latitude}),#{item.geoValid},#{item.areaCode},#{item.duration})
+        </foreach>
+    </insert>
+
+    <select id="findByFileIds" resultType="cn.reghao.tnb.file.app.zdisk.model.po.CameraPhoto">
+        select *
+        from disk_camera_photo
+        where file_id in
+        <foreach collection="list" item="id" index="index" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </select>
+</mapper>