You've already forked FrameTour-BE
加个普通水印、推送订单纠正、水印预览和下载
This commit is contained in:
@ -1,170 +0,0 @@
|
||||
package com.ycwl.basic.task;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
||||
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
||||
import com.ycwl.basic.image.watermark.exception.ImageWatermarkException;
|
||||
import com.ycwl.basic.image.watermark.operator.IOperator;
|
||||
import com.ycwl.basic.mapper.SourceMapper;
|
||||
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
||||
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.source.entity.MemberSourceEntity;
|
||||
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
||||
import com.ycwl.basic.notify.entity.WxMpSrvConfig;
|
||||
import com.ycwl.basic.repository.FaceRepository;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||
import com.ycwl.basic.utils.WxMpUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.ycwl.basic.constant.StorageConstant.PHOTO_WATERMARKED_PATH;
|
||||
|
||||
|
||||
@Component
|
||||
@EnableScheduling
|
||||
@Slf4j
|
||||
public class ImageWatermarkTask {
|
||||
@Autowired
|
||||
private FaceRepository faceRepository;
|
||||
@Autowired
|
||||
private ScenicRepository scenicRepository;
|
||||
@Autowired
|
||||
private SourceMapper sourceMapper;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class Task {
|
||||
public Long memberId;
|
||||
public Long faceId;
|
||||
}
|
||||
|
||||
public static ConcurrentLinkedQueue<Task> queue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public static void addTask(Long memberId, Long faceId) {
|
||||
queue.add(new Task(memberId, faceId));
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 200L)
|
||||
public void doTask() {
|
||||
Task task = queue.poll();
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
log.info("poll task: {}/{}", task, queue.size());
|
||||
new Thread(() -> {
|
||||
try {
|
||||
runTask(task);
|
||||
} catch (Exception e) {
|
||||
log.error("run task error", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void runTask(Task task) {
|
||||
// 生成二维码
|
||||
FaceEntity face = faceRepository.getFace(task.faceId);
|
||||
if (face == null) {
|
||||
return;
|
||||
}
|
||||
ScenicEntity scenic = scenicRepository.getScenic(face.getScenicId());
|
||||
if (scenic == null) {
|
||||
return;
|
||||
}
|
||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(face.getScenicId());
|
||||
MpConfigEntity scenicMpConfig = scenicRepository.getScenicMpConfig(face.getScenicId());
|
||||
if (scenicMpConfig == null) {
|
||||
return;
|
||||
}
|
||||
List<SourceEntity> sourceEntities = sourceMapper.listImageByFaceRelation(task.memberId, task.faceId);
|
||||
if (sourceEntities == null || sourceEntities.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
File qrcode = new File("qrcode_"+face.getMemberId()+".jpg");
|
||||
try {
|
||||
String urlLink = WxMpUtil.generateUrlLink(scenicMpConfig.getAppId(), scenicMpConfig.getAppSecret(), "pages/videoSynthesis/index", "scenicId=" + face.getScenicId() + "&faceId=" + face.getId());
|
||||
QrCodeUtil.generate(urlLink + "?cq=", 300, 300, qrcode);
|
||||
} catch (Exception e) {
|
||||
log.error("generateWXQRCode error", e);
|
||||
return;
|
||||
}
|
||||
IStorageAdapter adapter = StorageFactory.get(scenicConfig.getStoreType());
|
||||
adapter.loadConfig(JSONObject.parseObject(scenicConfig.getStoreConfigJson(), Map.class));
|
||||
// TODO
|
||||
WatermarkInfo info = new WatermarkInfo();
|
||||
info.setQrcodeFile(qrcode);
|
||||
final ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 128, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(128));
|
||||
for (SourceEntity sourceEntity : sourceEntities) {
|
||||
executor.execute(() -> {
|
||||
String url;
|
||||
try {
|
||||
IOperator operator = ImageWatermarkFactory.get(scenicConfig.getWatermarkType());
|
||||
File dstFile = new File(sourceEntity.getId() + ".jpg");
|
||||
File watermarkedFile = new File(sourceEntity.getId() + "_w.png");
|
||||
try {
|
||||
HttpUtil.downloadFile(sourceEntity.getUrl(), dstFile);
|
||||
} catch (Exception e) {
|
||||
log.error("downloadFile error", e);
|
||||
return;
|
||||
}
|
||||
info.setOriginalFile(dstFile);
|
||||
info.setScenicLine(scenicConfig.getWatermarkScenicText());
|
||||
info.setDatetime(sourceEntity.getCreateTime());
|
||||
info.setDtFormat(scenicConfig.getWatermarkDtFormat());
|
||||
info.setWatermarkedFile(watermarkedFile);
|
||||
try {
|
||||
operator.process(info);
|
||||
} catch (ImageWatermarkException e) {
|
||||
log.error("process error", e);
|
||||
return;
|
||||
}
|
||||
url = adapter.uploadFile(watermarkedFile, PHOTO_WATERMARKED_PATH, watermarkedFile.getName());
|
||||
adapter.setAcl(StorageAcl.PUBLIC_READ, PHOTO_WATERMARKED_PATH, watermarkedFile.getName());
|
||||
} catch (ImageWatermarkException e) {
|
||||
// 不支持
|
||||
url = sourceEntity.getUrl();
|
||||
}
|
||||
|
||||
MemberSourceEntity memberSource = new MemberSourceEntity();
|
||||
memberSource.setMemberId(task.memberId);
|
||||
memberSource.setScenicId(face.getScenicId());
|
||||
memberSource.setFaceId(task.faceId);
|
||||
memberSource.setType(sourceEntity.getType());
|
||||
memberSource.setSourceId(sourceEntity.getId());
|
||||
memberSource.setWaterUrl(url);
|
||||
sourceMapper.updateWaterUrl(memberSource);
|
||||
});
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000L);
|
||||
log.info("executor等待被结束![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount());
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(30, TimeUnit.SECONDS);
|
||||
log.info("executor已结束![A:{}/T:{}/F:{}]", executor.getActiveCount(), executor.getTaskCount(), executor.getCompletedTaskCount());
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user