商品详情由前端生成改为后端生成
This commit is contained in:
@ -0,0 +1,8 @@
|
|||||||
|
package co.yixiang.modules.shop.service;
|
||||||
|
|
||||||
|
import co.yixiang.modules.shop.web.dto.ProductDTO;
|
||||||
|
|
||||||
|
public interface CreatShareProductService {
|
||||||
|
|
||||||
|
String creatProductPic(ProductDTO productDTO,String qrcode,String spreadPicName,String spreadPicPath,String apiUrl);
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package co.yixiang.modules.shop.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import co.yixiang.modules.shop.service.CreatShareProductService;
|
||||||
|
import co.yixiang.modules.shop.web.dto.ProductDTO;
|
||||||
|
import co.yixiang.modules.user.entity.YxSystemAttachment;
|
||||||
|
import co.yixiang.modules.user.service.YxSystemAttachmentService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class CreatShareProductServiceImpl implements CreatShareProductService {
|
||||||
|
|
||||||
|
private final YxSystemAttachmentService systemAttachmentService;
|
||||||
|
|
||||||
|
public String creatProductPic(ProductDTO productDTO,String shareCode,String spreadPicName,String spreadPicPath,String apiUrl) {
|
||||||
|
YxSystemAttachment attachmentT = systemAttachmentService.getInfo(spreadPicName);
|
||||||
|
String spreadUrl = "";
|
||||||
|
if(ObjectUtil.isNull(attachmentT)){
|
||||||
|
//创建图片
|
||||||
|
BufferedImage img = new BufferedImage(750, 1334, BufferedImage.TYPE_INT_RGB);
|
||||||
|
//开启画图
|
||||||
|
Graphics g = img.getGraphics();
|
||||||
|
//背景 -- 读取互联网图片
|
||||||
|
BufferedImage back = null;
|
||||||
|
InputStream stream = getClass().getClassLoader().getResourceAsStream("background.png");
|
||||||
|
try {
|
||||||
|
ImageInputStream background = ImageIO.createImageInputStream(stream);
|
||||||
|
back = ImageIO.read(background);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(back.getScaledInstance(750, 1334, Image.SCALE_DEFAULT), 0, 0, null); // 绘制缩小后的图
|
||||||
|
//商品 banner图
|
||||||
|
//读取互联网图片
|
||||||
|
BufferedImage priductUrl = null;
|
||||||
|
try {
|
||||||
|
priductUrl = ImageIO.read(new URL(productDTO.getStoreInfo().getImage_base()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
g.drawImage(priductUrl.getScaledInstance(690,516,Image.SCALE_DEFAULT),29,61,null);
|
||||||
|
//文案标题
|
||||||
|
g.setFont(new Font("微软雅黑", Font.BOLD, 34));
|
||||||
|
g.setColor(new Color(29,29,29));
|
||||||
|
//绘制文字
|
||||||
|
g.drawString(productDTO.getStoreInfo().getStoreName(), 31, 638);
|
||||||
|
//文案
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 30));
|
||||||
|
g.setColor(new Color(47,47,47));
|
||||||
|
int fontlen = getWatermarkLength(productDTO.getStoreInfo().getStoreInfo(), g);
|
||||||
|
//文字长度相对于图片宽度应该有多少行
|
||||||
|
int line = fontlen / (back.getWidth() - 90);
|
||||||
|
//高度
|
||||||
|
int y = back.getHeight() - (line + 1) * 30 + 200;
|
||||||
|
//文字叠加,自动换行叠加
|
||||||
|
int tempX = 32;
|
||||||
|
int tempY = y;
|
||||||
|
//单字符长度
|
||||||
|
int tempCharLen = 0;
|
||||||
|
//单行字符总长度临时计算
|
||||||
|
int tempLineLen = 0;
|
||||||
|
StringBuffer sb =new StringBuffer();
|
||||||
|
for(int i=0; i < productDTO.getStoreInfo().getStoreInfo().length(); i++) {
|
||||||
|
char tempChar = productDTO.getStoreInfo().getStoreInfo().charAt(i);
|
||||||
|
tempCharLen = getCharLen(tempChar, g);
|
||||||
|
tempLineLen += tempCharLen;
|
||||||
|
if(tempLineLen >= (back.getWidth()-90)) {
|
||||||
|
//长度已经满一行,进行文字叠加
|
||||||
|
g.drawString(sb.toString(), tempX, tempY + 50);
|
||||||
|
//清空内容,重新追加
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
//每行文字间距50
|
||||||
|
tempY += 50;
|
||||||
|
tempLineLen =0;
|
||||||
|
}
|
||||||
|
//追加字符
|
||||||
|
sb.append(tempChar);
|
||||||
|
}
|
||||||
|
//最后叠加余下的文字
|
||||||
|
g.drawString(sb.toString(), tempX, tempY + 50);
|
||||||
|
|
||||||
|
//价格背景
|
||||||
|
//读取互联网图片
|
||||||
|
BufferedImage bground = null;//
|
||||||
|
InputStream redStream = getClass().getClassLoader().getResourceAsStream("red.jpg");
|
||||||
|
try {
|
||||||
|
ImageInputStream red = ImageIO.createImageInputStream(redStream);
|
||||||
|
bground = ImageIO.read(red);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// 绘制缩小后的图
|
||||||
|
g.drawImage(bground.getScaledInstance(160, 40, Image.SCALE_DEFAULT), 30, 1053, null);
|
||||||
|
|
||||||
|
//限时促销价
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 24));
|
||||||
|
g.setColor(new Color(255,255,255));
|
||||||
|
g.drawString("限时促销价", 50, 1080);
|
||||||
|
|
||||||
|
//价格
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 50));
|
||||||
|
g.setColor(new Color(249,64,64));
|
||||||
|
g.drawString("¥" +productDTO.getStoreInfo().getPrice(), 29, 1162);
|
||||||
|
|
||||||
|
//原价
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 36));
|
||||||
|
g.setColor(new Color(171,171,171));
|
||||||
|
String price = "¥" + productDTO.getStoreInfo().getOtPrice();
|
||||||
|
g.drawString(price, 260, 1160);
|
||||||
|
g.drawLine(250,1148,260+150,1148);
|
||||||
|
|
||||||
|
//商品名称
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 32));
|
||||||
|
g.setColor(new Color(29,29,29));
|
||||||
|
g.drawString(productDTO.getStoreInfo().getStoreName(), 30, 1229);
|
||||||
|
|
||||||
|
//生成二维码返回链接
|
||||||
|
String url = shareCode;
|
||||||
|
//读取互联网图片
|
||||||
|
BufferedImage qrCode = null;
|
||||||
|
try {
|
||||||
|
qrCode = ImageIO.read(new URL(url));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// 绘制缩小后的图
|
||||||
|
g.drawImage(qrCode.getScaledInstance(174, 174, Image.SCALE_DEFAULT), 536, 1057, null);
|
||||||
|
|
||||||
|
//二维码字体
|
||||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, 25));
|
||||||
|
g.setColor(new Color(171,171,171));
|
||||||
|
//绘制文字
|
||||||
|
g.drawString("扫描或长按小程序码", 515, 1260);
|
||||||
|
|
||||||
|
g.dispose();
|
||||||
|
//先将画好的海报写到本地
|
||||||
|
File file = new File(spreadPicPath);
|
||||||
|
try {
|
||||||
|
ImageIO.write(img, "jpg",file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
systemAttachmentService.attachmentAdd(spreadPicName,
|
||||||
|
String.valueOf(FileUtil.size(new File(spreadPicPath))),
|
||||||
|
spreadPicPath,"qrcode/"+spreadPicName);
|
||||||
|
spreadUrl = apiUrl + "/api/file/qrcode/"+spreadPicName;
|
||||||
|
//保存到本地 生成文件名字
|
||||||
|
}else {
|
||||||
|
spreadUrl = apiUrl + "/api/file/" + attachmentT.getSattDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
return spreadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取水印文字总长度
|
||||||
|
*@paramwaterMarkContent水印的文字
|
||||||
|
*@paramg
|
||||||
|
*@return水印文字总长度
|
||||||
|
*/
|
||||||
|
public static int getWatermarkLength(String waterMarkContent, Graphics g) {
|
||||||
|
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(),0, waterMarkContent.length());
|
||||||
|
}
|
||||||
|
public static int getCharLen(char c, Graphics g) {
|
||||||
|
return g.getFontMetrics(g.getFont()).charWidth(c);
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,7 @@ import co.yixiang.common.api.ApiResult;
|
|||||||
import co.yixiang.common.web.controller.BaseController;
|
import co.yixiang.common.web.controller.BaseController;
|
||||||
import co.yixiang.enums.AppFromEnum;
|
import co.yixiang.enums.AppFromEnum;
|
||||||
import co.yixiang.enums.ProductEnum;
|
import co.yixiang.enums.ProductEnum;
|
||||||
import co.yixiang.modules.shop.service.YxStoreProductRelationService;
|
import co.yixiang.modules.shop.service.*;
|
||||||
import co.yixiang.modules.shop.service.YxStoreProductReplyService;
|
|
||||||
import co.yixiang.modules.shop.service.YxStoreProductService;
|
|
||||||
import co.yixiang.modules.shop.service.YxSystemConfigService;
|
|
||||||
import co.yixiang.modules.shop.web.dto.ProductDTO;
|
import co.yixiang.modules.shop.web.dto.ProductDTO;
|
||||||
import co.yixiang.modules.shop.web.param.YxStoreProductQueryParam;
|
import co.yixiang.modules.shop.web.param.YxStoreProductQueryParam;
|
||||||
import co.yixiang.modules.shop.web.param.YxStoreProductRelationQueryParam;
|
import co.yixiang.modules.shop.web.param.YxStoreProductRelationQueryParam;
|
||||||
@ -67,7 +64,7 @@ public class StoreProductController extends BaseController {
|
|||||||
private final YxSystemConfigService systemConfigService;
|
private final YxSystemConfigService systemConfigService;
|
||||||
private final YxSystemAttachmentService systemAttachmentService;
|
private final YxSystemAttachmentService systemAttachmentService;
|
||||||
private final YxUserService yxUserService;
|
private final YxUserService yxUserService;
|
||||||
|
private final CreatShareProductService creatShareProductService;
|
||||||
@Value("${file.path}")
|
@Value("${file.path}")
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
@ -125,9 +122,7 @@ public class StoreProductController extends BaseController {
|
|||||||
@RequestParam(value = "",required=false) String longitude,
|
@RequestParam(value = "",required=false) String longitude,
|
||||||
@RequestParam(value = "",required=false) String from){
|
@RequestParam(value = "",required=false) String from){
|
||||||
int uid = SecurityUtils.getUserId().intValue();
|
int uid = SecurityUtils.getUserId().intValue();
|
||||||
|
|
||||||
ProductDTO productDTO = storeProductService.goodsDetail(id,0,uid,latitude,longitude);
|
ProductDTO productDTO = storeProductService.goodsDetail(id,0,uid,latitude,longitude);
|
||||||
|
|
||||||
// 海报
|
// 海报
|
||||||
String siteUrl = systemConfigService.getData("site_url");
|
String siteUrl = systemConfigService.getData("site_url");
|
||||||
if(StrUtil.isEmpty(siteUrl)){
|
if(StrUtil.isEmpty(siteUrl)){
|
||||||
@ -137,66 +132,40 @@ public class StoreProductController extends BaseController {
|
|||||||
if(StrUtil.isEmpty(apiUrl)){
|
if(StrUtil.isEmpty(apiUrl)){
|
||||||
return ApiResult.fail("未配置api地址");
|
return ApiResult.fail("未配置api地址");
|
||||||
}
|
}
|
||||||
|
|
||||||
YxUserQueryVo userInfo = yxUserService.getYxUserById(uid);
|
YxUserQueryVo userInfo = yxUserService.getYxUserById(uid);
|
||||||
String userType = userInfo.getUserType();
|
String userType = userInfo.getUserType();
|
||||||
if(!userType.equals(AppFromEnum.ROUNTINE.getValue())) {
|
if(!userType.equals(AppFromEnum.ROUNTINE.getValue())) {
|
||||||
userType = AppFromEnum.H5.getValue();
|
userType = AppFromEnum.H5.getValue();
|
||||||
}
|
}
|
||||||
//app类型
|
|
||||||
if(StrUtil.isNotBlank(from) && AppFromEnum.APP.getValue().equals(from)){
|
|
||||||
String name = id+"_"+uid + "_"+from+"_product_detail_wap.jpg";
|
|
||||||
YxSystemAttachment attachment = systemAttachmentService.getInfo(name);
|
|
||||||
String inviteCode = OrderUtil.createShareCode();
|
|
||||||
if(ObjectUtil.isNull(attachment)){
|
|
||||||
systemAttachmentService.newAttachmentAdd(name, "", "","",uid,inviteCode);
|
|
||||||
}else{
|
|
||||||
inviteCode = attachment.getInviteCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
productDTO.getStoreInfo().setCodeBase(inviteCode);
|
|
||||||
}else {
|
|
||||||
String name = id+"_"+uid + "_"+userType+"_product_detail_wap.jpg";
|
String name = id+"_"+uid + "_"+userType+"_product_detail_wap.jpg";
|
||||||
YxSystemAttachment attachment = systemAttachmentService.getInfo(name);
|
YxSystemAttachment attachment = systemAttachmentService.getInfo(name);
|
||||||
String fileDir = path+"qrcode"+ File.separator;
|
String fileDir = path+"qrcode"+ File.separator;
|
||||||
String qrcodeUrl = "";
|
String qrcodeUrl = "";
|
||||||
String routineQrcodeUrl = "";
|
|
||||||
if(ObjectUtil.isNull(attachment)){
|
if(ObjectUtil.isNull(attachment)){
|
||||||
//生成二维码
|
|
||||||
File file = FileUtil.mkdir(new File(fileDir));
|
File file = FileUtil.mkdir(new File(fileDir));
|
||||||
|
//如果类型是小程序
|
||||||
if(userType.equals(AppFromEnum.ROUNTINE.getValue())){
|
if(userType.equals(AppFromEnum.ROUNTINE.getValue())){
|
||||||
//下载图片
|
//h5地址
|
||||||
siteUrl = siteUrl+"/product/";
|
siteUrl = siteUrl+"/product/";
|
||||||
|
//生成二维码
|
||||||
QrCodeUtil.generate(siteUrl+"?productId="+id+"&spread="+uid, 180, 180,
|
QrCodeUtil.generate(siteUrl+"?productId="+id+"&spread="+uid, 180, 180,
|
||||||
FileUtil.file(fileDir+name));
|
FileUtil.file(fileDir+name));
|
||||||
}else{
|
}else{//如果类型是h5
|
||||||
|
//生成二维码
|
||||||
QrCodeUtil.generate(siteUrl+"/detail/"+id+"?spread="+uid, 180, 180,
|
QrCodeUtil.generate(siteUrl+"/detail/"+id+"?spread="+uid, 180, 180,
|
||||||
FileUtil.file(fileDir+name));
|
FileUtil.file(fileDir+name));
|
||||||
}
|
}
|
||||||
|
|
||||||
systemAttachmentService.attachmentAdd(name,String.valueOf(FileUtil.size(file)),
|
systemAttachmentService.attachmentAdd(name,String.valueOf(FileUtil.size(file)),
|
||||||
fileDir+name,"qrcode/"+name);
|
fileDir+name,"qrcode/"+name);
|
||||||
|
|
||||||
qrcodeUrl = fileDir+name;
|
qrcodeUrl = apiUrl + "/api/file/qrcode/"+name;
|
||||||
routineQrcodeUrl = apiUrl + "/api/file/qrcode/"+name;
|
|
||||||
}else{
|
}else{
|
||||||
qrcodeUrl = attachment.getAttDir();
|
qrcodeUrl = apiUrl + "/api/file/" + attachment.getSattDir();
|
||||||
routineQrcodeUrl = apiUrl + "/api/file/" + attachment.getSattDir();
|
|
||||||
}
|
}
|
||||||
|
String spreadPicName = id+"_"+uid + "_"+userType+"_product_user_spread.jpg";
|
||||||
if(userType.equals(AppFromEnum.ROUNTINE.getValue())){
|
String spreadPicPath = fileDir+spreadPicName;
|
||||||
productDTO.getStoreInfo().setCodeBase(routineQrcodeUrl);
|
String rr = creatShareProductService.creatProductPic(productDTO,qrcodeUrl,spreadPicName,spreadPicPath,apiUrl);
|
||||||
}else{
|
productDTO.getStoreInfo().setCodeBase(rr);
|
||||||
try {
|
|
||||||
String base64CodeImg = co.yixiang.utils.FileUtil.fileToBase64(new File(qrcodeUrl));
|
|
||||||
productDTO.getStoreInfo().setCodeBase("data:image/jpeg;base64," + base64CodeImg);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ApiResult.ok(productDTO);
|
return ApiResult.ok(productDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,16 +215,5 @@ public class StoreProductController extends BaseController {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
yshop-api/src/main/resources/background.png
Normal file
BIN
yshop-api/src/main/resources/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
@ -47,7 +47,7 @@ spring:
|
|||||||
database: 0
|
database: 0
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 6379
|
port: 6379
|
||||||
password:
|
password: root
|
||||||
#连接超时时间
|
#连接超时时间
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
|
|
||||||
@ -75,8 +75,8 @@ swagger:
|
|||||||
|
|
||||||
# 文件存储路径
|
# 文件存储路径
|
||||||
file:
|
file:
|
||||||
path: E:\yshop\file\
|
path: D:\yshop\file\
|
||||||
avatar: E:\yshop\avatar\
|
avatar: D:\yshop\avatar\
|
||||||
# 文件大小 /M
|
# 文件大小 /M
|
||||||
maxSize: 100
|
maxSize: 100
|
||||||
avatarMaxSize: 5
|
avatarMaxSize: 5
|
||||||
|
BIN
yshop-api/src/main/resources/red.jpg
Normal file
BIN
yshop-api/src/main/resources/red.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 419 B |
Reference in New Issue
Block a user