You've already forked FrameTour-BE
1
This commit is contained in:
@ -40,6 +40,13 @@ public class AppGoodsController {
|
||||
return ApiResponse.success(goodsDetailVOS);
|
||||
}
|
||||
|
||||
@ApiOperation("源素材(原片/照片)商品数量")
|
||||
@PostMapping("/sourceGoodsCount")
|
||||
public ApiResponse<Integer> sourceGoodsCount(@RequestBody GoodsReqQuery query) {
|
||||
Integer count = goodsService.sourceGoodsCount(query);
|
||||
return ApiResponse.success(count);
|
||||
}
|
||||
|
||||
@PostMapping("/sourceGoodsList/preview")
|
||||
public ApiResponse<List<GoodsUrlVO>> sourceGoodsListPreview(@RequestBody GoodsReqQuery query) {
|
||||
List<GoodsUrlVO> goodsUrlList = goodsService.sourceGoodsListPreview(query);
|
||||
|
@ -97,8 +97,8 @@ public class ViidController {
|
||||
.setNamePrefix("VIID-" + scenicId + "-t")
|
||||
.build();
|
||||
return new ThreadPoolExecutor(
|
||||
4, 4096, 0L, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(4096),
|
||||
4, 1024, 0L, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(1024),
|
||||
threadFactory);
|
||||
});
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ public class AliFaceBodyAdapter implements IFaceBodyAdapter {
|
||||
IRateLimiter deleteEntityLimiter = getLimiter(LOCK_TYPE.DELETE_ENTITY);
|
||||
IRateLimiter deleteDbLimiter = getLimiter(LOCK_TYPE.DELETE_DB);
|
||||
request.setDbName(dbName);
|
||||
request.setOrder("asc");
|
||||
request.setLimit(200);
|
||||
try (ClientWrapper clientWrapper = getClient()) {
|
||||
IAcsClient client = clientWrapper.getClient();
|
||||
|
@ -51,6 +51,7 @@ public interface SourceMapper {
|
||||
int addRelation(MemberSourceEntity source);
|
||||
|
||||
List<SourceRespVO> listUser(SourceReqQuery sourceReqQuery);
|
||||
Integer countUser(SourceReqQuery sourceReqQuery);
|
||||
SourceRespVO listUserOne(Long userId, Long sourceId);
|
||||
|
||||
int addRelations(List<MemberSourceEntity> list);
|
||||
|
@ -91,4 +91,6 @@ public class ScenicConfigEntity {
|
||||
|
||||
private String imageSourcePackHint;
|
||||
private String videoSourcePackHint;
|
||||
|
||||
private String extraNotificationTime;
|
||||
}
|
||||
|
@ -45,6 +45,6 @@ public class SourceRespVO {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
@ApiModelProperty("是否购买:0未购买,1已购买")
|
||||
private Integer isBuy;
|
||||
private Integer isFree;
|
||||
private int isBuy;
|
||||
private int isFree;
|
||||
}
|
||||
|
@ -48,4 +48,6 @@ public interface GoodsService {
|
||||
List<GoodsUrlVO> sourceGoodsListPreview(GoodsReqQuery query);
|
||||
|
||||
List<GoodsUrlVO> sourceGoodsListDownload(GoodsReqQuery query);
|
||||
|
||||
Integer sourceGoodsCount(GoodsReqQuery query);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ycwl.basic.biz.OrderBiz;
|
||||
import com.ycwl.basic.biz.TaskStatusBiz;
|
||||
@ -199,6 +200,8 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
goodsDetailVO.setScenicName(sourceRespVO.getScenicName());
|
||||
goodsDetailVO.setGoodsType(sourceType);
|
||||
goodsDetailVO.setGoodsId(sourceRespVO.getId());
|
||||
goodsDetailVO.setIsFree(sourceRespVO.getIsFree());
|
||||
goodsDetailVO.setIsBuy(sourceRespVO.getIsBuy());
|
||||
if (sourceRespVO.getVideoUrl() != null) {
|
||||
try {
|
||||
URL url = new URL(sourceRespVO.getVideoUrl());
|
||||
@ -278,10 +281,15 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
paramJson.entrySet().stream()
|
||||
.filter(entry -> StringUtils.isNumeric(entry.getKey()))
|
||||
.forEach(entry -> {
|
||||
JSONArray jsonArray = paramJson.getJSONArray(entry.getKey());
|
||||
if (jsonArray != null && !jsonArray.isEmpty()) {
|
||||
for (Object ignored : jsonArray) {
|
||||
if (templatePlaceholder.contains(entry.getKey())) {
|
||||
deviceCount.getAndIncrement();
|
||||
templatePlaceholder.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
goodsDetailVO.setLensNum(deviceCount.get());
|
||||
@ -573,14 +581,9 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
if (face == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), query.getScenicId(), query.getSourceType(), query.getFaceId());
|
||||
if (!isBuy.isBuy()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Integer sourceType = query.getSourceType();
|
||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||
sourceReqQuery.setScenicId(query.getScenicId());
|
||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||
sourceReqQuery.setScenicId(face.getScenicId());
|
||||
sourceReqQuery.setMemberId(face.getMemberId());
|
||||
sourceReqQuery.setType(sourceType);
|
||||
sourceReqQuery.setFaceId(query.getFaceId());
|
||||
@ -598,6 +601,21 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
return goodsUrlVO;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
long count = list.stream().filter((item) -> {
|
||||
if (item.getIsFree() > 0) {
|
||||
return false;
|
||||
}
|
||||
if (item.getIsBuy() > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}).count();
|
||||
if (count > 0) {
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), query.getScenicId(), query.getSourceType(), query.getFaceId());
|
||||
if (!isBuy.isBuy()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
List<GoodsUrlVO> defaultUrlList = list.stream().map(source -> {
|
||||
GoodsUrlVO goodsUrlVO = new GoodsUrlVO();
|
||||
goodsUrlVO.setGoodsType(source.getType());
|
||||
@ -678,4 +696,20 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
}
|
||||
return defaultUrlList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer sourceGoodsCount(GoodsReqQuery query) {
|
||||
FaceEntity face = faceRepository.getFace(query.getFaceId());
|
||||
if (face == null) {
|
||||
return 0;
|
||||
}
|
||||
Integer sourceType = query.getSourceType();
|
||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||
sourceReqQuery.setScenicId(query.getScenicId());
|
||||
sourceReqQuery.setIsBuy(query.getIsBuy());
|
||||
sourceReqQuery.setMemberId(face.getMemberId());
|
||||
sourceReqQuery.setType(sourceType);
|
||||
sourceReqQuery.setFaceId(query.getFaceId());
|
||||
return sourceMapper.countUser(sourceReqQuery);
|
||||
}
|
||||
}
|
||||
|
@ -202,14 +202,11 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
||||
SearchFaceRespVo respVo = new SearchFaceRespVo();
|
||||
List<SearchFaceResultItem> records = response.getResult();
|
||||
respVo.setScore(response.getOriginalFaceScore());
|
||||
if (records.isEmpty()) {
|
||||
return respVo;
|
||||
}
|
||||
respVo.setSearchResultJson(JSON.toJSONString(records));
|
||||
logEntity.setMatchRawRecord(records);
|
||||
if (records.isEmpty()) {
|
||||
return respVo;
|
||||
}
|
||||
logEntity.setMatchRawRecord(records);
|
||||
acceptFaceSampleIds = records.stream()
|
||||
.filter(record -> record.getScore() > _threshold)
|
||||
.map(SearchFaceResultItem::getExtData)
|
||||
@ -268,12 +265,12 @@ public class TaskFaceServiceImpl implements TaskFaceService {
|
||||
record.setMatched(item.getScore() > _threshold);
|
||||
collect.add(record);
|
||||
}
|
||||
logEntity.setMatchLocalRecord(JSONObject.toJSONString(collect));
|
||||
if (acceptFaceSampleIds.isEmpty()) {
|
||||
respVo.setFirstMatchRate(0f);
|
||||
respVo.setSampleListIds(Collections.emptyList());
|
||||
return respVo;
|
||||
}
|
||||
logEntity.setMatchLocalRecord(JSONObject.toJSONString(collect));
|
||||
respVo.setFirstMatchRate(response.getFirstMatchRate());
|
||||
respVo.setSampleListIds(acceptFaceSampleIds);
|
||||
return respVo;
|
||||
|
@ -45,7 +45,6 @@ import com.ycwl.basic.notify.entity.NotifyContent;
|
||||
import com.ycwl.basic.notify.enums.NotifyType;
|
||||
import com.ycwl.basic.repository.DeviceRepository;
|
||||
import com.ycwl.basic.repository.FaceRepository;
|
||||
import com.ycwl.basic.repository.OrderRepository;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.repository.VideoRepository;
|
||||
import com.ycwl.basic.repository.VideoTaskRepository;
|
||||
@ -74,10 +73,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
@ -603,7 +599,7 @@ public class TaskTaskServiceImpl implements TaskService {
|
||||
IStorageAdapter adapter = scenicService.getScenicTmpStorageAdapter(task.getScenicId());
|
||||
String filename = StorageUtil.joinPath(StorageConstant.VLOG_PATH, task.getId() + "_" + task.getScenicId() + ".mp4");
|
||||
adapter.setAcl(StorageAcl.PUBLIC_READ, filename);
|
||||
videoReUploader.addVideoTask(task.getVideoUrl(), video.getId());
|
||||
videoReUploader.addVideoTask(video.getId());
|
||||
int isBuy = 0;
|
||||
FaceEntity face = faceRepository.getFace(task.getFaceId());
|
||||
if (face != null) {
|
||||
|
@ -150,6 +150,7 @@ final public class AliOssAdapter extends AStorageAdapter {
|
||||
object.setPath(getRelativePath(item.getKey().substring(0, item.getKey().lastIndexOf("/"))));
|
||||
object.setName(item.getKey().substring(item.getKey().lastIndexOf("/") + 1));
|
||||
object.setSize(item.getSize());
|
||||
object.setModifyTime(item.getLastModified());
|
||||
object.setRawObject(item);
|
||||
return object;
|
||||
}).collect(Collectors.toList());
|
||||
|
@ -2,11 +2,14 @@ package com.ycwl.basic.task;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.ycwl.basic.mapper.MemberMapper;
|
||||
import com.ycwl.basic.mapper.ScenicMapper;
|
||||
import com.ycwl.basic.mapper.VideoMapper;
|
||||
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||
import com.ycwl.basic.model.pc.mp.MpConfigEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
|
||||
import com.ycwl.basic.notify.NotifyFactory;
|
||||
import com.ycwl.basic.notify.adapters.INotifyAdapter;
|
||||
@ -22,8 +25,11 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@ -39,6 +45,8 @@ public class DownloadNotificationTasker {
|
||||
private MemberMapper memberMapper;
|
||||
@Autowired
|
||||
private TemplateRepository templateRepository;
|
||||
@Autowired
|
||||
private ScenicMapper scenicMapper;
|
||||
|
||||
@Scheduled(cron = "0 0 21 * * *")
|
||||
public void sendDownloadNotification() {
|
||||
@ -131,4 +139,69 @@ public class DownloadNotificationTasker {
|
||||
adapter.sendTo(new NotifyContent(title, page, params), member.getOpenId());
|
||||
});
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 * * * *")
|
||||
public void sendExtraDownloadNotification() {
|
||||
log.info("开始执行定时任务");
|
||||
List<ScenicRespVO> scenicList = scenicMapper.list(new ScenicReqQuery());
|
||||
if (scenicList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date());
|
||||
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
calendar.clear();
|
||||
scenicList.parallelStream().forEach(scenic -> {
|
||||
Long scenicId = scenic.getId();
|
||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
|
||||
if (scenicConfig == null) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isEmpty(scenicConfig.getExtraNotificationTime())) {
|
||||
return;
|
||||
}
|
||||
List<String> timeList = Arrays.asList(StringUtils.split(scenicConfig.getExtraNotificationTime(), ","));
|
||||
if (!timeList.contains(String.valueOf(currentHour))) {
|
||||
return;
|
||||
}
|
||||
log.info("当前景区{},配置了{}", scenic.getName(), scenicConfig.getExtraNotificationTime());
|
||||
|
||||
videoMapper.listRelationByCreateTime(DateUtil.beginOfDay(new Date()), new Date())
|
||||
.parallelStream()
|
||||
.forEach(item -> {
|
||||
if (item.getIsBuy() == 1) {
|
||||
return;
|
||||
}
|
||||
MemberRespVO member = memberMapper.getById(item.getMemberId());
|
||||
MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
|
||||
// 发送模板消息
|
||||
String templateId = scenicRepository.getVideoDownloadTemplateId(item.getScenicId());
|
||||
if (StringUtils.isBlank(templateId)) {
|
||||
log.info("模板消息为空");
|
||||
return;
|
||||
}
|
||||
log.info("发送模板消息");
|
||||
String title = "您在【" + scenic.getName() + "】的专属影像";
|
||||
String page = "pages/videoSynthesis/index?type=2&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
|
||||
/**
|
||||
* 景区 {{thing1.DATA}}
|
||||
* 备注 {{thing3.DATA}}
|
||||
*/
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
Map<String, Object> dataParam = new HashMap<>();
|
||||
Map<String, String> videoMap = new HashMap<>();
|
||||
videoMap.put("value", title);
|
||||
dataParam.put("thing1", videoMap);
|
||||
Map<String, String> remarkMap = new HashMap<>();
|
||||
remarkMap.put("value", "请及时购买并下载好您的旅行视频");
|
||||
dataParam.put("thing3", remarkMap);
|
||||
params.put("data", dataParam);
|
||||
params.put("page", page);
|
||||
params.put("template_id", templateId);
|
||||
log.info("视频下载通知模板参数:{},用户ID:{}", params, member.getOpenId());
|
||||
INotifyAdapter adapter = NotifyFactory.get(NotifyType.WX_MP_SRV, scenicMp.toMap());
|
||||
adapter.sendTo(new NotifyContent(title, page, params), member.getOpenId());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ public class VideoPieceGetter {
|
||||
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setNamePrefix("VPG-" + task.faceId + "-t")
|
||||
.build();
|
||||
final ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 512, 0L, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(512),
|
||||
final ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 128, 0L, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(128),
|
||||
threadFactory
|
||||
);
|
||||
List<String> currentUnFinPlaceholder = new ArrayList<>();
|
||||
|
@ -10,7 +10,6 @@ import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
||||
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.repository.VideoRepository;
|
||||
import com.ycwl.basic.repository.VideoTaskRepository;
|
||||
import com.ycwl.basic.service.pc.ScenicService;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||
@ -21,19 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@ -102,7 +93,7 @@ public class VideoReUploader {
|
||||
}
|
||||
});
|
||||
}
|
||||
public void addVideoTask(String url, Long videoId) {
|
||||
public void addVideoTask(Long videoId) {
|
||||
VideoEntity entity = videoMapper.getEntity(videoId);
|
||||
if (entity == null) {
|
||||
return;
|
||||
@ -112,16 +103,16 @@ public class VideoReUploader {
|
||||
}
|
||||
final String dstFilePath = StorageUtil.joinPath(StorageConstant.VLOG_PATH, entity.getTaskId() + "_" + entity.getScenicId() + ".mp4");
|
||||
final IStorageAdapter adapter = scenicService.getScenicStorageAdapter(entity.getScenicId());
|
||||
if (StringUtils.equals(url, adapter.getUrl(dstFilePath))) {
|
||||
if (StringUtils.equals(entity.getVideoUrl(), adapter.getUrl(dstFilePath))) {
|
||||
return;
|
||||
}
|
||||
String tmpFilePath = UUID.randomUUID().toString();
|
||||
executor.execute(() -> {
|
||||
// 先下载,后上传
|
||||
File dstFile = new File(tmpFilePath);
|
||||
log.info("下载视频:{};videoId:{}", url, videoId);
|
||||
long size = HttpUtil.downloadFile(url, dstFile);
|
||||
log.info("下载视频完成:{};大小:{};videoId:{}", url, size, videoId);
|
||||
log.info("下载视频:{};videoId:{}", entity.getVideoUrl(), videoId);
|
||||
long size = HttpUtil.downloadFile(entity.getVideoUrl(), dstFile);
|
||||
log.info("下载视频完成:{};大小:{};videoId:{}", entity.getVideoUrl(), size, videoId);
|
||||
try {
|
||||
log.info("开始上传:{};videoId:{}", dstFilePath, videoId);
|
||||
String newUrl = adapter.uploadFile("video/mp4", dstFile, dstFilePath);
|
||||
|
@ -125,7 +125,8 @@
|
||||
pay_type=#{payType},
|
||||
pay_config_json=#{payConfigJson},
|
||||
image_source_pack_hint=#{imageSourcePackHint},
|
||||
video_source_pack_hint=#{videoSourcePackHint}
|
||||
video_source_pack_hint=#{videoSourcePackHint},
|
||||
extra_notification_time=#{extraNotificationTime}
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
@ -139,7 +139,7 @@
|
||||
<if test="isBuy!=null">and ms.is_buy = #{isBuy} </if>
|
||||
<if test="type!=null">and ms.type = #{type} </if>
|
||||
<if test="faceId!=null">and ms.face_id = #{faceId} </if>
|
||||
order by so.create_time asc
|
||||
order by ms.is_free desc, so.create_time asc
|
||||
</select>
|
||||
|
||||
<select id="listUserOne" resultType="com.ycwl.basic.model.pc.source.resp.SourceRespVO">
|
||||
@ -214,4 +214,14 @@
|
||||
</if>
|
||||
and watermark_type = #{watermarkType}
|
||||
</select>
|
||||
<select id="countUser" resultType="java.lang.Integer">
|
||||
select count(1)
|
||||
from member_source ms
|
||||
where
|
||||
ms.member_id = #{memberId}
|
||||
<if test="scenicId!= null">and ms.scenic_id = #{scenicId} </if>
|
||||
<if test="isBuy!=null">and ms.is_buy = #{isBuy} </if>
|
||||
<if test="type!=null">and ms.type = #{type} </if>
|
||||
<if test="faceId!=null">and ms.face_id = #{faceId} </if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
Reference in New Issue
Block a user