Browse Source

Merge branch 'jwy' into glx

master
glx 1 month ago
parent
commit
191c7437ea
  1. 1
      src/main/java/com/youlai/boot/auth/service/impl/WxMaAuthServiceImpl.java
  2. 27
      src/main/java/com/youlai/boot/mini/controller/HomePageController.java
  3. 35
      src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java
  4. 59
      src/main/java/com/youlai/boot/mini/controller/UnauthenticatedController.java
  5. 15
      src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java
  6. 6
      src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java
  7. 24
      src/main/java/com/youlai/boot/mini/model/dto/MapBoundsDTO.java
  8. 18
      src/main/java/com/youlai/boot/mini/model/dto/MapSearchDTO.java
  9. 4
      src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java
  10. 18
      src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java
  11. 20
      src/main/java/com/youlai/boot/mini/model/query/StrayAnimalQuery.java
  12. 36
      src/main/java/com/youlai/boot/mini/model/vo/MiniStrayAnimalNoteMediaVO.java
  13. 46
      src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalDetailsVO.java
  14. 28
      src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalNearbyVO.java
  15. 89
      src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java
  16. 15
      src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java
  17. 131
      src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java
  18. 7
      src/main/java/com/youlai/boot/system/model/entity/SysUser.java
  19. 2
      src/main/resources/application-dev.yml
  20. 2
      src/main/resources/application-prod.yml
  21. BIN
      src/main/resources/default-img/default_cat.png
  22. BIN
      src/main/resources/default-img/default_dog.png
  23. BIN
      src/main/resources/default-img/default_other.png
  24. 176
      src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml
  25. 17
      src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml

1
src/main/java/com/youlai/boot/auth/service/impl/WxMaAuthServiceImpl.java

@ -184,6 +184,7 @@ public class WxMaAuthServiceImpl implements WxMaAuthService {
private SysUser createNewUser(String mobile) { private SysUser createNewUser(String mobile) {
SysUser user = new SysUser(); SysUser user = new SysUser();
user.setMobile(mobile); user.setMobile(mobile);
user.setUuid(IdUtil.fastSimpleUUID());
user.setUsername("wx_" + IdUtil.fastSimpleUUID().substring(0, 8)); user.setUsername("wx_" + IdUtil.fastSimpleUUID().substring(0, 8));
user.setNickname("微信用户"); user.setNickname("微信用户");
user.setStatus(1); user.setStatus(1);

27
src/main/java/com/youlai/boot/mini/controller/HomePageController.java

@ -0,0 +1,27 @@
package com.youlai.boot.mini.controller;
import com.youlai.boot.common.result.Result;
import com.youlai.boot.mini.model.dto.MapSearchDTO;
import com.youlai.boot.mini.service.StrayAnimalService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@Tag(name = "首页的相关接口")
@RestController
@RequestMapping("/api/v1/mini/homePage")
@RequiredArgsConstructor
public class HomePageController {
private final StrayAnimalService strayAnimalService;
@Operation(summary = "根据地图边界获取流浪动物信息(不需要登录)")
@RequestMapping(value = "/listByBounds", method = RequestMethod.GET)
public Result<?> listByMapBounds(MapSearchDTO mapSearch) {
return Result.success(strayAnimalService.listByMapBounds(mapSearch));
}
}

35
src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java

@ -4,12 +4,16 @@ import com.youlai.boot.common.annotation.Log;
import com.youlai.boot.common.annotation.RepeatSubmit; import com.youlai.boot.common.annotation.RepeatSubmit;
import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.ActionTypeEnum;
import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.enums.LogModuleEnum;
import com.youlai.boot.common.model.Option; import com.youlai.boot.common.result.PageResult;
import com.youlai.boot.common.result.Result; import com.youlai.boot.common.result.Result;
import com.youlai.boot.framework.security.util.SecurityUtils;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO;
import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.dto.EditVisibilityDTO;
import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.form.StrayAnimalForm;
import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery;
import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO;
import com.youlai.boot.mini.model.vo.StrayAnimalShortVO;
import com.youlai.boot.mini.service.StrayAnimalService; import com.youlai.boot.mini.service.StrayAnimalService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@ -19,7 +23,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -111,4 +114,32 @@ public class StrayAnimalController {
return Result.success(); return Result.success();
} }
@Operation(summary = "获取自己登记创建的动物信息列表")
@GetMapping(value = "/getSelfCreatedPage")
@Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.LIST)
public PageResult<StrayAnimalShortVO> getSelfCreatedPage(
OwnStrayAnimalQuery queryParams
) {
return PageResult.success(strayAnimalService.getSelfCreatedPage(queryParams));
}
@Operation(summary = "获取动物信息详情")
@RequestMapping(value = "/getDetails/{animalUuid}", method = RequestMethod.GET)
public Result<StrayAnimalDetailsVO> getDetails(
@PathVariable String animalUuid){
return Result.success(strayAnimalService.getDetails(animalUuid, SecurityUtils.getUserId()));
}
@Operation(summary = "获取某个用户登记创建的动物信息列表")
@GetMapping(value = "/getOthersCreatedPage/{authorUuid}")
@Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.LIST)
public PageResult<StrayAnimalShortVO> getOthersCreatedPage(
@PathVariable String authorUuid,
OwnStrayAnimalQuery queryParams
) {
return PageResult.success(strayAnimalService.getOthersCreatedPage(authorUuid, queryParams));
}
} }

59
src/main/java/com/youlai/boot/mini/controller/UnauthenticatedController.java

@ -0,0 +1,59 @@
package com.youlai.boot.mini.controller;
import com.youlai.boot.common.annotation.Log;
import com.youlai.boot.common.annotation.RepeatSubmit;
import com.youlai.boot.common.enums.ActionTypeEnum;
import com.youlai.boot.common.enums.LogModuleEnum;
import com.youlai.boot.common.result.PageResult;
import com.youlai.boot.common.result.Result;
import com.youlai.boot.framework.security.util.SecurityUtils;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO;
import com.youlai.boot.mini.model.dto.EditVisibilityDTO;
import com.youlai.boot.mini.model.form.StrayAnimalForm;
import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery;
import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO;
import com.youlai.boot.mini.model.vo.StrayAnimalShortVO;
import com.youlai.boot.mini.service.StrayAnimalService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 流浪动物信息
*/
@Tag(name = "未登录状态下的相关接口")
@RestController
@RequestMapping("/api/v1/mini/public")
@RequiredArgsConstructor
public class UnauthenticatedController {
private final StrayAnimalService strayAnimalService;
@Operation(summary = "获取动物信息详情)", operationId = "publicGetAnimalDetails")
@RequestMapping(value = "/strayAnimal/getDetails/{animalUuid}", method = RequestMethod.GET)
public Result<StrayAnimalDetailsVO> getDetails(
@PathVariable String animalUuid){
return Result.success(strayAnimalService.getDetails(animalUuid, null));
}
@Operation(summary = "获取某个用户登记创建的动物信息列表", operationId = "publicGetOthersCreatedPage")
@GetMapping(value = "/strayAnimal/getOthersCreatedPage/{authorUuid}")
@Log(module = LogModuleEnum.STRAY_ANIMAL_INFO, value = ActionTypeEnum.LIST)
public PageResult<StrayAnimalShortVO> getOthersCreatedPage(
@PathVariable String authorUuid,
OwnStrayAnimalQuery queryParams
) {
return PageResult.success(strayAnimalService.getOthersCreatedPage(authorUuid, queryParams));
}
}

15
src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java

@ -1,7 +1,17 @@
package com.youlai.boot.mini.mapper; package com.youlai.boot.mini.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youlai.boot.mini.model.dto.MapSearchDTO;
import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.entity.MiniStrayAnimal;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery;
import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO;
import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO;
import com.youlai.boot.mini.model.vo.StrayAnimalShortVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 流浪动物基础信息表 Mapper 接口 * 流浪动物基础信息表 Mapper 接口
@ -15,4 +25,9 @@ public interface MiniStrayAnimalMapper extends BaseMapper<MiniStrayAnimal> {
void updateStrayAnimal(MiniStrayAnimal miniStrayAnimal); void updateStrayAnimal(MiniStrayAnimal miniStrayAnimal);
IPage<StrayAnimalShortVO> getAnimalPage(Page<StrayAnimalShortVO> page, @Param("queryParams") OwnStrayAnimalQuery queryParams);
StrayAnimalDetailsVO getStrayAnimalDetails(@Param("animalUuid") String animalUuid, @Param("miniUserId") Long miniUserId);
List<StrayAnimalNearbyVO> listByMapBounds(MapSearchDTO mapSearch);
} }

6
src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalNoteMediaMapper.java

@ -2,16 +2,20 @@ package com.youlai.boot.mini.mapper;
import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.youlai.boot.mini.model.vo.MiniStrayAnimalNoteMediaVO;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* 流浪信息资源表 Mapper 接口 * 流浪信息资源表 Mapper 接口
* *
* @author jwy * @author jwy
* @since * @since
*/ */
public interface MiniStrayAnimalNoteMediaMapper extends BaseMapper<MiniStrayAnimalNoteMedia> { public interface MiniStrayAnimalNoteMediaMapper extends BaseMapper<MiniStrayAnimalNoteMedia> {
int getMediaCountByNoteIdAndType(Map<String, Object> param); int getMediaCountByNoteIdAndType(Map<String, Object> param);
List<MiniStrayAnimalNoteMediaVO> getMediaByNoteIdAndType(Map<String, Object> param);
} }

24
src/main/java/com/youlai/boot/mini/model/dto/MapBoundsDTO.java

@ -0,0 +1,24 @@
package com.youlai.boot.mini.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 地图视口边界请求参数 DTO
*/
@Data
public class MapBoundsDTO {
@Schema(description = "地图窗口左下角经度")
private Double southWestLng;
@Schema(description = "地图窗口左下角纬度")
private Double southWestLat;
@Schema(description = "地图窗口右上角经度")
private Double northEastLng;
@Schema(description = "地图窗口右上角纬度")
private Double northEastLat;
}

18
src/main/java/com/youlai/boot/mini/model/dto/MapSearchDTO.java

@ -0,0 +1,18 @@
package com.youlai.boot.mini.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 地图视口边界请求参数 DTO
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MapSearchDTO extends MapBoundsDTO{
@Schema(description = "动物类型,cat-猫,dog-狗,other-其他", example = "cat")
private String animalType;
}

4
src/main/java/com/youlai/boot/mini/model/entity/MiniStrayAnimalNoteMedia.java

@ -60,10 +60,6 @@ public class MiniStrayAnimalNoteMedia implements Serializable {
@Schema(description = "时长(秒,视频用)") @Schema(description = "时长(秒,视频用)")
private Integer duration; private Integer duration;
@TableField("sort_order")
@Schema(description = "排序顺序")
private Long sortOrder;
@TableField("create_time") @TableField("create_time")
@Schema(description = "创建时间") @Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

18
src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java

@ -0,0 +1,18 @@
package com.youlai.boot.mini.model.query;
import com.youlai.boot.common.base.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class OwnStrayAnimalQuery extends StrayAnimalQuery {
@Schema(description = "登录用户ID", example = "1", hidden = true)
private Long miniUserId;
@Schema(description = "创建动物的用户ID", example = "1", hidden = true)
private Long creatorId;
}

20
src/main/java/com/youlai/boot/mini/model/query/StrayAnimalQuery.java

@ -0,0 +1,20 @@
package com.youlai.boot.mini.model.query;
import com.youlai.boot.common.base.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class StrayAnimalQuery extends BaseQuery {
@Schema(description = "动物类型,cat-猫,dog-狗,other-其他", example = "cat")
private String animalType;
@Schema(description = "起始登记时间,毫秒级时间戳", example = "1776426078459")
private Long createStartTimestamp;
@Schema(description = "截止登记时间,毫秒级时间戳", example = "1776426078459")
private Long createEndTimestamp;
}

36
src/main/java/com/youlai/boot/mini/model/vo/MiniStrayAnimalNoteMediaVO.java

@ -0,0 +1,36 @@
package com.youlai.boot.mini.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class MiniStrayAnimalNoteMediaVO {
@Schema(type = "string", description = "资源ID")
private String noteMediaUuid;
@Schema(type = "string", description = "动物笔记UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED)
private String noteUuid;
@Schema(description = "媒体类型,image-图片,video-视频")
private String mediaType;
@Schema(description = "资源URL")
private String sourceUrl;
@Schema(description = "对象存储中的key")
private String storageKey;
@Schema(description = "缩略图URL(视频需要)")
private String thumbnailUrl;
@Schema(description = "宽度(像素)")
private Integer width;
@Schema(description = "高度(像素)")
private Integer height;
@Schema(description = "时长(秒,视频用)")
private Integer duration;
}

46
src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalDetailsVO.java

@ -0,0 +1,46 @@
package com.youlai.boot.mini.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class StrayAnimalDetailsVO extends StrayAnimalShortVO {
@Schema(description = "颜色", example = "白色")
private String color;
@Schema(description = "体型,small-小,medium-中等,large-大", example = "medium")
private String size;
@Schema(description = "状态,found-发现,adopted-已被领养,missing-失踪", example = "missing", requiredMode = Schema.RequiredMode.REQUIRED)
private String status="found";
@Schema(description = "经度", example = "118.08125")
private Double lng;
@Schema(description = "纬度", example = "24.606929")
private Double lat;
@Schema(description = "省", example = "福建省")
private String province;
@Schema(description = "市", example = "厦门市")
private String city;
@Schema(description = "区(县)", example = "集美区")
private String district;
@Schema(description = "完整详细地址,含省市区(县)", example = "福建省厦门市集美区侨英街道莲花尚院1号院")
private String address;
@Schema(description = "图片信息", example = "[]")
private List<MiniStrayAnimalNoteMediaVO> images;
@Schema(description = "视频信息", example = "[]")
private List<MiniStrayAnimalNoteMediaVO> videos;
}

28
src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalNearbyVO.java

@ -0,0 +1,28 @@
package com.youlai.boot.mini.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StrayAnimalNearbyVO {
@Schema(type = "string", description = "动物信息UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED)
private String animalUuid;
@Schema(description = "动物类型,cat-猫,dog-狗,other-其他")
private String animalType;
@Schema(description = "颜色")
private String color;
@Schema(description = "体型大小,small-小,medium-中等,large-大")
private String size;
@Schema(description = "经度")
private Double lng;
@Schema(description = "纬度")
private Double lat;
}

89
src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java

@ -0,0 +1,89 @@
package com.youlai.boot.mini.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StrayAnimalShortVO {
@Schema(description = "作者uuid", example = "true")
private String authorUuid;
@Schema(description = "作者昵称", example = "true")
private String authorName;
@Schema(description = "作者头像", example = "true")
private String authorAvatar;
@Schema(type = "string", description = "动物信息UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED)
private String animalUuid;
@Schema(type = "string", description = "动物笔记UUID", example = "0677d62d63ec693bf1bd6dab8a877dc1", requiredMode = Schema.RequiredMode.REQUIRED)
private String animalNoteUuid;
@Schema(description = "封面图片url", example = "https://pet-map.oss-cn-beijing.aliyuncs.com/animal_note/18ec68e743a0bba8c85f441fbce08/17441599158f190n30q.jpg")
private String firstImageUrl;
@Schema(description = "动物类型,cat-猫,dog-狗,other-其他", example = "cat", requiredMode = Schema.RequiredMode.REQUIRED)
private String animalType;
// @Schema(description = "颜色", example = "白色")
// private String color;
//
// @Schema(description = "体型,small-小,medium-中等,large-大", example = "medium")
// private String size;
// @Schema(description = "状态,found-发现,adopted-已被领养,missing-失踪", example = "missing", requiredMode = Schema.RequiredMode.REQUIRED)
// private String status="found";
@Schema(description = "笔记标题", example = "在公园发现的小猫", requiredMode = Schema.RequiredMode.REQUIRED)
private String title;
@Schema(description = "笔记内容", example = "今天下午在人民公园看到一只走失的小猫")
private String content;
@Schema(description = "可见性范围:public-公开,private-仅自己,friends-仅好友", example = "public")
private String visibility="public";
// @Schema(description = "经度", example = "118.08125")
// private Double lng;
//
// @Schema(description = "纬度", example = "24.606929")
// private Double lat;
//
// @Schema(description = "省", example = "福建省")
// private String province;
//
// @Schema(description = "市", example = "厦门市")
// private String city;
//
// @Schema(description = "区(县)", example = "集美区")
// private String district;
//
// @Schema(description = "完整详细地址,含省市区(县)", example = "福建省厦门市集美区侨英街道莲花尚院1号院")
// private String address;
@Schema(description = "浏览数", example = "118")
private Integer viewCount;
@Schema(description = "点赞数", example = "125")
private Integer likeCount;
@Schema(description = "评论数", example = "125")
private Integer commentCount;
@Schema(description = "收藏数", example = "125")
private Integer collectCount;
@Schema(description = "当前用户是否已点赞", example = "false")
private Boolean isLiked;
@Schema(description = "当前用户是否收藏", example = "false")
private Boolean isCollected;
@Schema(description = "审核状态:0通过,1审核中,2审核未通过", example = "0")
private Integer auditStatus;
}

15
src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java

@ -1,12 +1,17 @@
package com.youlai.boot.mini.service; package com.youlai.boot.mini.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.youlai.boot.common.result.Result;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO;
import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.dto.EditVisibilityDTO;
import com.youlai.boot.mini.model.dto.MapSearchDTO;
import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.entity.MiniStrayAnimal;
import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.form.StrayAnimalForm;
import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery;
import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO;
import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO;
import com.youlai.boot.mini.model.vo.StrayAnimalShortVO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -25,5 +30,13 @@ public interface StrayAnimalService extends IService<MiniStrayAnimal> {
void updateVisibility(String animalUuid, EditVisibilityDTO editVisibilityDTO); void updateVisibility(String animalUuid, EditVisibilityDTO editVisibilityDTO);
void delete(DeleteStrayAnimalDTO deleteStrayAnimalDTO); void delete(DeleteStrayAnimalDTO deleteStrayAnimalDTO);
IPage<StrayAnimalShortVO> getSelfCreatedPage(OwnStrayAnimalQuery queryParams);
StrayAnimalDetailsVO getDetails(String animalUuid, Long miniUserId);
IPage<StrayAnimalShortVO> getOthersCreatedPage(String authorUuid, OwnStrayAnimalQuery queryParams);
List<StrayAnimalNearbyVO> listByMapBounds(MapSearchDTO mapSearch);
} }

131
src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java

@ -3,8 +3,11 @@ package com.youlai.boot.mini.service.impl;
import ch.hsr.geohash.GeoHash; import ch.hsr.geohash.GeoHash;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.common.constant.CommonConstants; import com.youlai.boot.common.constant.CommonConstants;
import com.youlai.boot.common.exception.MsgException; import com.youlai.boot.common.exception.MsgException;
@ -21,12 +24,20 @@ import com.youlai.boot.mini.mapper.MiniStrayAnimalNoteMediaMapper;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalDTO;
import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO; import com.youlai.boot.mini.model.dto.DeleteStrayAnimalNoteMediaDTO;
import com.youlai.boot.mini.model.dto.EditVisibilityDTO; import com.youlai.boot.mini.model.dto.EditVisibilityDTO;
import com.youlai.boot.mini.model.dto.MapSearchDTO;
import com.youlai.boot.mini.model.enums.AnimalNoteMediaTypeEnum; import com.youlai.boot.mini.model.enums.AnimalNoteMediaTypeEnum;
import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.entity.MiniStrayAnimal;
import com.youlai.boot.mini.model.entity.MiniStrayAnimalNote; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNote;
import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia;
import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.form.StrayAnimalForm;
import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery;
import com.youlai.boot.mini.model.vo.MiniStrayAnimalNoteMediaVO;
import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO;
import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO;
import com.youlai.boot.mini.model.vo.StrayAnimalShortVO;
import com.youlai.boot.mini.service.StrayAnimalService; import com.youlai.boot.mini.service.StrayAnimalService;
import com.youlai.boot.system.mapper.UserMapper;
import com.youlai.boot.system.model.entity.SysUser;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
@ -34,6 +45,7 @@ import org.apache.commons.io.FilenameUtils;
import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Point;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -51,14 +63,26 @@ import java.util.*;
@Slf4j @Slf4j
public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, MiniStrayAnimal> implements StrayAnimalService { public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, MiniStrayAnimal> implements StrayAnimalService {
@Value("${oss.aliyun.endpoint}")
private String endpoint;
@Value("${oss.aliyun.bucket-name}")
private String bucketName;
private final AliyunFileService aliyunFileService; private final AliyunFileService aliyunFileService;
private final MiniStrayAnimalNoteMapper miniStrayAnimalNoteMapper; private final MiniStrayAnimalNoteMapper miniStrayAnimalNoteMapper;
private final MiniStrayAnimalNoteMediaMapper miniStrayAnimalNoteMediaMapper; private final MiniStrayAnimalNoteMediaMapper miniStrayAnimalNoteMediaMapper;
private final MiniStrayAnimalMapper miniStrayAnimalMapper; private final MiniStrayAnimalMapper miniStrayAnimalMapper;
private final UserMapper userMapper;
private final MiniStrayAnimalConverter miniStrayAnimalConverter; private final MiniStrayAnimalConverter miniStrayAnimalConverter;
public String getDefaultCatCoverHost() {
return "https://" + bucketName + "." + endpoint;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -81,7 +105,6 @@ public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, M
} }
private void saveMediaFiles(MiniStrayAnimalNote note, List<MultipartFile> images, List<MultipartFile> videos, long currentTimestamp) { private void saveMediaFiles(MiniStrayAnimalNote note, List<MultipartFile> images, List<MultipartFile> videos, long currentTimestamp) {
long sortOrder = currentTimestamp;
// 处理图片 // 处理图片
if (images != null) { if (images != null) {
for (MultipartFile image : images) { for (MultipartFile image : images) {
@ -101,7 +124,6 @@ public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, M
BufferedImage imageInfo = ImageIO.read(image.getInputStream()); BufferedImage imageInfo = ImageIO.read(image.getInputStream());
miniStrayAnimalNoteMedia.setWidth(imageInfo.getWidth()); miniStrayAnimalNoteMedia.setWidth(imageInfo.getWidth());
miniStrayAnimalNoteMedia.setHeight(imageInfo.getHeight()); miniStrayAnimalNoteMedia.setHeight(imageInfo.getHeight());
miniStrayAnimalNoteMedia.setSortOrder(sortOrder++);
miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp); miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp);
miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp)); miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp));
miniStrayAnimalNoteMedia.setCreateBy(note.getMiniUserId()); miniStrayAnimalNoteMedia.setCreateBy(note.getMiniUserId());
@ -131,7 +153,6 @@ public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, M
miniStrayAnimalNoteMedia.setMediaType(AnimalNoteMediaTypeEnum.VIDEO.name().toLowerCase()); miniStrayAnimalNoteMedia.setMediaType(AnimalNoteMediaTypeEnum.VIDEO.name().toLowerCase());
miniStrayAnimalNoteMedia.setSourceUrl(url); miniStrayAnimalNoteMedia.setSourceUrl(url);
miniStrayAnimalNoteMedia.setStorageKey(objectName); miniStrayAnimalNoteMedia.setStorageKey(objectName);
miniStrayAnimalNoteMedia.setSortOrder(sortOrder++);
miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp); miniStrayAnimalNoteMedia.setCreateTimestamp(currentTimestamp);
miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp)); miniStrayAnimalNoteMedia.setCreateTime(new Date(currentTimestamp));
miniStrayAnimalNoteMedia.setCreateBy(note.getMiniUserId()); miniStrayAnimalNoteMedia.setCreateBy(note.getMiniUserId());
@ -231,6 +252,7 @@ public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, M
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateStrayAnimal(String animalUuid, StrayAnimalForm formData) { public void updateStrayAnimal(String animalUuid, StrayAnimalForm formData) {
// 校验动物是否存在 // 校验动物是否存在
MiniStrayAnimal animal = getValidAnimal(animalUuid); MiniStrayAnimal animal = getValidAnimal(animalUuid);
@ -422,4 +444,107 @@ public class StrayAnimalServiceImpl extends ServiceImpl<MiniStrayAnimalMapper, M
miniStrayAnimalMapper.update(null, updateWrapper); miniStrayAnimalMapper.update(null, updateWrapper);
} }
@Override
public IPage<StrayAnimalShortVO> getSelfCreatedPage(OwnStrayAnimalQuery queryParams) {
queryParams.setMiniUserId(SecurityUtils.getUserId());
queryParams.setCreatorId(SecurityUtils.getUserId());
return getAnimalPage(queryParams);
}
private IPage<StrayAnimalShortVO> getAnimalPage(OwnStrayAnimalQuery queryParams) {
// 参数构建
int pageNum = queryParams.getPageNum();
int pageSize = queryParams.getPageSize();
Page<StrayAnimalShortVO> page = new Page<>(pageNum, pageSize);
IPage<StrayAnimalShortVO> result = this.miniStrayAnimalMapper.getAnimalPage(page, queryParams);
if (result.getTotal() > 0) {
result.getRecords().forEach(item -> {
if (StrUtil.isBlank(item.getFirstImageUrl())) {
switch (item.getAnimalType()) {
case "cat":
item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_cat.png");
break;
case "dog":
item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_dog.png");
break;
default:
item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_other.png");
break;
}
}
});
}
// 查询数据
return result;
}
@Override
public StrayAnimalDetailsVO getDetails(String animalUuid, Long miniUserId) {
// 校验动物是否存在
MiniStrayAnimal animal = getValidAnimal(animalUuid);
StrayAnimalDetailsVO strayAnimalDetailsVO = miniStrayAnimalMapper.getStrayAnimalDetails(animalUuid, miniUserId);
MiniStrayAnimalNote appStrayAnimalNote = miniStrayAnimalNoteMapper.selectOne(new LambdaQueryWrapper<MiniStrayAnimalNote>()
.eq(MiniStrayAnimalNote::getStrayAnimalId, animal.getId()));
if (appStrayAnimalNote != null) {
Map<String, Object> param = new HashMap<>();
param.put("noteId", appStrayAnimalNote.getId());
param.put("mediaType", AnimalNoteMediaTypeEnum.IMAGE.name().toLowerCase());
List<MiniStrayAnimalNoteMediaVO> images = miniStrayAnimalNoteMediaMapper.getMediaByNoteIdAndType(param);
if (CollectionUtils.isNotEmpty(images)) {
images.forEach(item -> {
item.setNoteUuid(appStrayAnimalNote.getUuid());
});
}
param.put("mediaType", AnimalNoteMediaTypeEnum.VIDEO.name().toLowerCase());
List<MiniStrayAnimalNoteMediaVO> videos = miniStrayAnimalNoteMediaMapper.getMediaByNoteIdAndType(param);
if (CollectionUtils.isNotEmpty(videos)) {
videos.forEach(item -> {
item.setNoteUuid(appStrayAnimalNote.getUuid());
});
}
strayAnimalDetailsVO.setImages(images);
strayAnimalDetailsVO.setVideos(videos);
}
return strayAnimalDetailsVO;
}
@Override
public IPage<StrayAnimalShortVO> getOthersCreatedPage(String authorUuid, OwnStrayAnimalQuery queryParams) {
SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUuid, authorUuid)
.eq(SysUser::getIsDeleted, 0));
if (sysUser == null) {
throw new MsgException("用户不存在");
}
queryParams.setMiniUserId(SecurityUtils.getUserId());
queryParams.setCreatorId(sysUser.getId());
return getAnimalPage(queryParams);
}
@Override
public List<StrayAnimalNearbyVO> listByMapBounds(MapSearchDTO mapSearch) {
if (mapSearch.getNorthEastLng() == null || mapSearch.getNorthEastLat() == null
|| mapSearch.getSouthWestLng() == null || mapSearch.getSouthWestLat() == null) {
throw new MsgException("地图边界参数未完整填写");
}
double[] wgs84 = CoordinateTransformUtils.gcj02ToWgs84(mapSearch.getNorthEastLng(), mapSearch.getNorthEastLat());
mapSearch.setNorthEastLat(wgs84[1]);
mapSearch.setNorthEastLng(wgs84[0]);
double[] wgs842 = CoordinateTransformUtils.gcj02ToWgs84(mapSearch.getSouthWestLng(), mapSearch.getSouthWestLat());
mapSearch.setSouthWestLat(wgs842[1]);
mapSearch.setSouthWestLng(wgs842[0]);
return miniStrayAnimalMapper.listByMapBounds(mapSearch);
}
} }

7
src/main/java/com/youlai/boot/system/model/entity/SysUser.java

@ -13,6 +13,11 @@ import lombok.Setter;
@Setter @Setter
public class SysUser extends BaseEntity { public class SysUser extends BaseEntity {
/**
* uuid
*/
private String uuid;
/** /**
* 用户名 * 用户名
*/ */
@ -72,4 +77,4 @@ public class SysUser extends BaseEntity {
* 是否删除(0- 1-) * 是否删除(0- 1-)
*/ */
private Integer isDeleted; private Integer isDeleted;
} }

2
src/main/resources/application-dev.yml

@ -88,6 +88,8 @@ security:
- /api/v1/auth/refresh-token # 刷新令牌接口 - /api/v1/auth/refresh-token # 刷新令牌接口
- /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号)
- /api/v1/logs/** # 日志接口(访问日志列表) - /api/v1/logs/** # 日志接口(访问日志列表)
- /api/v1/mini/public/**
- /api/v1/mini/homePage/listByBounds
- /healthcheck - /healthcheck
# 非安全端点路径,完全绕过 Spring Security 的过滤器 # 非安全端点路径,完全绕过 Spring Security 的过滤器
unsecured-urls: unsecured-urls:

2
src/main/resources/application-prod.yml

@ -88,6 +88,8 @@ security:
- /api/v1/auth/refresh-token # 刷新令牌接口 - /api/v1/auth/refresh-token # 刷新令牌接口
- /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - /api/v1/wxma/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号)
- /api/v1/logs/** # 日志接口(访问日志列表) - /api/v1/logs/** # 日志接口(访问日志列表)
- /api/v1/mini/public/**
- /api/v1/mini/homePage/listByBounds
- /healthcheck - /healthcheck
# 非安全端点路径,完全绕过 Spring Security 的过滤器 # 非安全端点路径,完全绕过 Spring Security 的过滤器
unsecured-urls: unsecured-urls:

BIN
src/main/resources/default-img/default_cat.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

BIN
src/main/resources/default-img/default_dog.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

BIN
src/main/resources/default-img/default_other.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

176
src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml

@ -116,4 +116,180 @@
WHERE id = #{id} WHERE id = #{id}
</update> </update>
<select id="getAnimalPage" resultType="com.youlai.boot.mini.model.vo.StrayAnimalShortVO" databaseId="mysql">
WITH first_image AS (
SELECT
m.note_id,
m.source_url,
ROW_NUMBER() OVER (
PARTITION BY m.note_id
ORDER BY m.id ASC
) AS rn
FROM mini_stray_animal_note_media m
WHERE m.media_type = 'image'
AND m.is_deleted = 0
)
SELECT
u.uuid AS authorUuid,
u.nickname AS authorName,
u.avatar AS authorAvatar,
a.uuid AS animalUuid,
n.uuid AS animalNoteUuid,
a.animal_type,
fi.source_url AS firstImageUrl,
n.title,
n.content,
n.visibility,
n.view_count,
n.like_count,
n.comment_count,
n.collect_count,
<if test="queryParams.miniUserId != null">
-- 当前用户是否点赞
EXISTS (
SELECT 1
FROM mini_stray_animal_note_like l
WHERE l.note_id = n.id
AND l.mini_user_id = #{queryParams.miniUserId}
AND l.is_deleted = 0
) AS isLiked,
-- 当前用户是否收藏
EXISTS (
SELECT 1
FROM mini_stray_animal_note_collect c
WHERE c.note_id = n.id
AND c.mini_user_id = #{queryParams.miniUserId}
AND c.is_deleted = 0
) AS isCollected,
</if>
a.audit_status
FROM
mini_stray_animal a
INNER JOIN sys_user u ON a.mini_user_id = u.id
LEFT JOIN mini_stray_animal_note n ON n.stray_animal_id = a.id
LEFT JOIN first_image fi ON fi.note_id = n.id AND fi.rn = 1
<where>
n.is_deleted = 0 AND a.is_deleted = 0
<!-- 指定用户 -->
AND n.mini_user_id = #{queryParams.creatorId}
<!-- 动物类型 -->
<if test="queryParams.animalType != null and queryParams.animalType != ''">
AND a.animal_type = #{queryParams.animalType}
</if>
<!-- 时间范围 -->
<if test="queryParams.createStartTimestamp != null">
AND a.create_timestamp >= #{queryParams.createStartTimestamp}
</if>
<if test="queryParams.createEndTimestamp != null">
AND #{queryParams.createEndTimestamp} >= a.create_timestamp
</if>
</where>
ORDER BY a.id DESC
</select>
<select id="getStrayAnimalDetails" resultType="com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO">
SELECT
su.uuid AS authorUuid,
su.nickname AS authorName,
su.avatar AS authorAvatar,
a.uuid AS animalUuid,
a.animal_type,
a.color,
a.size,
a.status,
a.audit_status,
n.uuid animalNoteUuid,
n.title,
n.content,
n.visibility,
n.view_count,
n.like_count,
n.comment_count,
n.collect_count,
<if test="miniUserId != null">
-- 当前用户是否点赞
EXISTS (
SELECT 1
FROM mini_stray_animal_note_like l
WHERE l.note_id = n.id
AND l.mini_user_id = #{miniUserId}
AND l.is_deleted = 0
) AS isLiked,
-- 当前用户是否收藏
EXISTS (
SELECT 1
FROM mini_stray_animal_note_collect c
WHERE c.note_id = n.id
AND c.mini_user_id = #{miniUserId}
AND c.is_deleted = 0
) AS isCollected,
</if>
a.province,
a.city,
a.district,
ST_X(a.gd_location_point) AS lng,
ST_Y(a.gd_location_point) AS lat,
a.address
FROM
mini_stray_animal a
LEFT JOIN mini_stray_animal_note n ON a.id = n.stray_animal_id
LEFT JOIN sys_user su ON su.id = a.mini_user_id AND su.is_deleted = 0
WHERE a.uuid = #{animalUuid}
</select>
<select id="listByMapBounds" resultType="com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO">
SELECT
uuid animalUuid,
animal_type,
color,
size,
ST_X(gd_location_point) AS lng,
ST_Y(gd_location_point) AS lat
FROM
mini_stray_animal
WHERE is_deleted = 0
AND MBRContains(
ST_GeomFromText(
CONCAT(
'Polygon((',
#{southWestLat}, ' ', #{southWestLng}, ',',
#{southWestLat}, ' ', #{northEastLng}, ',',
#{northEastLat}, ' ', #{northEastLng}, ',',
#{northEastLat}, ' ', #{southWestLng}, ',',
#{southWestLat}, ' ', #{southWestLng},
'))'
), 4326
),
wgs84_location_point
)
<if test="animalType != null and animalType !=''">
AND animal_type = #{animalType}
</if>
</select>
</mapper> </mapper>

17
src/main/resources/mapper/mini/MiniStrayAnimalNoteMediaMapper.xml

@ -14,4 +14,21 @@
note_id = #{noteId} AND media_type = #{mediaType} note_id = #{noteId} AND media_type = #{mediaType}
</select> </select>
<select id="getMediaByNoteIdAndType" resultType="com.youlai.boot.mini.model.vo.MiniStrayAnimalNoteMediaVO">
SELECT
uuid AS noteMediaUuid,
media_type,
source_url,
storage_key,
thumbnail_url,
width,
height,
duration
FROM
mini_stray_animal_note_media
WHERE
note_id = #{noteId} AND media_type = #{mediaType} AND is_deleted = 0
ORDER BY id desc
</select>
</mapper> </mapper>

Loading…
Cancel
Save