From 7049d82e4117ea75dcbb3657d06634d06407f294 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期三, 02 七月 2025 18:40:06 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev
---
framework/src/main/resources/mapper/lmk/ThumbsUpRecordMapper.xml | 27 +
framework/src/main/java/cn/lili/modules/search/repository/EsVideoIndexRepository.java | 15
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoVO.java | 4
framework/src/main/java/cn/lili/modules/lmk/service/ThumbsUpRecordService.java | 17
buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java | 21
framework/src/main/java/cn/lili/modules/lmk/mapper/ThumbsUpRecordMapper.java | 17
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java | 520 +++++++++++++++++--
framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoQuery.java | 5
framework/src/main/java/cn/lili/modules/lmk/domain/form/KitchenVideoForm.java | 6
framework/src/main/java/cn/lili/cache/CachePrefix.java | 5
framework/src/main/java/cn/lili/modules/lmk/constant/RedisKeyExpireConstant.java | 5
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java | 7
framework/src/main/java/cn/lili/modules/lmk/domain/entity/Video.java | 8
framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsDetailVO.java | 8
framework/src/main/resources/mapper/lmk/VideoMapper.xml | 142 +++++
framework/src/main/resources/es/video.json | 53 +
framework/src/main/java/cn/lili/modules/lmk/service/impl/ThumbsUpRecordServiceImpl.java | 12
manager-api/src/main/java/cn/lili/controller/lmk/VideoController.java | 22
framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyThumbsUpVO.java | 24
framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java | 60 +
framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java | 25
framework/src/main/java/cn/lili/modules/lmk/enums/general/ThumbsUpTypeEnum.java | 1
lmk-job/src/main/java/cn/lili/job/VideoJob.java | 15
framework/src/main/java/cn/lili/modules/lmk/service/EsService.java | 68 ++
framework/src/main/java/cn/lili/modules/lmk/domain/form/HealthVideoForm.java | 6
framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoEsQuery.java | 24
framework/src/main/java/cn/lili/modules/lmk/domain/vo/KitchenVideoVO.java | 4
framework/src/main/java/cn/lili/modules/lmk/domain/dto/VideoEsUpdateDTO.java | 24
consumer/src/main/java/cn/lili/listener/VideoMessageListener.java | 70 ++
framework/src/main/java/cn/lili/elasticsearch/EsSuffix.java | 5
framework/src/main/java/cn/lili/rocketmq/tags/VideoTagsEnum.java | 5
buyer-api/src/main/java/cn/lili/controller/order/CartController.java | 21
framework/src/main/java/cn/lili/modules/lmk/domain/es/VideoIndex.java | 110 ++++
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoEsServiceImpl.java | 214 +++++++
framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleVideoTagVO.java | 5
35 files changed, 1,486 insertions(+), 89 deletions(-)
diff --git a/buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java b/buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
index 19e4379..8078d3f 100644
--- a/buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
+++ b/buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
@@ -2,6 +2,7 @@
import cn.lili.group.Update;
import cn.lili.group.Add;
+import cn.lili.modules.lmk.domain.form.ThumbsUpRecordForm;
import cn.lili.modules.lmk.domain.form.VideoFootPrintForm;
import cn.lili.modules.lmk.domain.form.VideoHomePageInfoForm;
import cn.lili.modules.lmk.domain.form.WxVideoForm;
@@ -38,7 +39,7 @@
}
@PutMapping
- @ApiOperation(value = "淇敼", notes = "淇敼")
+ @ApiOperation(value = "淇敼瑙嗛", notes = "淇敼瑙嗛")
public Result update(@RequestBody @Validated(Update.class) WxVideoForm form) {
return videoService.updatePublish(form);
}
@@ -118,6 +119,12 @@
return videoService.getAuthorCollectVideoPage(query);
}
+ @GetMapping("/author-like-video-page")
+ @ApiOperation(value = "鑾峰彇瑙嗛涓婚〉浣滆�呯偣璧炵殑瑙嗛鍒嗛〉", notes = "鑾峰彇瑙嗛涓婚〉浣滆�呯偣璧炵殑瑙嗛鍒嗛〉")
+ public Result getAuthorLikeVideoPage(AuthorVideoQuery query) {
+ return videoService.getAuthorLikeVideoPage(query);
+ }
+
@PostMapping("/home-page-info-edit")
@ApiOperation(value = "淇濆瓨瑙嗛涓婚〉鐨勪釜浜轰俊鎭慨鏀�", notes = "淇濆瓨瑙嗛涓婚〉鐨勪釜浜轰俊鎭慨鏀�")
public Result homePageInfoEdit(@RequestBody @Validated VideoHomePageInfoForm form) {
@@ -129,4 +136,16 @@
public Result wxDetail(@PathVariable("id") String id) {
return videoService.wxDetail(id);
}
+
+ @PostMapping("/change/thumbs-up")
+ @ApiOperation(value = "鐐硅禐/鍙栨秷鐐硅禐瑙嗛", notes = "鐐硅禐/鍙栨秷鐐硅禐瑙嗛")
+ public Result changeThumbsUp(@RequestBody @Validated(Add.class) ThumbsUpRecordForm form) {
+ return videoService.changeThumbsUp(form);
+ }
+
+ @GetMapping("/es/search")
+ @ApiOperation(value = "瑙嗛鎼滅储", notes = "瑙嗛鎼滅储")
+ public Result esSearch(VideoEsQuery query) {
+ return videoService.esSearch(query);
+ }
}
diff --git a/buyer-api/src/main/java/cn/lili/controller/order/CartController.java b/buyer-api/src/main/java/cn/lili/controller/order/CartController.java
index 2973172..70fc330 100644
--- a/buyer-api/src/main/java/cn/lili/controller/order/CartController.java
+++ b/buyer-api/src/main/java/cn/lili/controller/order/CartController.java
@@ -74,6 +74,27 @@
throw new ServiceException(ResultCode.CART_ERROR);
}
}
+ @ApiOperation(value = "鍚戣喘鐗╄溅涓鐩栨坊鍔犱竴涓骇鍝�")
+ @PostMapping("/addCard")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "skuId", value = "浜у搧ID", required = true, dataType = "Long", paramType = "query"),
+ @ApiImplicitParam(name = "num", value = "姝や骇鍝佺殑璐拱鏁伴噺", required = true, dataType = "int", paramType = "query"),
+ @ApiImplicitParam(name = "cartType", value = "璐墿杞︾被鍨嬶紝榛樿鍔犲叆璐墿杞�", paramType = "query")
+ })
+ public ResultMessage<Object> addCard(@NotNull(message = "浜у搧id涓嶈兘涓虹┖") String skuId,
+ @NotNull(message = "璐拱鏁伴噺涓嶈兘涓虹┖") @Min(value = 1, message = "鍔犲叆璐墿杞︽暟閲忓繀椤诲ぇ浜�0") Integer num) {
+ try {
+ //璇诲彇閫変腑鐨勫垪琛�
+ cartService.add(skuId, num, CartTypeEnum.CART.name(), true);
+ return ResultUtil.success();
+ } catch (ServiceException se) {
+ log.info(se.getMsg(), se);
+ throw se;
+ } catch (Exception e) {
+ log.error(ResultCode.CART_ERROR.message(), e);
+ throw new ServiceException(ResultCode.CART_ERROR);
+ }
+ }
@ApiOperation(value = "鑾峰彇璐墿杞﹂〉闈㈣喘鐗╄溅璇︽儏")
diff --git a/consumer/src/main/java/cn/lili/listener/VideoMessageListener.java b/consumer/src/main/java/cn/lili/listener/VideoMessageListener.java
index 613f9af..e970292 100644
--- a/consumer/src/main/java/cn/lili/listener/VideoMessageListener.java
+++ b/consumer/src/main/java/cn/lili/listener/VideoMessageListener.java
@@ -1,9 +1,13 @@
package cn.lili.listener;
import cn.lili.cache.Cache;
+import cn.lili.elasticsearch.EsSuffix;
+import cn.lili.modules.lmk.domain.dto.VideoEsUpdateDTO;
import cn.lili.modules.lmk.domain.entity.MyCollect;
import cn.lili.modules.lmk.domain.entity.ThumbsUpRecord;
+import cn.lili.modules.lmk.domain.es.VideoIndex;
import cn.lili.modules.lmk.domain.form.ThumbsUpRecordForm;
+import cn.lili.modules.lmk.service.EsService;
import cn.lili.modules.lmk.service.ThumbsUpRecordService;
import cn.lili.modules.lmk.service.VideoCommentService;
import cn.lili.modules.lmk.service.VideoService;
@@ -16,6 +20,7 @@
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
@@ -33,20 +38,35 @@
private VideoService videoService;
@Autowired
+ @Qualifier("videoEsServiceImpl")
+ private EsService esService;
+
+ @Autowired
private Cache<Object> cache;
@Override
public void onMessage(MessageExt messageExt) {
try {
String msg = new String(messageExt.getBody());
- if (StringUtils.isBlank(msg)) {
- log.error("video msg is null, cant not consumer");
- return;
- }
+
switch (VideoTagsEnum.valueOf(messageExt.getTags())) {
case COLLECT:
this.collect(msg);
break;
+ case THUMBS_UP:
+ this.changeThumbsUp(msg);
+ break;
+ case ES_RECREATE:
+ this.recreateVideoIndex();
+ break;
+ case ES_DOC_ADD_OR_UPDATE:
+ this.addOrUpdateEsVideo(msg);
+ break;
+ case ES_DOC_UPDATE_SOME_FIELD:
+ this.updateEsVideoSomeField(msg);
+ break;
+ case ES_DOC_DEL:
+ this.delEsVideo(msg);
default:
log.error("video msg not match correct tag, consumer err");
break;
@@ -66,4 +86,46 @@
videoService.mqCollectChange(collect);
}
+ /**
+ * 閲嶅缓瑙嗛绱㈠紩
+ *
+ */
+ public void recreateVideoIndex() {
+ esService.recreateIndex(EsSuffix.VIDEO_INDEX_NAME, "/es/video.json");
+ }
+
+ /**
+ * 鏂板es瑙嗛鏁版嵁/鏇存柊
+ *
+ * @param msg
+ */
+ public void addOrUpdateEsVideo(String msg) {
+ VideoIndex videoIndex = JSON.parseObject(msg, VideoIndex.class);
+ esService.addOrUpdateDocument(videoIndex);
+ }
+
+ /**
+ * 鏇存柊es瑙嗛鐨勬煇浜涘瓧娈�
+ *
+ * @param msg
+ */
+ public void updateEsVideoSomeField(String msg) {
+ VideoEsUpdateDTO dto = JSON.parseObject(msg, VideoEsUpdateDTO.class);
+ esService.updateSomeField(EsSuffix.VIDEO_INDEX_NAME, dto.getId(), dto.getFields());
+ }
+
+ /**
+ * 鏍规嵁id鍒犻櫎es涓殑瑙嗛
+ *
+ * @param id
+ */
+ public void delEsVideo(String id) {
+ esService.deleteDocument(EsSuffix.VIDEO_INDEX_NAME, id);
+ }
+
+ public void changeThumbsUp(String msg) {
+ ThumbsUpRecord thumbsUpRecord = JSON.parseObject(msg, ThumbsUpRecord.class);
+ videoService.mqChangeThumbsUp(thumbsUpRecord);
+ }
+
}
diff --git a/framework/src/main/java/cn/lili/cache/CachePrefix.java b/framework/src/main/java/cn/lili/cache/CachePrefix.java
index e3cb80b..9d8ec0b 100644
--- a/framework/src/main/java/cn/lili/cache/CachePrefix.java
+++ b/framework/src/main/java/cn/lili/cache/CachePrefix.java
@@ -528,6 +528,11 @@
*/
VIDEO_COLLECT_NUM,
+ /**
+ * 瑙嗛鐐硅禐鏁伴噺
+ */
+ VIDEO_THUMBS_UP_NUM,
+
/**
* 鎵爜鐧诲綍
diff --git a/framework/src/main/java/cn/lili/elasticsearch/EsSuffix.java b/framework/src/main/java/cn/lili/elasticsearch/EsSuffix.java
index 9b6e4a9..72bd99c 100644
--- a/framework/src/main/java/cn/lili/elasticsearch/EsSuffix.java
+++ b/framework/src/main/java/cn/lili/elasticsearch/EsSuffix.java
@@ -14,6 +14,11 @@
public static final String GOODS_INDEX_NAME = "goods";
/**
+ * 瑙嗛绱㈠紩鍚庣紑
+ */
+ public static final String VIDEO_INDEX_NAME = "video";
+
+ /**
* 鏃ュ織绱㈠紩鍚庣紑
*/
public static final String LOGS_INDEX_NAME = "logs";
diff --git a/framework/src/main/java/cn/lili/modules/lmk/constant/RedisKeyExpireConstant.java b/framework/src/main/java/cn/lili/modules/lmk/constant/RedisKeyExpireConstant.java
index 2c4a4ba..edc1aa4 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/constant/RedisKeyExpireConstant.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/constant/RedisKeyExpireConstant.java
@@ -25,6 +25,11 @@
*/
public static final Long COLLECT_NUM_EXPIRE = 15l;
+ /**
+ * 瑙嗛鐐硅禐鏁拌繃鏈熸椂闂�
+ */
+ public static final Long VIDEO_THUMBS_UP_EXPIRE = 15l;
+
/**
* 杩囨湡鏃堕棿鍗曚綅
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/dto/VideoEsUpdateDTO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/dto/VideoEsUpdateDTO.java
new file mode 100644
index 0000000..ea3ee6d
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/dto/VideoEsUpdateDTO.java
@@ -0,0 +1,24 @@
+package cn.lili.modules.lmk.domain.dto;
+
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/7/1 10:01
+ */
+@Data
+public class VideoEsUpdateDTO {
+
+ /**
+ * 瑙嗛id
+ */
+ private String id;
+
+ /**
+ * 淇敼鍝簺瀛楁
+ */
+ private Map<String, Object> fields;
+
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/entity/Video.java b/framework/src/main/java/cn/lili/modules/lmk/domain/entity/Video.java
index 35ca6a7..d2e7e15 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/entity/Video.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/entity/Video.java
@@ -85,10 +85,18 @@
/** 璇勮鏁� */
private Integer commentNum;
+ @TableField("thumbs_up_num")
+ /** 鐐硅禐鏁� */
+ private Integer thumbsUpNum;
+
@TableField("collect_num_job")
/** 鏄惁闇�瑕佸畾鏃朵换鍔$粺璁℃敹钘忔暟 */
private Boolean collectNumJob;
+ @TableField("thumbs_up_num_job")
+ /** 鏄惁闇�瑕佸畾鏃朵换鍔$粺璁$偣璧炴暟 */
+ private Boolean thumbsUpNumJob;
+
@TableField("comment_num_job")
/** 鏄惁闇�瑕佸畾鏃朵换鍔$粺璁¤瘎璁烘暟 */
private Boolean commentNumJob;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/es/VideoIndex.java b/framework/src/main/java/cn/lili/modules/lmk/domain/es/VideoIndex.java
new file mode 100644
index 0000000..09f10d3
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/es/VideoIndex.java
@@ -0,0 +1,110 @@
+package cn.lili.modules.lmk.domain.es;
+
+import cn.lili.elasticsearch.EsSuffix;
+import cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO;
+import cn.lili.modules.lmk.domain.vo.VideoGoodsDetailVO;
+import lombok.Data;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * es鐨勮棰慸ocument锛堝瓨鍌ㄥ崟鍏冿級
+ *
+ * @author锛歺p
+ * @date锛�2025/6/30 14:50
+ */
+@Data
+@Document(indexName = "#{@elasticsearchProperties.indexPrefix}_" + EsSuffix.VIDEO_INDEX_NAME, createIndex = false)
+public class VideoIndex {
+
+ /** 瑙嗛id */
+ @Id
+ private String id;
+
+ /** 瑙嗛鏍囬 */
+ @Field(type = FieldType.Text, searchAnalyzer = "ik_max_word")
+ private String title;
+
+ /** 浣滆�卛d */
+ @Field(type = FieldType.Keyword)
+ private String authorId;
+
+ /** 浣滆�呭悕绉� */
+ @Field(type = FieldType.Text, searchAnalyzer = "ik_max_word")
+ private String authorName;
+
+ /** 浣滆�呭ご鍍� */
+ @Field(type = FieldType.Keyword)
+ private String authorAvatar;
+
+ /** 灏侀潰 */
+ @Field(type = FieldType.Keyword)
+ private String coverFileKey;
+
+ /** 瑙嗛鍦板潃 */
+ @Field(type = FieldType.Keyword)
+ private String videoFileKey;
+
+ /**
+ * 瑙嗛鍐呭绫诲瀷锛氳棰戙�佸浘鐗�
+ * @see cn.lili.modules.lmk.enums.general.VideoContentTypeEnum
+ */
+ @Field(type = FieldType.Keyword)
+ private String videoContentType;
+
+ /**
+ * 瑙嗛绫诲瀷锛氳棰戙�佸ぇ鍋ュ悍銆佺鍘�
+ * @see cn.lili.modules.lmk.enums.general.VideoTypeEnum
+ */
+ @Field(type = FieldType.Keyword)
+ private String videoType;
+
+ /** 鍥鹃泦-json鏁扮粍 */
+ @Field(type = FieldType.Keyword)
+ private String videoImgs;
+
+ /** 瑙嗛鏍囩 */
+ @Field(type = FieldType.Nested)
+ private List<SimpleVideoTagVO> tagList;
+
+ /** 瑙嗛鏃堕暱锛氱 */
+ @Field(type = FieldType.Keyword)
+ private Long videoDuration;
+
+ /** 瑙嗛濉厖妯″紡 */
+ @Field(type = FieldType.Keyword)
+ private String videoFit;
+
+ /** 瑙嗛鐘舵�� */
+ @Field(type = FieldType.Keyword)
+ private String status;
+
+ /** 鍟嗗搧淇℃伅 */
+ @Field(type = FieldType.Nested)
+ private List<VideoGoodsDetailVO> goodsList;
+
+ /** 鏄惁鎺ㄨ崘瑙嗛 */
+ @Field(type = FieldType.Keyword)
+ private boolean recommend = false;
+
+ /** 瑙嗛鏀惰棌鏁� */
+ @Field(type = FieldType.Integer)
+ private Integer collectNum;
+
+ /** 瑙嗛鐐硅禐鏁� */
+ @Field(type = FieldType.Integer)
+ private Integer thumbsUpNum;
+
+ /** 瑙嗛璇勮鏁� */
+ @Field(type = FieldType.Integer)
+ private Integer commentNum;
+
+ /** 瑙嗛鍙戝竷鏃堕棿锛堝鏍搁�氳繃鏃堕棿锛� */
+ @Field(type = FieldType.Date)
+ private Date publishTime;
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/form/HealthVideoForm.java b/framework/src/main/java/cn/lili/modules/lmk/domain/form/HealthVideoForm.java
index d372d82..37ba636 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/form/HealthVideoForm.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/form/HealthVideoForm.java
@@ -42,13 +42,17 @@
/** 瑙嗛闀垮害(绉�) */
-// @NotNull(message = "瑙嗛闀垮害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @NotNull(message = "瑙嗛闀垮害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
private Long videoDuration;
/** 瑙嗛鏍囬 */
@NotBlank(message = "鏍囬涓嶈兘涓虹┖", groups = {Add.class, Update.class})
private String title;
+ @NotBlank(message = "瑙嗛濉厖妯″紡涓嶈兘涓虹┖",groups = {Add.class, Update.class})
+ /** 瑙嗛濉厖妯″紡 */
+ private String videoFit;
+
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/form/KitchenVideoForm.java b/framework/src/main/java/cn/lili/modules/lmk/domain/form/KitchenVideoForm.java
index cb7906c..9809ccf 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/form/KitchenVideoForm.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/form/KitchenVideoForm.java
@@ -10,6 +10,7 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
@@ -41,7 +42,7 @@
/** 瑙嗛闀垮害(绉�) */
-// @NotNull(message = "瑙嗛闀垮害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
+ @NotNull(message = "瑙嗛闀垮害涓嶈兘涓虹┖", groups = {Add.class, Update.class})
private Long videoDuration;
/** 瑙嗛鏍囬 */
@@ -52,6 +53,9 @@
@Size(min = 1,max = 5, message = "鏍囩鍒楄〃涓嶈兘涓虹┖",groups = {Add.class, Update.class})
private List<String> checkKitchenType;
+ @NotBlank(message = "瑙嗛濉厖妯″紡涓嶈兘涓虹┖",groups = {Add.class, Update.class})
+ /** 瑙嗛濉厖妯″紡 */
+ private String videoFit;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoEsQuery.java b/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoEsQuery.java
new file mode 100644
index 0000000..1cdda02
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoEsQuery.java
@@ -0,0 +1,24 @@
+package cn.lili.modules.lmk.domain.query;
+
+import cn.lili.base.AbsQuery;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author锛歺p
+ * @date锛�2025/7/2 10:08
+ */
+@Data
+@ApiModel("瑙嗛鎼滅储")
+public class VideoEsQuery {
+
+ @ApiModelProperty("鍏抽敭璇�")
+ private String keyword;
+
+ @ApiModelProperty(value = "褰撳墠椤�", required = true)
+ private int pageNumber = 0;
+
+ @ApiModelProperty(value = "姣忛〉鏉℃暟", required = true)
+ private int pageSize = 10;
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoQuery.java b/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoQuery.java
index 8aa7959..3aa3b2a 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoQuery.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoQuery.java
@@ -24,7 +24,7 @@
@ApiModelProperty("浣滆�卛d")
private String authorId;
- @ApiModelProperty("瑙嗛鏉ユ簮锛歳ecommend鎺ㄨ崘銆乤uthor鏌愪綔鑰呯殑瑙嗛銆乧ollect鏌愪綔鑰呮敹钘忕殑瑙嗛")
+ @ApiModelProperty("瑙嗛鏉ユ簮锛歳ecommend鎺ㄨ崘銆乤uthor鏌愪綔鑰呯殑瑙嗛銆乧ollect鏌愪綔鑰呮敹钘忕殑瑙嗛銆乴ike鏌愪綔鑰呯偣璧炵殑瑙嗛")
private String videoFrom;
/**
@@ -32,5 +32,8 @@
*/
@ApiModelProperty("瑙嗛绫诲瀷锛氳棰戙�佸ぇ鍋ュ悍銆佺鍘紝榛樿涓嶄紶鏌ヨ棰�")
private String videoType = VideoTypeEnum.VIDEO.getValue();
+
+ @ApiModelProperty("鎼滅储瑙嗛鐨勫叧閿瘝")
+ private String keyword;
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/KitchenVideoVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/KitchenVideoVO.java
index 7511b4d..bf57ce5 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/KitchenVideoVO.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/KitchenVideoVO.java
@@ -97,6 +97,10 @@
@ApiModelProperty("璇勮鏁�")
private Integer commentNum;
+ /** 鐐硅禐鏁� */
+ @ApiModelProperty("鐐硅禐鏁�")
+ private Integer thumbsUpNum;
+
/** 鏉冮噸 */
@ApiModelProperty("鏉冮噸")
private double weight;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyThumbsUpVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyThumbsUpVO.java
new file mode 100644
index 0000000..7d43ba7
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleMyThumbsUpVO.java
@@ -0,0 +1,24 @@
+package cn.lili.modules.lmk.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 鎴戠殑鐐硅禐灞曠ず
+ *
+ * @author xp
+ * @since 2025-05-22
+ */
+@Data
+@ApiModel(value = "鎴戠殑鐐硅禐鍝嶅簲鏁版嵁", description = "鎴戠殑鐐硅禐鍝嶅簲鏁版嵁")
+public class SimpleMyThumbsUpVO {
+
+ private String id;
+
+ /** 鐐硅禐瀵瑰簲鐨刬d锛岃棰慽d銆佽瘎璁篿d锛屾牴鎹偣璧炵被鍨嬪畾 */
+ @ApiModelProperty("鐐硅禐瀵瑰簲鐨刬d锛岃棰慽d銆佽瘎璁篿d锛屾牴鎹偣璧炵被鍨嬪畾")
+ private String refId;
+
+
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleVideoTagVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleVideoTagVO.java
index 87c6671..a613316 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleVideoTagVO.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/SimpleVideoTagVO.java
@@ -6,6 +6,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.lang.NonNull;
/**
@@ -19,13 +21,16 @@
public class SimpleVideoTagVO {
@ApiModelProperty("鏍囩id")
+ @Field(type = FieldType.Keyword)
private String id;
/** 鏍囩鍚嶇О */
@ApiModelProperty("鏍囩鍚嶇О")
+ @Field(type = FieldType.Text, searchAnalyzer = "ik_max_word")
private String tagName;
@ApiModelProperty(hidden = true)
+ @Field(type = FieldType.Keyword)
private String videoId;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsDetailVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsDetailVO.java
index a98f5dc..c5d4acc 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsDetailVO.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoGoodsDetailVO.java
@@ -4,6 +4,8 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* @author锛歺p
@@ -14,20 +16,26 @@
public class VideoGoodsDetailVO {
@ApiModelProperty("鍟嗗搧id")
+ @Field(type = FieldType.Keyword)
private String goodsId;
@ApiModelProperty("鍟嗗搧skuid")
+ @Field(type = FieldType.Keyword)
private String id;
@ApiModelProperty("鍟嗗搧鍚嶇О")
+ @Field(type = FieldType.Text, searchAnalyzer = "ik_max_word")
private String goodsName;
@ApiModelProperty("浠锋牸")
+ @Field(type = FieldType.Keyword)
private String price;
@ApiModelProperty("缂╃暐鍥�")
+ @Field(type = FieldType.Keyword)
private String thumbnail;
@ApiModelProperty("鍟嗗搧鏁伴噺")
+ @Field(type = FieldType.Keyword)
private Integer goodsNum;
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoVO.java
index 9d88c54..9370cdd 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoVO.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoVO.java
@@ -89,6 +89,10 @@
@ApiModelProperty("璇勮鏁�")
private Integer commentNum;
+ /** 鐐硅禐鏁� */
+ @ApiModelProperty("鐐硅禐鏁�")
+ private Integer thumbsUpNum;
+
/** 鏉冮噸 */
@ApiModelProperty("鏉冮噸")
private double weight;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java
index 9041166..16ca447 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoVO.java
@@ -81,6 +81,9 @@
@ApiModelProperty("褰撳墠鐢ㄦ埛鏄惁鏀惰棌浜嗚瑙嗛")
private Boolean collected = Boolean.FALSE;
+ @ApiModelProperty("褰撳墠鐢ㄦ埛鏄惁鐐硅禐浜嗚瑙嗛")
+ private Boolean thumbsUp = Boolean.FALSE;
+
/** 鏀惰棌鏁� */
@ApiModelProperty("鏀惰棌鏁�")
private Integer collectNum;
@@ -89,6 +92,10 @@
@ApiModelProperty("璇勮鏁�")
private Integer commentNum;
+ /** 鐐硅禐鏁� */
+ @ApiModelProperty("鐐硅禐鏁�")
+ private Integer thumbsUpNum;
+
/** 瑙嗛鎷ユ湁鐨勬搷浣� */
@ApiModelProperty("瑙嗛鏀寔鐨勬搷浣�")
private List<VideoOption> options;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/enums/general/ThumbsUpTypeEnum.java b/framework/src/main/java/cn/lili/modules/lmk/enums/general/ThumbsUpTypeEnum.java
index f8374f2..48303e6 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/enums/general/ThumbsUpTypeEnum.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/enums/general/ThumbsUpTypeEnum.java
@@ -13,6 +13,7 @@
public enum ThumbsUpTypeEnum {
VIDEO_COMMENT("video_comment", "瑙嗛璇勮"),
+ VIDEO("video", "瑙嗛"),
;
private final String value;
diff --git a/framework/src/main/java/cn/lili/modules/lmk/mapper/ThumbsUpRecordMapper.java b/framework/src/main/java/cn/lili/modules/lmk/mapper/ThumbsUpRecordMapper.java
index 013bc58..c1040cc 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/mapper/ThumbsUpRecordMapper.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/mapper/ThumbsUpRecordMapper.java
@@ -2,6 +2,7 @@
import cn.lili.modules.lmk.domain.entity.ThumbsUpRecord;
import cn.lili.modules.lmk.domain.vo.CollectTypeNumVO;
+import cn.lili.modules.lmk.domain.vo.SimpleMyThumbsUpVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.lili.modules.lmk.domain.vo.ThumbsUpRecordVO;
@@ -38,4 +39,20 @@
* @return
*/
List<CollectTypeNumVO> countNumGroupByComment();
+
+ /**
+ * 缁熻瑙嗛鐐硅禐鏁伴噺
+ *
+ * @return
+ */
+ List<CollectTypeNumVO> countNumGroupByVideo();
+
+ /**
+ * 鏍规嵁瑙嗛id鏌ヨ鎴戠殑鐐硅禐
+ *
+ * @param videoIds
+ * @param userId
+ * @return
+ */
+ List<SimpleMyThumbsUpVO> getThumbssByVideoIds(@Param("videoIds") List<String> videoIds, @Param("userId") String userId);
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java b/framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java
index d567860..b852d1d 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java
@@ -1,6 +1,7 @@
package cn.lili.modules.lmk.mapper;
import cn.lili.modules.lmk.domain.entity.Video;
+import cn.lili.modules.lmk.domain.es.VideoIndex;
import cn.lili.modules.lmk.domain.query.*;
import cn.lili.modules.lmk.domain.vo.*;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -66,6 +67,13 @@
void updateCommentNumBatch(@Param("list") List<CollectTypeNumVO> numList);
/**
+ * 鎵归噺鏇存柊瑙嗛鐐硅禐鏁�
+ *
+ * @param numList
+ */
+ void updateThumbsUpNumBatch(@Param("list") List<CollectTypeNumVO> numList);
+
+ /**
* 瑙嗛涓婚〉浣滆�呬俊鎭�
*
* @param authorId
@@ -104,6 +112,14 @@
* @param query
*/
IPage getAuthorCollectVideoPage(IPage page, @Param("query") AuthorVideoQuery query);
+
+ /**
+ * 鑾峰彇瑙嗛涓婚〉浣滆�呯偣璧炵殑瑙嗛鍒嗛〉
+ *
+ * @param page
+ * @param query
+ */
+ IPage getAuthorLikeVideoPage(IPage page, @Param("query") AuthorVideoQuery query);
/**
* 灏忕▼搴�-瑙嗛璇︽儏
@@ -147,4 +163,13 @@
VideoFootInfoVo getVideoFootInfo(String id);
List<VideoFootVO> videoFoot(String id);
+
+ /**
+ * es鍚屾鏌ヨ瑙嗛鏁版嵁
+ *
+ * @param start 寮�濮嬩綅缃�
+ * @param pageSize 姣忛〉鏉℃暟
+ * @return
+ */
+ List<VideoIndex> getEsPage(@Param("start") int start, @Param("pageSize") int pageSize);
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/EsService.java b/framework/src/main/java/cn/lili/modules/lmk/service/EsService.java
new file mode 100644
index 0000000..1054162
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/EsService.java
@@ -0,0 +1,68 @@
+package cn.lili.modules.lmk.service;
+
+import java.util.Map;
+
+/**
+ * es澶勭悊
+ *
+ * @author锛歺p
+ * @date锛�2025/6/30 14:47
+ */
+public interface EsService {
+
+ /**
+ * 鑾峰彇绱㈠紩鐨勫畬鏁村悕绉�
+ *
+ * @param indexName
+ * @return
+ */
+ String getIndexFullName(String indexName);
+
+ /**
+ * 鍒涘缓绱㈠紩
+ *
+ * @param indexName 绱㈠紩鍚嶇О
+ * @param mappingJsonPath json鏂囦欢浣嶇疆锛岀浉瀵逛簬resource鐩綍锛屼緥濡傦細/es/video.json
+ */
+ void createIndex(String indexName, String mappingJsonPath);
+
+ /**
+ * 閲嶅缓绱㈠紩锛屽苟閲嶆柊娣诲姞绱㈠紩鏁版嵁
+ *
+ * @param indexName 绱㈠紩鍚嶇О
+ * @param mappingJsonPath json鏂囦欢浣嶇疆锛岀浉瀵逛簬resource鐩綍锛屼緥濡傦細/es/video.json
+ */
+ void recreateIndex(String indexName, String mappingJsonPath);
+
+ /**
+ * 娣诲姞/淇敼 鏂囨。锛屽鏋滄槸淇敼锛屽垯鏄暣鏉℃暟鎹洿鏂�
+ *
+ * @param data 鏁版嵁瀵硅薄
+ */
+ void addOrUpdateDocument(Object data);
+
+ /**
+ * 鏇存柊鏌愪簺瀛楁鐨勫��
+ *
+ * @param indexName 绱㈠紩鍚嶇О
+ * @param id 鏁版嵁id
+ * @param updateList 鏇存柊鍝簺瀛楁锛宬ey 瀛楁 value瑕佷慨鏀圭殑鍊�
+ */
+ void updateSomeField(String indexName, String id, Map<String, Object> updateList);
+
+ /**
+ * 鍒犻櫎鏂囨。
+ * @param indexName 绱㈠紩鍚嶇О
+ * @param id es涓婚敭锛屽彲浼犱笟鍔′富閿�
+ */
+ void deleteDocument(String indexName, String id);
+
+ /**
+ * 绱㈠紩鏄惁瀛樺湪
+ *
+ * @param indexName
+ * @return
+ */
+ boolean indexExist(String indexName);
+
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/ThumbsUpRecordService.java b/framework/src/main/java/cn/lili/modules/lmk/service/ThumbsUpRecordService.java
index 24a2102..05864c1 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/ThumbsUpRecordService.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/ThumbsUpRecordService.java
@@ -5,8 +5,10 @@
import cn.lili.modules.lmk.domain.form.ThumbsUpRecordForm;
import cn.lili.modules.lmk.domain.query.ThumbsUpRecordQuery;
import cn.lili.modules.lmk.domain.vo.CollectTypeNumVO;
+import cn.lili.modules.lmk.domain.vo.SimpleMyThumbsUpVO;
import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.Collection;
import java.util.List;
/**
@@ -57,4 +59,19 @@
* @return
*/
List<CollectTypeNumVO> countNumGroupByComment();
+
+ /**
+ * 缁熻瑙嗛鐨勭偣璧炴暟
+ *
+ * @return
+ */
+ List<CollectTypeNumVO> countNumGroupByVideo();
+
+ /**
+ * 鏍规嵁瑙嗛id鏌ヨ鎴戠殑鐐硅禐
+ *
+ * @param videoIds
+ * @return
+ */
+ List<SimpleMyThumbsUpVO> getThumbssByVideoIds(List<String> videoIds);
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java b/framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
index 0671480..2592ed4 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
@@ -2,6 +2,7 @@
import cn.lili.group.Add;
import cn.lili.modules.lmk.domain.entity.MyCollect;
+import cn.lili.modules.lmk.domain.entity.ThumbsUpRecord;
import cn.lili.modules.lmk.domain.entity.Video;
import cn.lili.modules.lmk.domain.form.*;
import cn.lili.modules.lmk.domain.query.*;
@@ -20,20 +21,6 @@
* @since 2025-05-16
*/
public interface VideoService extends IService<Video> {
-
- /**
- * 娣诲姞
- * @param form
- * @return
- */
- Result add(WxVideoForm form);
-
- /**
- * 淇敼
- * @param form
- * @return
- */
- Result update(WxVideoForm form);
/**
* 鎵归噺鍒犻櫎
@@ -178,6 +165,14 @@
Result getAuthorCollectVideoPage(AuthorVideoQuery query);
/**
+ * 鑾峰彇瑙嗛涓婚〉浣滆�呯偣璧炶棰戝垎椤�
+ *
+ * @param query
+ * @return
+ */
+ Result getAuthorLikeVideoPage(AuthorVideoQuery query);
+
+ /**
* 淇濆瓨瑙嗛涓婚〉鐨勪釜浜轰俊鎭慨鏀�
*
* @param form
@@ -265,4 +260,41 @@
* @param collect
*/
void mqCollectChange(MyCollect collect);
+
+ /**
+ * 閲嶅缓瑙嗛es绱㈠紩
+ *
+ * @return
+ */
+ Result recreateEsIndex();
+
+ /**
+ * 淇敼瑙嗛鐐硅禐鐘舵��
+ *
+ * @param form
+ * @return
+ */
+ Result changeThumbsUp(ThumbsUpRecordForm form);
+
+ /**
+ * mq淇敼瑙嗛鐐硅禐鐘舵��
+ *
+ * @param thumbsUpRecord
+ */
+ void mqChangeThumbsUp(ThumbsUpRecord thumbsUpRecord);
+
+ /**
+ * 鎵归噺鏇存柊瑙嗛鐐硅禐鏁伴噺
+ *
+ * @param numList
+ */
+ void updateThumbsUpNumBatch(List<CollectTypeNumVO> numList);
+
+ /**
+ * 瑙嗛鎼滅储-es
+ *
+ * @param query
+ * @return
+ */
+ Result esSearch(VideoEsQuery query);
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ThumbsUpRecordServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ThumbsUpRecordServiceImpl.java
index 44570b1..e3ec3f0 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ThumbsUpRecordServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ThumbsUpRecordServiceImpl.java
@@ -1,6 +1,8 @@
package cn.lili.modules.lmk.service.impl;
+import cn.lili.common.security.context.UserContext;
import cn.lili.modules.lmk.domain.vo.CollectTypeNumVO;
+import cn.lili.modules.lmk.domain.vo.SimpleMyThumbsUpVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.lili.modules.lmk.domain.entity.ThumbsUpRecord;
import cn.lili.modules.lmk.mapper .ThumbsUpRecordMapper;
@@ -94,4 +96,14 @@
public List<CollectTypeNumVO> countNumGroupByComment() {
return baseMapper.countNumGroupByComment();
}
+
+ @Override
+ public List<CollectTypeNumVO> countNumGroupByVideo() {
+ return baseMapper.countNumGroupByVideo();
+ }
+
+ @Override
+ public List<SimpleMyThumbsUpVO> getThumbssByVideoIds(List<String> videoIds) {
+ return baseMapper.getThumbssByVideoIds(videoIds, UserContext.getCurrentUserId());
+ }
}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoEsServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoEsServiceImpl.java
new file mode 100644
index 0000000..3823ce3
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoEsServiceImpl.java
@@ -0,0 +1,214 @@
+package cn.lili.modules.lmk.service.impl;
+
+import cn.lili.elasticsearch.BaseElasticsearchService;
+import cn.lili.elasticsearch.EsSuffix;
+import cn.lili.elasticsearch.config.ElasticsearchProperties;
+import cn.lili.modules.lmk.domain.entity.Video;
+import cn.lili.modules.lmk.domain.es.VideoIndex;
+import cn.lili.modules.lmk.enums.general.VideoStatusEnum;
+import cn.lili.modules.lmk.mapper.VideoMapper;
+import cn.lili.modules.lmk.service.EsService;
+import cn.lili.modules.search.repository.EsVideoIndexRepository;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
+import org.elasticsearch.action.bulk.BulkRequest;
+import org.elasticsearch.action.delete.DeleteRequest;
+import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.action.update.UpdateRequest;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.indices.CreateIndexRequest;
+import org.elasticsearch.client.indices.CreateIndexResponse;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.springframework.data.elasticsearch.core.document.Document;
+import org.springframework.data.elasticsearch.core.query.UpdateQuery;
+import org.springframework.stereotype.Service;
+import org.springframework.util.FileCopyUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.*;
+
+/**
+ * 瑙嗛es
+ *
+ * @author锛歺p
+ * @date锛�2025/6/30 15:54
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service("videoEsServiceImpl")
+public class VideoEsServiceImpl extends BaseElasticsearchService implements EsService {
+
+ private final ElasticsearchProperties elasticsearchProperties;
+ private final VideoMapper videoMapper;
+ private final EsVideoIndexRepository esVideoIndexRepository;
+
+ @Override
+ public String getIndexFullName(String indexName) {
+ return elasticsearchProperties.getIndexPrefix() + "_" + indexName;
+ }
+
+ @Override
+ public void createIndex(String indexName, String mappingJsonPath) {
+ if (! indexName.startsWith(elasticsearchProperties.getIndexPrefix())) {
+ indexName = this.getIndexFullName(indexName);
+ }
+ if (this.indexExist(indexName)) {
+ throw new RuntimeException(String.format("绱㈠紩锛�%s宸茬粡瀛樺湪锛屾棤娉曞垱寤�", indexName));
+ }
+ CreateIndexRequest request = new CreateIndexRequest(indexName);
+
+ // 1. 閰嶇疆绱㈠紩
+ request.settings(Settings.builder()
+ .put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards())
+ .put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas())
+ .put("index.max_result_window", 100000) //鏈�澶ф煡璇㈢粨鏋滄暟
+ .put("index.mapping.total_fields.limit", 2000));
+ // 2. 閰嶇疆mapping
+ String mapping;
+ try (InputStream inputStream = this.getClass().getResourceAsStream(mappingJsonPath)) {
+ byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
+ mapping = new String(bytes, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException(String.format("璇诲彇es鏄犲皠json鏂囦欢锛�%s寮傚父", mappingJsonPath), e);
+ }
+ request.mapping(mapping, XContentType.JSON);
+ // 3. 鍒涘缓绱㈠紩
+ try {
+ CreateIndexResponse createIndexResponse = client.indices().create(request, COMMON_OPTIONS);
+ } catch (IOException e) {
+ throw new RuntimeException(String.format("es鍒涘缓绱㈠紩澶辫触锛�%s", indexName), e);
+ }
+ }
+
+ @Override
+ public void recreateIndex(String indexName, String mappingJsonPath) {
+ indexName = this.getIndexFullName(indexName);
+ // 1. 濡傛灉绱㈠紩瀛樺湪锛屽厛鍒犻櫎绱㈠紩锛屽啀鍒涘缓绱㈠紩
+ if (this.indexExist(indexName)) {
+ DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
+ try {
+ AcknowledgedResponse deleteRes = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
+ this.createIndex(indexName, mappingJsonPath);
+ } catch (IOException e) {
+ log.error("鍒犻櫎绱㈠紩澶辫触", e);
+ throw new RuntimeException("鍒犻櫎绱㈠紩澶辫触");
+ }
+ } else {
+ this.createIndex(indexName, mappingJsonPath);
+ }
+ // 2. 澶氱嚎绋嬫煡璇㈣棰戞暟鎹紝鏋勫缓鏂囨。瀵硅薄
+ Long totalVideo = new LambdaQueryChainWrapper<>(videoMapper)
+ .count();
+ int totalThreads = (int) Math.ceil((double) totalVideo / 200); // 璁$畻闇�瑕佸灏戜釜绾跨▼
+ CountDownLatch latch = new CountDownLatch(totalThreads);
+ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
+ 4,
+ 10,
+ 10,
+ TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(4),
+ Executors.defaultThreadFactory(),
+ new ThreadPoolExecutor.AbortPolicy());
+ BlockingQueue<VideoIndex> dataList = new LinkedBlockingQueue<>();
+ for (int page = 0; page < totalThreads; page++) {
+ final int currentPage = page;
+ threadPoolExecutor.execute(() -> {
+ try {
+ List<VideoIndex> pageData = videoMapper.getEsPage(currentPage * 200, 200);
+ dataList.addAll(pageData);
+ } catch (Exception e) {
+ log.error("绗瑊}椤垫暟鎹煡璇㈠け璐�", currentPage, e);
+ } finally {
+ latch.countDown(); // 绾跨▼鎵ц瀹屾垚 -1
+ }
+ });
+ }
+ try {
+ latch.await(); // 绛夊緟鎵�鏈夌嚎绋嬫墽琛屽畬鎴�
+ // 3. 娣诲姞es鏁版嵁
+// BulkRequest bulkRequest = new BulkRequest();
+// String finalIndexName = indexName;
+// dataList.forEach(data -> {
+// IndexRequest indexRequest = new IndexRequest(finalIndexName)
+// .id(data.getId())
+// .source(data);
+// bulkRequest.add(indexRequest);
+// });
+// client.bulk(bulkRequest, RequestOptions.DEFAULT);
+ esVideoIndexRepository.saveAll(dataList);
+ } catch (InterruptedException e) {
+ log.error("澶氱嚎绋嬭鍙栬棰戞暟鎹紓甯�", e);
+ } finally {
+ threadPoolExecutor.shutdown();
+ }
+ }
+
+ @Override
+ public void addOrUpdateDocument(Object data) {
+ VideoIndex videoIndex = (VideoIndex) data;
+ esVideoIndexRepository.save(videoIndex);
+// indexName = this.getIndexFullName(indexName);
+// IndexRequest request = new IndexRequest(indexName);
+// request.id(id).source(data);
+// try {
+// client.index(request, RequestOptions.DEFAULT);
+// } catch (IOException e) {
+// throw new RuntimeException("es鏂囨。娣诲姞/淇敼澶辫触", e);
+// }
+ }
+
+ @Override
+ public void updateSomeField(String indexName, String id, Map<String, Object> updateList) {
+ indexName = this.getIndexFullName(indexName);
+ // 鏋勫缓鏇存柊璇锋眰
+ UpdateRequest request = new UpdateRequest(indexName, id);
+
+ try {
+ // 鏋勫缓鏇存柊鍐呭
+ XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
+ for (Map.Entry<String, Object> entry : updateList.entrySet()) {
+ builder.field(entry.getKey(), entry.getValue());
+ }
+ builder.endObject();
+
+ request.doc(builder); // 璁剧疆閮ㄥ垎鏇存柊鍐呭
+
+ // 鍙�夐厤缃�
+ request.retryOnConflict(2); // 鍐茬獊閲嶈瘯娆℃暟
+// request.fetchSource(true); // 杩斿洖鏇存柊鍚庣殑鏂囨。
+
+ client.update(request, RequestOptions.DEFAULT);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void deleteDocument(String indexName, String id) {
+ indexName = this.getIndexFullName(indexName);
+ DeleteRequest request = new DeleteRequest(indexName, id);
+ try {
+ client.delete(request, RequestOptions.DEFAULT);
+ } catch (IOException e) {
+ throw new RuntimeException("鍒犻櫎es鏂囨。澶辫触锛�" + id, e);
+ }
+ }
+
+ @Override
+ public boolean indexExist(String indexName) {
+ if (!indexName.startsWith(elasticsearchProperties.getIndexPrefix())) {
+ indexName = this.getIndexFullName(indexName);
+ }
+ return super.indexExist(indexName);
+ }
+}
diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
index 57909e0..ad439e9 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
@@ -2,9 +2,13 @@
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
+import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.context.UserContext;
+import cn.lili.elasticsearch.EsSuffix;
import cn.lili.modules.lmk.constant.RedisKeyExpireConstant;
+import cn.lili.modules.lmk.domain.dto.VideoEsUpdateDTO;
import cn.lili.modules.lmk.domain.entity.*;
+import cn.lili.modules.lmk.domain.es.VideoIndex;
import cn.lili.modules.lmk.domain.form.*;
import cn.lili.modules.lmk.domain.query.*;
import cn.lili.modules.lmk.domain.vo.*;
@@ -14,6 +18,10 @@
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.FootprintService;
import cn.lili.modules.member.service.MemberService;
+import cn.lili.modules.search.entity.dos.EsGoodsIndex;
+import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
+import cn.lili.rocketmq.tags.CommentTagsEnum;
+import cn.lili.rocketmq.tags.VideoTagsEnum;
import cn.lili.utils.COSUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -26,6 +34,18 @@
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.lucene.search.join.ScoreMode;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.elasticsearch.index.query.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.SearchHits;
+import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
+import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import cn.lili.utils.PageUtil;
@@ -62,33 +82,14 @@
private final KitchenTypeService kitchenTypeService;
private final Cache cache;
- /**
- * 娣诲姞
- * @param form
- * @return
- */
- @Override
- public Result add(WxVideoForm form) {
- Video entity = WxVideoForm.getEntityByForm(form, null);
- baseMapper.insert(entity);
- return Result.ok("娣诲姞鎴愬姛");
- }
+ private final RocketmqCustomProperties rocketmqCustomProperties;
+ private final RocketMQTemplate rocketMQTemplate;
+ private final ThumbsUpRecordService thumbsUpRecordService;
+ private final ElasticsearchOperations restTemplate;
- /**
- * 淇敼
- * @param form
- * @return
- */
- @Override
- public Result update(WxVideoForm form) {
- Video entity = baseMapper.selectById(form.getId());
+ @Qualifier("videoEsServiceImpl")
+ private final EsService esService;
- // 涓虹┖鎶汭llegalArgumentException锛屽仛鍏ㄥ眬寮傚父澶勭悊
- Assert.notNull(entity, "璁板綍涓嶅瓨鍦�");
- BeanUtils.copyProperties(form, entity);
- baseMapper.updateById(entity);
- return Result.ok("淇敼鎴愬姛");
- }
/**
* 鎵归噺鍒犻櫎
@@ -107,8 +108,18 @@
* @return
*/
@Override
+ @Transactional(rollbackFor = Exception.class)
public Result removeById(String id) {
baseMapper.deleteById(id);
+ new LambdaUpdateChainWrapper<>(videoGoodsService.getBaseMapper())
+ .eq(VideoGoods::getVideoId, id)
+ .remove();
+ new LambdaUpdateChainWrapper<>(videoTagRefService.getBaseMapper())
+ .eq(VideoTagRef::getVideoId, id)
+ .remove();
+ // mq寮傛鍒犻櫎es鏁版嵁
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_DEL.name();
+ rocketMQTemplate.asyncSend(destination, id, RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("鍒犻櫎鎴愬姛");
}
@@ -140,6 +151,11 @@
} else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
}
+ if (CollectionUtils.isNotEmpty(vo.getGoodsList())) {
+ vo.getGoodsList().stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
+ }
return Result.ok().data(vo);
}
@@ -165,11 +181,13 @@
video.setStatus(VideoStatusEnum.AUDITING.getValue());
video.setCoverUrl(form.getCover());
video.setVideoType(VideoTypeEnum.VIDEO.getValue());
+ video.setRecommend(Boolean.FALSE);
if (VideoContentTypeEnum.IMG.getValue().equals(form.getVideoContentType())) {
video.setVideoImgs(JSON.toJSONString(form.getVideoImgs()));
}
baseMapper.insert(video);
// 2.澶勭悊鏍囩
+ List<SimpleVideoTagVO> esTagList = new ArrayList<>(2);
List<VideoTagRef> videoTagRefs = form.getTags().stream().map(tag -> {
VideoTagRef videoTagRef = new VideoTagRef();
videoTagRef.setVideoId(video.getId());
@@ -189,14 +207,19 @@
} else {
videoTagRef.setVideoTagId(tag.getId());
}
+ SimpleVideoTagVO esTag = new SimpleVideoTagVO();
+ esTag.setVideoId(video.getId());
+ esTag.setTagName(tag.getTagName());
+ esTag.setId(tag.getId());
+ esTagList.add(esTag);
return videoTagRef;
}).collect(Collectors.toList());
videoTagRefService.saveBatch(videoTagRefs);
// 3. 淇濆瓨瑙嗛鏂囦欢淇℃伅
lmkFileService.addByForm(form.getFileInfo());
// 4. 澶勭悊閫夋嫨鐨勫晢鍝�
+ List<VideoGoods> videoGoods = new ArrayList<>(2);
if (CollectionUtils.isNotEmpty(form.getGoodsList())) {
- List<VideoGoods> videoGoods = new ArrayList<>(2);
for (int i = 0; i < form.getGoodsList().size(); i++) {
VideoGoods e = new VideoGoods();
e.setVideoId(video.getId());
@@ -204,10 +227,25 @@
e.setGoodsSkuId(form.getGoodsList().get(i).getGoodsSkuId());
e.setGoodsNum(form.getGoodsList().get(i).getGoodsNum());
e.setOrderNum(i);
- videoGoods.add(e);
+ videoGoodsService.save(e);
}
videoGoodsService.saveBatch(videoGoods);
}
+ // 5. 鏋勫缓es涓暟鎹紝mq寮傛澶勭悊
+ VideoIndex videoIndex = new VideoIndex();
+ BeanUtils.copyProperties(video, videoIndex);
+ videoIndex.setAuthorName(UserContext.getCurrentUser().getNickName());
+ videoIndex.setAuthorAvatar(UserContext.getCurrentUser().getFace());
+ videoIndex.setCoverFileKey(video.getCoverUrl());
+ List<VideoGoodsDetailVO> esGoodsList = videoGoods.stream().map(goods -> {
+ VideoGoodsDetailVO vo = new VideoGoodsDetailVO();
+ BeanUtils.copyProperties(goods, vo);
+ return vo;
+ }).collect(Collectors.toList());
+ videoIndex.setGoodsList(esGoodsList);
+ videoIndex.setTagList(esTagList);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_ADD_OR_UPDATE.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(videoIndex), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("鍙戝竷鎴愬姛锛岃棰戝鏍镐腑~");
}
@@ -231,6 +269,7 @@
new LambdaUpdateChainWrapper<>(videoTagRefService.getBaseMapper())
.eq(VideoTagRef::getVideoId, video.getId())
.remove();
+ List<SimpleVideoTagVO> esTagList = new ArrayList<>(2);
List<VideoTagRef> videoTagRefs = form.getTags().stream().map(tag -> {
VideoTagRef videoTagRef = new VideoTagRef();
videoTagRef.setVideoId(video.getId());
@@ -250,6 +289,11 @@
} else {
videoTagRef.setVideoTagId(tag.getId());
}
+ SimpleVideoTagVO esTag = new SimpleVideoTagVO();
+ esTag.setVideoId(video.getId());
+ esTag.setTagName(tag.getTagName());
+ esTag.setId(tag.getId());
+ esTagList.add(esTag);
return videoTagRef;
}).collect(Collectors.toList());
videoTagRefService.saveBatch(videoTagRefs);
@@ -259,8 +303,8 @@
new LambdaUpdateChainWrapper<>(videoGoodsService.getBaseMapper())
.eq(VideoGoods::getVideoId, video.getId())
.remove();
+ List<VideoGoods> videoGoods = new ArrayList<>(2);
if (CollectionUtils.isNotEmpty(form.getGoodsList())) {
- List<VideoGoods> videoGoods = new ArrayList<>(2);
for (int i = 0; i < form.getGoodsList().size(); i++) {
VideoGoods e = new VideoGoods();
e.setVideoId(video.getId());
@@ -272,6 +316,21 @@
}
videoGoodsService.saveBatch(videoGoods);
}
+ // 5. 鏇存柊es涓殑鏁版嵁锛宮q寮傛澶勭悊
+ VideoIndex videoIndex = new VideoIndex();
+ BeanUtils.copyProperties(video, videoIndex);
+ videoIndex.setAuthorName(UserContext.getCurrentUser().getNickName());
+ videoIndex.setAuthorAvatar(UserContext.getCurrentUser().getFace());
+ videoIndex.setCoverFileKey(video.getCoverUrl());
+ List<VideoGoodsDetailVO> esGoodsList = videoGoods.stream().map(goods -> {
+ VideoGoodsDetailVO vo = new VideoGoodsDetailVO();
+ BeanUtils.copyProperties(goods, vo);
+ return vo;
+ }).collect(Collectors.toList());
+ videoIndex.setGoodsList(esGoodsList);
+ videoIndex.setTagList(esTagList);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_ADD_OR_UPDATE.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(videoIndex), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("鍙戝竷鎴愬姛锛岃棰戝鏍镐腑~");
}
@@ -300,6 +359,15 @@
.eq(Video::getId, form.getId())
.set(Video::getRecommend, form.getRecommend())
.update();
+
+ // mq寮傛鏇存柊es
+ Map<String, Object> fields = new HashMap<>(2);
+ fields.put("recommend", form.getRecommend());
+ VideoEsUpdateDTO dto = new VideoEsUpdateDTO();
+ dto.setId(form.getId());
+ dto.setFields(fields);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_UPDATE_SOME_FIELD.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(dto), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("璁剧疆鎴愬姛");
}
@@ -319,34 +387,64 @@
}
videoAuditRecordService.save(auditRecord);
// 2. 淇敼瑙嗛鐘舵��
+ Map<String, Object> fields = new HashMap<>(2);
if (form.getResult()) {
video.setStatus(VideoStatusEnum.PUBLISHED.getValue());
video.setAuditPassTime(new Date());
+
+ fields.put("status", VideoStatusEnum.PUBLISHED.getValue());
} else {
video.setStatus(VideoStatusEnum.REJECT.getValue());
+ fields.put("status", VideoStatusEnum.REJECT.getValue());
}
baseMapper.updateById(video);
+
+ // 3. mq寮傛鏇存柊es
+ VideoEsUpdateDTO dto = new VideoEsUpdateDTO();
+ dto.setId(video.getId());
+ dto.setFields(fields);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_UPDATE_SOME_FIELD.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(dto), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok();
}
@Override
public Result up(String id) {
+ // 1. 鏇存柊鏁版嵁搴�
new LambdaUpdateChainWrapper<>(baseMapper)
.eq(Video::getId, id)
.set(Video::getStatus, VideoStatusEnum.PUBLISHED.getValue())
.update();
+ // 2. mq寮傛鏇存柊es
+ Map<String, Object> fields = new HashMap<>(2);
+ fields.put("status", VideoStatusEnum.PUBLISHED.getValue());
+ VideoEsUpdateDTO dto = new VideoEsUpdateDTO();
+ dto.setId(id);
+ dto.setFields(fields);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_UPDATE_SOME_FIELD.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(dto), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("涓婃灦鎴愬姛");
}
@Override
public Result down(VideoDownForm form) {
+ // 1. 鏇存柊鏁版嵁搴�
new LambdaUpdateChainWrapper<>(baseMapper)
.eq(Video::getId, form.getId())
.set(Video::getStatus, VideoStatusEnum.DISABLE.getValue())
.update();
+ // 2. mq寮傛鏇存柊es
+ Map<String, Object> fields = new HashMap<>(2);
+ fields.put("status", VideoStatusEnum.DISABLE.getValue());
+ VideoEsUpdateDTO dto = new VideoEsUpdateDTO();
+ dto.setId(form.getId());
+ dto.setFields(fields);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_UPDATE_SOME_FIELD.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(dto), RocketmqSendCallbackBuilder.commonCallback());
// TODO 灏嗕笅鏋跺師鍥犱互閫氱煡鐨勬柟寮忓憡鐭ョ敤鎴�
+
return Result.ok("涓嬫灦鎴愬姛");
}
@@ -356,6 +454,14 @@
.eq(Video::getId, id)
.set(Video::getStatus, VideoStatusEnum.DISABLE.getValue())
.update();
+ // 2. mq寮傛鏇存柊es
+ Map<String, Object> fields = new HashMap<>(2);
+ fields.put("status", VideoStatusEnum.DISABLE.getValue());
+ VideoEsUpdateDTO dto = new VideoEsUpdateDTO();
+ dto.setId(id);
+ dto.setFields(fields);
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_UPDATE_SOME_FIELD.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(dto), RocketmqSendCallbackBuilder.commonCallback());
return Result.ok("涓嬫灦鎴愬姛");
}
@@ -364,19 +470,33 @@
// 鎺ㄨ崘绠楁硶锛� 1. 鏍规嵁鐢ㄦ埛鐨勬敹钘忚棰戠殑鏍囩 2. 鏍规嵁鐢ㄦ埛鍏虫敞鐨勪綔鑰呯殑鍏跺畠瑙嗛 3. 鏍规嵁鐢ㄦ埛鐨勮鐪嬭褰曪紙瑙傜湅鏃堕暱杈冮暱鐨勩�侀噸澶嶈鐪嬫鏁拌緝澶氱殑锛� 4. 鍩轰簬鐩镐技鐢ㄦ埛鐨勮鐪嬭涓烘潵缁欒鐢ㄦ埛鎺ㄨ崘
IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
switch (query.getVideoFrom()) {
- case "recommend":
+ case "recommend":// 鍔犺浇鎺ㄨ崘瑙嗛
baseMapper.recommendVideo(page, query);
break;
- case "author":
+ case "author": // 鍔犺浇瑙嗛涓婚〉鎴戝彂甯冪殑瑙嗛
AuthorVideoQuery query1 = new AuthorVideoQuery();
+ BeanUtils.copyProperties(query, query1);
query1.setAuthorId(query.getAuthorId());
baseMapper.getAuthorVideoPage(page, query1);
break;
- case "collect":
+ case "collect": // 鍔犺浇瑙嗛涓婚〉鏀惰棌瑙嗛
AuthorVideoQuery query2 = new AuthorVideoQuery();
+ BeanUtils.copyProperties(query, query2);
query2.setAuthorId(query.getAuthorId());
baseMapper.getAuthorCollectVideoPage(page, query2);
break;
+ case "like": // 鍔犺浇瑙嗛涓婚〉鐐硅禐瑙嗛
+ AuthorVideoQuery query3 = new AuthorVideoQuery();
+ BeanUtils.copyProperties(query, query3);
+ query3.setAuthorId(query.getAuthorId());
+ baseMapper.getAuthorLikeVideoPage(page, query3);
+ break;
+ case "search": // 鍔犺浇es鎼滅储瑙嗛
+ VideoEsQuery query4 = new VideoEsQuery();
+ BeanUtils.copyProperties(query, query4);
+ query4.setPageNumber((int) query.getPageNumber());
+ query4.setPageSize((int) query.getPageSize());
+ return this.esSearch(query4);
default:
break;
}
@@ -385,23 +505,32 @@
Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds)
.stream()
.collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId));
- Map<String, List<SimpleMyCollectVO>> collectMap =myCollectService.getCollectsByVideoIds(videoIds)
+ Map<String, List<SimpleMyCollectVO>> collectMap = myCollectService.getCollectsByVideoIds(videoIds)
.stream()
.collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId));
+ Map<String, List<SimpleMyThumbsUpVO>> thumbsUpMap = thumbsUpRecordService.getThumbssByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyThumbsUpVO::getRefId));
List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId());
- // 3. 鑾峰彇瑙嗛涓存椂璁块棶鍦板潃銆佽缃棰戞爣绛俱�佹垜鏄惁鏀惰棌銆佷綔鑰呮槸鍚﹀叧娉�
+ // 3. 鑾峰彇瑙嗛涓存椂璁块棶鍦板潃銆佽缃棰戞爣绛俱�佹垜鏄惁鏀惰棌銆佹槸鍚︾偣璧炪�佷綔鑰呮槸鍚﹀叧娉�
page.getRecords().forEach(v -> {
v.setTagList(tagMap.get(v.getId()));
v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId())));
+ v.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(v.getId())));
v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum()));
v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum()));
+ v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum()));
if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
} else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
}
-
+ if (CollectionUtils.isNotEmpty(v.getGoodsList())) {
+ v.getGoodsList().stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
+ }
v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId()));
});
}
@@ -437,6 +566,23 @@
if (Objects.isNull(redisNum)) {
// redis涓病鏈夊氨鎶婃暟鎹簱鐨勫啓鍒皉edis涓�
cache.put(CachePrefix.VIDEO_COLLECT_NUM.getPrefixWithId(videoId), mysqlNum, RedisKeyExpireConstant.COLLECT_NUM_EXPIRE, RedisKeyExpireConstant.EXPIRE_DAY);
+ return mysqlNum;
+ }
+ return (Integer) redisNum;
+ }
+
+ /**
+ * 浠巖edis涓幏鍙栫偣璧炴暟閲忥紝濡傛灉redis涓病鏈夊垯灏唌ysql涓殑鏁伴噺鍐欏叆鍒皉edis
+ *
+ * @param videoId
+ * @param mysqlNum
+ * @return
+ */
+ private Integer getThumbsUpNum(String videoId, Integer mysqlNum) {
+ Object redisNum = cache.get(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(videoId));
+ if (Objects.isNull(redisNum)) {
+ // redis涓病鏈夊氨鎶婃暟鎹簱鐨勫啓鍒皉edis涓�
+ cache.put(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(videoId), mysqlNum, RedisKeyExpireConstant.VIDEO_THUMBS_UP_EXPIRE, RedisKeyExpireConstant.EXPIRE_DAY);
return mysqlNum;
}
return (Integer) redisNum;
@@ -482,28 +628,40 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void updateCollectNumBatch(List<CollectTypeNumVO> numList) {
- // 鎸�500鏉℃暟鎹繘琛屾媶鍒�
- List<List<CollectTypeNumVO>> chunks = ListUtils.partition(numList, 500);
+ // 鎸�200鏉℃暟鎹繘琛屾媶鍒�
+ List<List<CollectTypeNumVO>> chunks = ListUtils.partition(numList, 200);
for (List<CollectTypeNumVO> chunk : chunks) {
baseMapper.updateCollectNumBatch(chunk);
new LambdaUpdateChainWrapper<>(baseMapper)
.in(Video::getId, chunk.stream().map(CollectTypeNumVO::getId).collect(Collectors.toList()))
.set(Video::getCollectNumJob, Boolean.FALSE)
.update();
+ // 鏇存柊es鐨勬敹钘忔暟
+ for (CollectTypeNumVO vo : chunk) {
+ Map<String, Object> fields = new HashMap<>(1);
+ fields.put("collectNum", vo.getCountNum());
+ esService.updateSomeField(EsSuffix.VIDEO_INDEX_NAME, vo.getId(), fields);
+ }
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateCommentNumBatch(List<CollectTypeNumVO> numList) {
- // 鎸�500鏉℃暟鎹繘琛屾媶鍒�
- List<List<CollectTypeNumVO>> chunks = ListUtils.partition(numList, 500);
+ // 鎸�200鏉℃暟鎹繘琛屾媶鍒�
+ List<List<CollectTypeNumVO>> chunks = ListUtils.partition(numList, 200);
for (List<CollectTypeNumVO> chunk : chunks) {
baseMapper.updateCommentNumBatch(chunk);
new LambdaUpdateChainWrapper<>(baseMapper)
.in(Video::getId, chunk.stream().map(CollectTypeNumVO::getId).collect(Collectors.toList()))
.set(Video::getCommentNumJob, Boolean.FALSE)
.update();
+ // 鏇存柊es鐨勮瘎璁烘暟
+ for (CollectTypeNumVO vo : chunk) {
+ Map<String, Object> fields = new HashMap<>(1);
+ fields.put("commentNum", vo.getCountNum());
+ esService.updateSomeField(EsSuffix.VIDEO_INDEX_NAME, vo.getId(), fields);
+ }
}
}
@@ -538,16 +696,39 @@
IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
query.setAuthorSelf(UserContext.getCurrentUserId().equals(query.getAuthorId()));
baseMapper.getAuthorVideoPage(page, query);
- for (WxVideoVO vo : page.getRecords()) {
- if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) {
- vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
- vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
- } else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
- vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ List<String> videoIds = page.getRecords().stream().map(WxVideoVO::getId).collect(Collectors.toList());
+ Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId));
+ Map<String, List<SimpleMyCollectVO>> collectMap = myCollectService.getCollectsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId));
+ Map<String, List<SimpleMyThumbsUpVO>> thumbsUpMap = thumbsUpRecordService.getThumbssByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyThumbsUpVO::getRefId));
+ List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId());
+ if (CollectionUtils.isNotEmpty(page.getRecords())) {
+ for (WxVideoVO v : page.getRecords()) {
+ v.setTagList(tagMap.get(v.getId()));
+ v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId())));
+ v.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(v.getId())));
+ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum()));
+ v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum()));
+ v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum()));
+ if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
+ v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
+ v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
+ } else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
+ v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ }
+ v.setOptions(VideoSupportOpEnum.getVideoOpByStatus(v.getStatus()));
+ if (CollectionUtils.isNotEmpty(v.getGoodsList())) {
+ v.getGoodsList().stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
+ }
+ v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId()));
}
-
-
- vo.setOptions(VideoSupportOpEnum.getVideoOpByStatus(vo.getStatus()));
}
return Result.ok().data(page.getRecords()).total(page.getTotal());
}
@@ -556,14 +737,72 @@
public Result getAuthorCollectVideoPage(AuthorVideoQuery query) {
IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
baseMapper.getAuthorCollectVideoPage(page, query);
- for (WxVideoVO vo : page.getRecords()) {
- if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) {
- vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
- vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
- } else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
- vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ if (CollectionUtils.isNotEmpty(page.getRecords())) {
+ List<String> videoIds = page.getRecords().stream().map(WxVideoVO::getId).collect(Collectors.toList());
+ Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId));
+ Map<String, List<SimpleMyThumbsUpVO>> thumbsUpMap = thumbsUpRecordService.getThumbssByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyThumbsUpVO::getRefId));
+ List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId());
+ for (WxVideoVO v : page.getRecords()) {
+ v.setTagList(tagMap.get(v.getId()));
+ v.setCollected(Boolean.TRUE);
+ v.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(v.getId())));
+ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum()));
+ v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum()));
+ v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum()));
+ if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
+ v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
+ v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
+ } else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
+ v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ }
+ if (CollectionUtils.isNotEmpty(v.getGoodsList())) {
+ v.getGoodsList().stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
+ }
+ v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId()));
}
- vo.setCollected(Boolean.TRUE);
+ }
+ return Result.ok().data(page.getRecords()).total(page.getTotal());
+ }
+
+ @Override
+ public Result getAuthorLikeVideoPage(AuthorVideoQuery query) {
+ IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
+ baseMapper.getAuthorLikeVideoPage(page, query);
+ if (CollectionUtils.isNotEmpty(page.getRecords())) {
+ List<String> videoIds = page.getRecords().stream().map(WxVideoVO::getId).collect(Collectors.toList());
+ Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId));
+ Map<String, List<SimpleMyCollectVO>> collectMap = myCollectService.getCollectsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId));
+ List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId());
+ for (WxVideoVO v : page.getRecords()) {
+ v.setTagList(tagMap.get(v.getId()));
+ v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId())));
+ v.setThumbsUp(Boolean.TRUE);
+ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum()));
+ v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum()));
+ v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum()));
+ if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
+ v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
+ v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
+ } else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
+ v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ }
+ if (CollectionUtils.isNotEmpty(v.getGoodsList())) {
+ v.getGoodsList().stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
+ }
+ v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId()));
+ }
}
return Result.ok().data(page.getRecords()).total(page.getTotal());
}
@@ -571,6 +810,9 @@
@Override
public Result getGoodsDetail(String videoId) {
List<VideoGoodsDetailVO> goodsList = baseMapper.getVideoGoods(videoId);
+ goodsList.stream().forEach(goods -> {
+ goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail()));
+ });
return Result.ok().data(goodsList);
}
@@ -621,7 +863,7 @@
video.setAuthorId(UserContext.getCurrentUserId());
video.setVideoType(VideoTypeEnum.HEALTH.getValue());
//璁剧疆濉厖妯″紡 淇濇寔姣斾緥锛屽畬鏁存樉绀�
- video.setVideoFit("contain");
+ video.setVideoFit(form.getVideoFit());
video.setVideoContentType(VideoContentTypeEnum.VIDEO.getValue());
video.setStatus(VideoStatusEnum.PUBLISHED.getValue());
baseMapper.insert(video);
@@ -678,7 +920,7 @@
video.setAuthorId(UserContext.getCurrentUserId());
video.setVideoType(VideoTypeEnum.COOK.getValue());
//璁剧疆濉厖妯″紡 淇濇寔姣斾緥锛屽畬鏁存樉绀�
- video.setVideoFit("contain");
+ video.setVideoFit(form.getVideoFit());
video.setVideoContentType(VideoContentTypeEnum.VIDEO.getValue());
video.setStatus(VideoStatusEnum.PUBLISHED.getValue());
baseMapper.insert(video);
@@ -802,4 +1044,170 @@
.update();
}
}
+
+ @Override
+ public Result recreateEsIndex() {
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_RECREATE.name();
+ // 娑堟伅浣撲笉鑳戒负绌猴紝闅忎究浼犱竴涓�1
+ rocketMQTemplate.asyncSend(destination, "1", RocketmqSendCallbackBuilder.commonCallback());
+ return Result.ok("宸叉垚鍔熷彂璧锋瀯寤鸿姹傦紝绋嶄綔绛夊緟鍚庝究浼氳嚜鍔ㄥ畬鎴�");
+ }
+
+
+ @Override
+ public Result changeThumbsUp(ThumbsUpRecordForm form) {
+ // mq寮傛澶勭悊
+ ThumbsUpRecord thumbsUp = new ThumbsUpRecord();
+ thumbsUp.setRefId(form.getRefId());
+ thumbsUp.setThumbsUpType(ThumbsUpTypeEnum.VIDEO.getValue());
+ thumbsUp.setUserId(UserContext.getCurrentUserId());
+ String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.THUMBS_UP.name();
+ rocketMQTemplate.asyncSend(destination, JSON.toJSONString(thumbsUp), RocketmqSendCallbackBuilder.commonCallback());
+ return Result.ok();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void mqChangeThumbsUp(ThumbsUpRecord thumbsUpRecord) {
+ ThumbsUpRecord exists = new LambdaQueryChainWrapper<>(thumbsUpRecordService.getBaseMapper())
+ .eq(ThumbsUpRecord::getUserId, thumbsUpRecord.getUserId())
+ .eq(ThumbsUpRecord::getRefId, thumbsUpRecord.getRefId())
+ .eq(ThumbsUpRecord::getThumbsUpType, thumbsUpRecord.getThumbsUpType())
+ .one();
+ boolean add = false;
+ if (Objects.nonNull(exists)) {
+ // 鍙栨秷鐐硅禐
+ thumbsUpRecordService.removeById(exists.getId());
+ } else {
+ // 鐐硅禐
+ thumbsUpRecordService.save(thumbsUpRecord);
+ add = true;
+ }
+ // 澶勭悊缂撳瓨
+ Video video = baseMapper.selectById(thumbsUpRecord.getRefId());
+ if (cache.exist(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(thumbsUpRecord.getRefId()))) {
+ if (add) {
+ cache.incr(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(thumbsUpRecord.getRefId()));
+ } else {
+ cache.decr(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(thumbsUpRecord.getRefId()));
+ }
+ } else {
+ if (Objects.nonNull(video)) {
+ cache.put(CachePrefix.VIDEO_THUMBS_UP_NUM.getPrefixWithId(video.getId()),
+ video.getThumbsUpNum() + (add ? 1 : -1),
+ RedisKeyExpireConstant.VIDEO_THUMBS_UP_EXPIRE,
+ RedisKeyExpireConstant.EXPIRE_DAY);
+ }
+ }
+ // 鏍囪瘑璇ヨ棰戦渶瑕侀�氳繃瀹氭椂浠诲姟缁熻鏀惰棌鏁�
+ if (Objects.nonNull(video) && ! video.getCollectNumJob()) {
+ new LambdaUpdateChainWrapper<>(baseMapper)
+ .eq(Video::getId, video.getId())
+ .set(Video::getThumbsUpNumJob, Boolean.TRUE)
+ .update();
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateThumbsUpNumBatch(List<CollectTypeNumVO> numList) {
+ // 鎸�200鏉℃暟鎹繘琛屾媶鍒�
+ List<List<CollectTypeNumVO>> chunks = ListUtils.partition(numList, 200);
+ for (List<CollectTypeNumVO> chunk : chunks) {
+ baseMapper.updateThumbsUpNumBatch(chunk);
+ new LambdaUpdateChainWrapper<>(baseMapper)
+ .in(Video::getId, chunk.stream().map(CollectTypeNumVO::getId).collect(Collectors.toList()))
+ .set(Video::getThumbsUpNumJob, Boolean.FALSE)
+ .update();
+ // 鏇存柊es鐨勭偣璧炴暟
+ for (CollectTypeNumVO vo : chunk) {
+ Map<String, Object> fields = new HashMap<>(1);
+ fields.put("thumbsUpNum", vo.getCountNum());
+ esService.updateSomeField(EsSuffix.VIDEO_INDEX_NAME, vo.getId(), fields);
+ }
+ }
+ }
+
+ @Override
+ public Result esSearch(VideoEsQuery q) {
+ // 鍒ゆ柇鍟嗗搧绱㈠紩鏄惁瀛樺湪
+ if (!restTemplate.indexOps(VideoIndex.class).exists()) {
+ return Result.ok();
+ }
+ q.setPageNumber(q.getPageNumber() - 1); // 鍓嶇淇濇寔缁熶竴浠庣涓�椤靛紑濮嬶紝浣嗘槸es浠�0椤靛紑濮嬶紝鎵�浠ュ噺涓�
+ // 鏍规嵁鐐硅禐鏁版帓搴�
+ Pageable pageable = PageRequest.of(q.getPageNumber(), q.getPageSize(), Sort.by(Sort.Direction.DESC, "thumbsUpNum"));
+
+ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
+ queryBuilder.withPageable(pageable);
+
+ if (StringUtils.isNotBlank(q.getKeyword())) {
+ // 1. 鏋勫缓涓诲竷灏旀煡璇�
+ BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
+
+ // 2. 娣诲姞鏍囬鍖归厤锛堥潪宓屽瀛楁锛�
+ boolQuery.should(QueryBuilders.matchQuery("title", q.getKeyword()));
+
+ // 3. 娣诲姞宓屽鏍囩鍖归厤
+ NestedQueryBuilder tagQuery = QueryBuilders.nestedQuery(
+ "tagList",
+ QueryBuilders.matchQuery("tagList.tagName", q.getKeyword()),
+ ScoreMode.Total // 浣跨敤鎬诲垎妯″紡
+ );
+ boolQuery.should(tagQuery);
+
+ // 4. 娣诲姞宓屽鍟嗗搧鍖归厤
+ NestedQueryBuilder goodsQuery = QueryBuilders.nestedQuery(
+ "goodsList",
+ QueryBuilders.matchQuery("goodsList.goodsName", q.getKeyword()),
+ ScoreMode.Total
+ );
+ boolQuery.should(goodsQuery);
+
+ // 5. 璁剧疆鑷冲皯鍖归厤涓�涓潯浠讹紙OR閫昏緫锛�
+ boolQuery.minimumShouldMatch(1);
+
+ // 6. 鐘舵�佷负宸插彂甯冪殑
+ boolQuery.must(QueryBuilders.termQuery("status", VideoStatusEnum.PUBLISHED.getValue()));
+ queryBuilder.withQuery(boolQuery);
+ } else {
+ return Result.ok().data(new ArrayList<>()).total(0);
+ }
+ NativeSearchQuery query = queryBuilder.build();
+ SearchHits<VideoIndex> searchHits = restTemplate.search(query, VideoIndex.class);
+ if (CollectionUtils.isEmpty(searchHits.getSearchHits())) {
+ return Result.ok().data(new ArrayList<>()).total(0);
+ }
+ List<VideoIndex> data = searchHits.stream().map(hit -> hit.getContent()).collect(Collectors.toList());
+ List<String> videoIds = data.stream().map(VideoIndex::getId).collect(Collectors.toList());
+ // 瀵硅薄杞崲
+ Map<String, List<SimpleMyCollectVO>> collectMap = myCollectService.getCollectsByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId));
+ Map<String, List<SimpleMyThumbsUpVO>> thumbsUpMap = thumbsUpRecordService.getThumbssByVideoIds(videoIds)
+ .stream()
+ .collect(Collectors.groupingBy(SimpleMyThumbsUpVO::getRefId));
+ List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId());
+ List<WxVideoVO> vos = data.stream().map(videoIndex -> {
+ WxVideoVO wxVideoVO = new WxVideoVO();
+ BeanUtils.copyProperties(videoIndex, wxVideoVO);
+ // 鍒ゆ柇鏄惁鍏虫敞浣滆�呫�佹槸鍚︾偣璧炪�佹槸鍚︽敹钘�
+ wxVideoVO.setCollected(CollectionUtils.isNotEmpty(collectMap.get(wxVideoVO.getId())));
+ wxVideoVO.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(wxVideoVO.getId())));
+ if (UserContext.getCurrentUserId().equals(wxVideoVO.getAuthorId())) {
+ wxVideoVO.setSubscribeThisAuthor(Boolean.TRUE);
+ } else {
+ wxVideoVO.setSubscribeThisAuthor(subscribes.contains(wxVideoVO.getAuthorId()));
+ }
+ if (VideoContentTypeEnum.VIDEO.getValue().equals(wxVideoVO.getVideoContentType())) {
+ wxVideoVO.setCoverUrl(cosUtil.getPreviewUrl(wxVideoVO.getCoverFileKey()));
+ wxVideoVO.setVideoUrl(cosUtil.getPreviewUrl(wxVideoVO.getVideoFileKey()));
+ } else if (VideoContentTypeEnum.IMG.getValue().equals(wxVideoVO.getVideoContentType()) && StringUtils.isNotBlank(wxVideoVO.getVideoImgs())) {
+ wxVideoVO.setImgs(JSON.parseArray(wxVideoVO.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
+ wxVideoVO.setCoverUrl(wxVideoVO.getImgs().get(0));
+ }
+ return wxVideoVO;
+ }).collect(Collectors.toList());
+ return Result.ok().data(vos).total(searchHits.getTotalHits());
+ }
}
diff --git a/framework/src/main/java/cn/lili/modules/search/repository/EsVideoIndexRepository.java b/framework/src/main/java/cn/lili/modules/search/repository/EsVideoIndexRepository.java
new file mode 100644
index 0000000..1819a0d
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/search/repository/EsVideoIndexRepository.java
@@ -0,0 +1,15 @@
+package cn.lili.modules.search.repository;
+
+import cn.lili.modules.lmk.domain.es.VideoIndex;
+import cn.lili.modules.search.entity.dos.EsGoodsIndex;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+
+/**
+ * 瑙嗛绱㈠紩
+ *
+ * @author paulG
+ * @since 2020/10/15
+ **/
+public interface EsVideoIndexRepository extends ElasticsearchRepository<VideoIndex, String> {
+
+}
diff --git a/framework/src/main/java/cn/lili/rocketmq/tags/VideoTagsEnum.java b/framework/src/main/java/cn/lili/rocketmq/tags/VideoTagsEnum.java
index 03b5ea1..4b8ab2a 100644
--- a/framework/src/main/java/cn/lili/rocketmq/tags/VideoTagsEnum.java
+++ b/framework/src/main/java/cn/lili/rocketmq/tags/VideoTagsEnum.java
@@ -12,6 +12,11 @@
* 鏀惰棌
*/
COLLECT("鏀惰棌"),
+ THUMBS_UP("鐐硅禐"),
+ ES_RECREATE("閲嶅缓瑙嗛绱㈠紩"),
+ ES_DOC_ADD_OR_UPDATE("鏂板鎴栧叏閲忎慨鏀硅棰�"),
+ ES_DOC_UPDATE_SOME_FIELD("淇敼瑙嗛鏌愪簺瀛楁"),
+ ES_DOC_DEL("鍒犻櫎瑙嗛"),
;
diff --git a/framework/src/main/resources/es/video.json b/framework/src/main/resources/es/video.json
new file mode 100644
index 0000000..ca5a219
--- /dev/null
+++ b/framework/src/main/resources/es/video.json
@@ -0,0 +1,53 @@
+{
+ "properties": {
+ "id": {"type": "keyword"},
+ "title": {
+ "type": "text",
+ "analyzer": "ik_max_word"
+ },
+ "authorId": {"type": "keyword"},
+ "authorName": {
+ "type": "text",
+ "analyzer": "ik_max_word"
+ },
+ "authorAvatar": {"type": "keyword"},
+ "publishTime": {"type": "date"},
+ "recommend": {"type": "boolean"},
+ "collectNum": {"type": "integer"},
+ "thumbsUpNum": {"type": "integer"},
+ "commentNum": {"type": "integer"},
+ "coverFileKey": {"type": "keyword"},
+ "videoFileKey": {"type": "keyword"},
+ "videoContentType": {"type": "keyword"},
+ "videoType": {"type": "keyword"},
+ "videoImgs": {"type": "keyword"},
+ "tagList": {
+ "type": "nested",
+ "properties": {
+ "id": {"type": "keyword"},
+ "videoId": {"type": "keyword"},
+ "tagName": {
+ "type": "text",
+ "analyzer": "ik_max_word"
+ }
+ }
+ },
+ "videoDuration": {"type": "keyword"},
+ "videoFit": {"type": "keyword"},
+ "status": {"type": "keyword"},
+ "goodsList": {
+ "type": "nested",
+ "properties": {
+ "id": {"type": "keyword"},
+ "goodsId": {"type": "keyword"},
+ "price": {"type": "keyword"},
+ "thumbnail": {"type": "keyword"},
+ "goodsNum": {"type": "keyword"},
+ "goodsName": {
+ "type": "text",
+ "analyzer": "ik_max_word"
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/main/resources/mapper/lmk/ThumbsUpRecordMapper.xml b/framework/src/main/resources/mapper/lmk/ThumbsUpRecordMapper.xml
index a0a28e7..48008b4 100644
--- a/framework/src/main/resources/mapper/lmk/ThumbsUpRecordMapper.xml
+++ b/framework/src/main/resources/mapper/lmk/ThumbsUpRecordMapper.xml
@@ -56,4 +56,31 @@
LTUR.ref_id
</select>
+ <select id="countNumGroupByVideo" resultType="cn.lili.modules.lmk.domain.vo.CollectTypeNumVO">
+ SELECT
+ LV.id as id,
+ count(LTUR.ref_id) as countNum
+ FROM
+ lmk_video LV
+ LEFT JOIN lmk_thumbs_up_record LTUR ON LTUR.ref_id = LV.id AND LTUR.thumbs_up_type = 'video' AND LTUR.delete_flag = 0
+ WHERE
+ LV.thumbs_up_num_job = 1
+ AND LV.delete_flag = 0
+ GROUP BY
+ LTUR.ref_id
+ </select>
+
+ <select id="getThumbssByVideoIds" resultType="cn.lili.modules.lmk.domain.vo.SimpleMyThumbsUpVO">
+ SELECT
+ id,
+ ref_id as refId
+ FROM
+ lmk_thumbs_up_record
+ WHERE
+ user_id = #{userId}
+ AND delete_flag = 0
+ AND thumbs_up_type = 'video'
+ AND ref_id IN <foreach collection="videoIds" open="(" item="videoId" close=")" separator=",">#{videoId}</foreach>
+ </select>
+
</mapper>
diff --git a/framework/src/main/resources/mapper/lmk/VideoMapper.xml b/framework/src/main/resources/mapper/lmk/VideoMapper.xml
index 26809d9..eb193ad 100644
--- a/framework/src/main/resources/mapper/lmk/VideoMapper.xml
+++ b/framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -17,6 +17,7 @@
<result column="play_num" property="playNum" />
<result column="collect_num" property="collectNum" />
<result column="comment_num" property="commentNum" />
+ <result column="thumbs_up_num" property="thumbsUpNum" />
<result column="weight" property="weight" />
<result column="audit_pass_time" property="auditPassTime" />
<result column="update_time" property="updateTime" />
@@ -71,6 +72,7 @@
<result column="play_num" property="playNum" />
<result column="collect_num" property="collectNum" />
<result column="comment_num" property="commentNum" />
+ <result column="thumbs_up_num" property="thumbsUpNum" />
<result column="weight" property="weight" />
<result column="audit_pass_time" property="auditPassTime" />
<result column="update_time" property="updateTime" />
@@ -92,6 +94,7 @@
<result column="title" property="title" />
<result column="collect_num" property="collectNum" />
<result column="comment_num" property="commentNum" />
+ <result column="thumbs_up_num" property="thumbsUpNum" />
<result column="status" property="status" />
<result column="video_content_type" property="videoContentType" />
<result column="video_type" property="videoType" />
@@ -115,6 +118,7 @@
LV.play_num,
LV.collect_num,
LV.comment_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -146,6 +150,7 @@
LV.play_num,
LV.collect_num,
LV.comment_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -177,6 +182,7 @@
LV.play_num,
LV.collect_num,
LV.comment_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -219,6 +225,7 @@
LV.play_num,
LV.comment_num,
LV.collect_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -252,6 +259,7 @@
LV.play_num,
LV.comment_num,
LV.collect_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -284,6 +292,7 @@
LV.play_num,
LV.comment_num,
LV.collect_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -327,6 +336,20 @@
WHEN #{video.id} THEN #{video.countNum}
</foreach>
ELSE comment_num
+ END
+ WHERE id IN
+ <foreach collection="list" item="video" open="(" separator="," close=")">
+ #{video.id}
+ </foreach>
+ </update>
+
+ <update id="updateThumbsUpNumBatch">
+ UPDATE lmk_video
+ SET thumbs_up_num = CASE id
+ <foreach collection="list" item="video">
+ WHEN #{video.id} THEN #{video.countNum}
+ </foreach>
+ ELSE thumbs_up_num
END
WHERE id IN
<foreach collection="list" item="video" open="(" separator="," close=")">
@@ -379,6 +402,7 @@
LV.play_num,
LV.comment_num,
LV.collect_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -417,6 +441,7 @@
LV.play_num,
LV.comment_num,
LV.collect_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -432,6 +457,41 @@
LEFT JOIN li_member LM ON LV.author_id = LM.id
WHERE
LMC.delete_flag = 0 AND LMC.user_id = #{query.authorId} AND LMC.collect_type = 'video' AND LV.video_type = #{query.videoType}
+ ORDER BY
+ LMC.create_time DESC
+ </select>
+
+ <select id="getAuthorLikeVideoPage" resultMap="WxResultMap">
+ SELECT
+ LV.author_id,
+ LV.cover_url,
+ LV.video_fit,
+ LV.video_duration,
+ LV.video_file_key,
+ LV.title,
+ LV.goods_view_num,
+ LV.goods_order_num,
+ LV.recommend,
+ LV.status,
+ LV.play_num,
+ LV.comment_num,
+ LV.collect_num,
+ LV.thumbs_up_num,
+ LV.weight,
+ LV.audit_pass_time,
+ LV.update_time,
+ LV.video_content_type,
+ LV.video_type,
+ LV.video_imgs,
+ LV.id,
+ LM.nick_name as authorName,
+ LM.face as authorAvatar
+ FROM
+ lmk_thumbs_up_record LMC
+ INNER JOIN lmk_video LV ON LMC.ref_id = LV.id AND LV.delete_flag = 0 AND LV.status = '1'
+ LEFT JOIN li_member LM ON LV.author_id = LM.id
+ WHERE
+ LMC.delete_flag = 0 AND LMC.user_id = #{query.authorId} AND LMC.thumbs_up_type = 'video' AND LV.video_type = #{query.videoType}
ORDER BY
LMC.create_time DESC
</select>
@@ -480,6 +540,7 @@
LV.play_num,
LV.collect_num,
LV.comment_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -521,6 +582,7 @@
LV.play_num,
LV.collect_num,
LV.comment_num,
+ LV.thumbs_up_num,
LV.weight,
LV.audit_pass_time,
LV.update_time,
@@ -651,4 +713,84 @@
LFP.member_id
</select>
+
+ <resultMap id="EsResultMap" type="cn.lili.modules.lmk.domain.es.VideoIndex">
+ <id column="id" property="id"/>
+ <result column="author_id" property="authorId" />
+ <result column="authorName" property="authorName" />
+ <result column="authorAvatar" property="authorAvatar" />
+ <result column="cover_url" property="coverFileKey" />
+ <result column="video_file_key" property="videoFileKey" />
+ <result column="video_fit" property="videoFit" />
+ <result column="video_duration" property="videoDuration" />
+ <result column="title" property="title" />
+ <result column="status" property="status" />
+ <result column="recommend" property="recommend" />
+ <result column="audit_pass_time" property="publishTime" />
+ <result column="video_content_type" property="videoContentType" />
+ <result column="video_type" property="videoType" />
+ <result column="video_imgs" property="videoImgs" />
+ <result column="collect_num" property="collectNum" />
+ <result column="thumbs_up_num" property="thumbsUpNum" />
+ <result column="comment_num" property="commentNum" />
+ <collection property="goodsList" column="id" select="getVideoGoods" ofType="cn.lili.modules.lmk.domain.vo.VideoGoodsDetailVO"/>
+ <collection property="tagList" column="id" select="getVideoTags" ofType="cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO"/>
+ </resultMap>
+
+ <select id="getVideoTags" resultType="cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO">
+ SELECT
+ LVT.id,
+ LVT.tag_name as tagName
+ FROM
+ lmk_video_tag_ref LVTR
+ INNER JOIN lmk_video_tag LVT ON LVTR.video_tag_id = LVT.id AND LVT.delete_flag = 0
+ WHERE
+ LVTR.video_id = #{id}
+ </select>
+
+ <select id="getEsPage" parameterType="int" resultMap="EsResultMap">
+ SELECT
+ LV.author_id,
+ LV.cover_url,
+ LV.video_fit,
+ LV.video_duration,
+ LV.video_file_key,
+ LV.title,
+ LV.goods_view_num,
+ LV.goods_order_num,
+ LV.recommend,
+ LV.status,
+ LV.play_num,
+ LV.comment_num,
+ LV.collect_num,
+ LV.thumbs_up_num,
+ LV.weight,
+ CASE
+ WHEN LV.audit_pass_time IS NOT NULL THEN LV.audit_pass_time
+ ELSE LV.create_time
+ END as audit_pass_time,
+ LV.update_time,
+ LV.create_time,
+ LV.video_content_type,
+ LV.video_type,
+ LV.video_imgs,
+ LV.id,
+ CASE
+ WHEN LM.nick_name IS NOT NULL THEN LM.nick_name
+ WHEN LM.nick_name IS NULL THEN (SELECT nick_name FROM li_admin_user WHERE id = LV.author_id)
+ ELSE ''
+ END as authorName,
+ CASE
+ WHEN LM.face IS NOT NULL THEN LM.face
+ WHEN LM.face IS NULL THEN (SELECT avatar FROM li_admin_user WHERE id = LV.author_id)
+ ELSE ''
+ END as authorAvatar
+ FROM
+ lmk_video LV
+ LEFT JOIN li_member LM ON LV.author_id = LM.id
+ WHERE
+ LV.delete_flag = 0
+ LIMIT #{start}, #{pageSize}
+ </select>
+
</mapper>
diff --git a/lmk-job/src/main/java/cn/lili/job/VideoJob.java b/lmk-job/src/main/java/cn/lili/job/VideoJob.java
index 15035f1..e2df6d1 100644
--- a/lmk-job/src/main/java/cn/lili/job/VideoJob.java
+++ b/lmk-job/src/main/java/cn/lili/job/VideoJob.java
@@ -72,4 +72,19 @@
}
}
+ /**
+ * 瑙嗛鐐硅禐鏁扮粺璁�
+ *
+ * @throws Exception
+ */
+ @XxlJob("videoThumbsUpNumJob")
+ public void videoThumbsUpNumJob() throws Exception {
+ XxlJobHelper.log("寮�濮嬫墽琛岋細瑙嗛鐐硅禐鏁扮粺璁�");
+
+ List<CollectTypeNumVO> numList = thumbsUpRecordService.countNumGroupByVideo();
+ if (CollectionUtils.isNotEmpty(numList)) {
+ videoService.updateThumbsUpNumBatch(numList);
+ }
+ }
+
}
diff --git a/manager-api/src/main/java/cn/lili/controller/lmk/VideoController.java b/manager-api/src/main/java/cn/lili/controller/lmk/VideoController.java
index b496f0d..364f2cd 100644
--- a/manager-api/src/main/java/cn/lili/controller/lmk/VideoController.java
+++ b/manager-api/src/main/java/cn/lili/controller/lmk/VideoController.java
@@ -1,5 +1,6 @@
package cn.lili.controller.lmk;
+import cn.lili.elasticsearch.EsSuffix;
import cn.lili.group.Update;
import cn.lili.group.Add;
import cn.lili.modules.lmk.domain.form.VideoAuditingForm;
@@ -7,6 +8,8 @@
import cn.lili.modules.lmk.domain.form.VideoRecommendForm;
import cn.lili.modules.lmk.domain.form.WxVideoForm;
import cn.lili.modules.lmk.domain.query.ManagerVideoQuery;
+import cn.lili.modules.lmk.service.EsService;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.annotation.Validated;
import lombok.RequiredArgsConstructor;
import java.util.List;
@@ -32,17 +35,8 @@
private final VideoService videoService;
- @PostMapping
- @ApiOperation(value = "娣诲姞", notes = "娣诲姞")
- public Result add(@RequestBody @Validated(Add.class) WxVideoForm form) {
- return videoService.add(form);
- }
-
- @PutMapping
- @ApiOperation(value = "淇敼", notes = "淇敼")
- public Result update(@RequestBody @Validated(Update.class) WxVideoForm form) {
- return videoService.update(form);
- }
+ @Qualifier("videoEsServiceImpl")
+ private final EsService esService;
@DeleteMapping("/{id}")
@ApiOperation(value = "ID鍒犻櫎", notes = "ID鍒犻櫎")
@@ -97,4 +91,10 @@
public Result down(@RequestBody @Validated VideoDownForm form) {
return videoService.down(form);
}
+
+ @PostMapping("/recreate/es/index")
+ @ApiOperation(value = "閲嶅缓es绱㈠紩", notes = "閲嶅缓es绱㈠紩")
+ public Result recreateEsIndex() {
+ return videoService.recreateEsIndex();
+ }
}
--
Gitblit v1.8.0