diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGoodsController.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGoodsController.java index 88cc2ae1..d280de1e 100644 --- a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGoodsController.java +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGoodsController.java @@ -5,6 +5,7 @@ import org.apache.commons.logging.LogFactory; import org.linlinjava.litemall.admin.annotation.LoginAdmin; import org.linlinjava.litemall.admin.dao.GoodsAllinone; import org.linlinjava.litemall.admin.util.CatVo; +import org.linlinjava.litemall.core.qcode.QCodeService; import org.linlinjava.litemall.db.domain.*; import org.linlinjava.litemall.db.service.*; import org.linlinjava.litemall.core.util.ResponseUtil; @@ -15,7 +16,6 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.web.bind.annotation.*; -import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; @@ -40,13 +40,16 @@ public class AdminGoodsController { @Autowired private LitemallBrandService brandService; + @Autowired + private QCodeService qCodeService; + @GetMapping("/list") public Object list(@LoginAdmin Integer adminId, String goodsSn, String name, @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "limit", defaultValue = "10") Integer limit, - String sort, String order){ - if(adminId == null){ + String sort, String order) { + if (adminId == null) { return ResponseUtil.unlogin(); } @@ -71,8 +74,8 @@ public class AdminGoodsController { * 因此这里只能删除所有旧的数据,然后添加新的数据 */ @PostMapping("/update") - public Object update(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){ - if(adminId == null){ + public Object update(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone) { + if (adminId == null) { return ResponseUtil.unlogin(); } @@ -97,7 +100,7 @@ public class AdminGoodsController { // 商品规格表litemall_goods_specification Map specIds = new HashMap<>(); - for(LitemallGoodsSpecification specification : specifications){ + for (LitemallGoodsSpecification specification : specifications) { specification.setGoodsId(goods.getId()); specification.setAddTime(LocalDateTime.now()); specificationService.add(specification); @@ -105,14 +108,14 @@ public class AdminGoodsController { } // 商品参数表litemall_goods_attribute - for(LitemallGoodsAttribute attribute : attributes){ + for (LitemallGoodsAttribute attribute : attributes) { attribute.setGoodsId(goods.getId()); attribute.setAddTime(LocalDateTime.now()); attributeService.add(attribute); } // 商品货品表litemall_product - for(LitemallProduct product : products){ + for (LitemallProduct product : products) { product.setGoodsId(goods.getId()); product.setAddTime(LocalDateTime.now()); productService.add(product); @@ -123,12 +126,14 @@ public class AdminGoodsController { } txManager.commit(status); + qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName()); + return ResponseUtil.ok(); } @PostMapping("/delete") - public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){ - if(adminId == null){ + public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods) { + if (adminId == null) { return ResponseUtil.unlogin(); } @@ -152,8 +157,8 @@ public class AdminGoodsController { } @PostMapping("/create") - public Object create(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){ - if(adminId == null){ + public Object create(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone) { + if (adminId == null) { return ResponseUtil.unlogin(); } @@ -163,7 +168,7 @@ public class AdminGoodsController { LitemallProduct[] products = goodsAllinone.getProducts(); String name = goods.getName(); - if(goodsService.checkExistByName(name)){ + if (goodsService.checkExistByName(name)) { return ResponseUtil.fail(403, "商品名已经存在"); } @@ -179,7 +184,7 @@ public class AdminGoodsController { // 商品规格表litemall_goods_specification Map specIds = new HashMap<>(); - for(LitemallGoodsSpecification specification : specifications){ + for (LitemallGoodsSpecification specification : specifications) { specification.setGoodsId(goods.getId()); specification.setAddTime(LocalDateTime.now()); specificationService.add(specification); @@ -187,14 +192,14 @@ public class AdminGoodsController { } // 商品参数表litemall_goods_attribute - for(LitemallGoodsAttribute attribute : attributes){ + for (LitemallGoodsAttribute attribute : attributes) { attribute.setGoodsId(goods.getId()); attribute.setAddTime(LocalDateTime.now()); attributeService.add(attribute); } // 商品货品表litemall_product - for(LitemallProduct product : products){ + for (LitemallProduct product : products) { product.setGoodsId(goods.getId()); product.setAddTime(LocalDateTime.now()); productService.add(product); @@ -205,11 +210,13 @@ public class AdminGoodsController { } txManager.commit(status); + + qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName()); + return ResponseUtil.ok(); } - @GetMapping("/catAndBrand") public Object list2(@LoginAdmin Integer adminId) { if (adminId == null) { @@ -221,14 +228,14 @@ public class AdminGoodsController { List l1CatList = categoryService.queryL1(); List categoryList = new ArrayList<>(l1CatList.size()); - for(LitemallCategory l1 : l1CatList){ + for (LitemallCategory l1 : l1CatList) { CatVo l1CatVo = new CatVo(); l1CatVo.setValue(l1.getId()); l1CatVo.setLabel(l1.getName()); List l2CatList = categoryService.queryByPid(l1.getId()); List children = new ArrayList<>(l2CatList.size()); - for(LitemallCategory l2 : l2CatList) { + for (LitemallCategory l2 : l2CatList) { CatVo l2CatVo = new CatVo(); l2CatVo.setValue(l2.getId()); l2CatVo.setLabel(l2.getName()); @@ -243,7 +250,7 @@ public class AdminGoodsController { // 管理员设置“所属品牌商” List list = brandService.all(); List> brandList = new ArrayList<>(l1CatList.size()); - for(LitemallBrand brand : list){ + for (LitemallBrand brand : list) { Map b = new HashMap<>(2); b.put("value", brand.getId()); b.put("label", brand.getName()); @@ -251,7 +258,7 @@ public class AdminGoodsController { } Map data = new HashMap<>(); - data.put("categoryList" ,categoryList); + data.put("categoryList", categoryList); data.put("brandList", brandList); return ResponseUtil.ok(data); } @@ -276,11 +283,11 @@ public class AdminGoodsController { Integer[] categoryIds = new Integer[]{}; if (category != null) { Integer parentCategoryId = category.getPid(); - categoryIds = new Integer[] {parentCategoryId, categoryId}; + categoryIds = new Integer[]{parentCategoryId, categoryId}; } Map data = new HashMap<>(); - data.put("goods" ,goods); + data.put("goods", goods); data.put("specifications", specifications); data.put("products", products); data.put("attributes", attributes); diff --git a/litemall-core/pom.xml b/litemall-core/pom.xml index c4ece35b..a9a61cc5 100644 --- a/litemall-core/pom.xml +++ b/litemall-core/pom.xml @@ -81,6 +81,12 @@ weixin-java-pay 3.0.0 + + org.springframework + spring-test + 5.0.7.RELEASE + compile + diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WxTemplateSender.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WxTemplateSender.java index 5f01e7e0..e8dd998d 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WxTemplateSender.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WxTemplateSender.java @@ -2,7 +2,6 @@ package org.linlinjava.litemall.core.notify; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import me.chanjar.weixin.common.exception.WxErrorException; import org.linlinjava.litemall.db.domain.LitemallUserFormid; import org.linlinjava.litemall.db.service.LitemallUserFormIdService; import org.springframework.beans.factory.annotation.Autowired; @@ -61,7 +60,7 @@ public class WxTemplateSender { try { wxMaService.getMsgService().sendTemplateMsg(msg); formIdService.updateUserFormId(userFormid); - } catch (WxErrorException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/qcode/QCodeService.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/qcode/QCodeService.java new file mode 100644 index 00000000..81ed380d --- /dev/null +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/qcode/QCodeService.java @@ -0,0 +1,129 @@ +package org.linlinjava.litemall.core.qcode; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.error.WxErrorException; +import org.linlinjava.litemall.core.storage.StorageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.URL; + +@Service +public class QCodeService { + @Autowired + WxMaService wxMaService; + + @Autowired + private StorageService storageService; + + /** + * 创建商品分享图 + * + * @param goodId + * @param goodPicUrl + * @param goodName + */ + public void createGoodShareImage(String goodId, String goodPicUrl, String goodName) { + try { + //创建该商品的二维码 + File file = wxMaService.getQrcodeService().createWxaCodeUnlimit(goodId, "pages/index/index"); + FileInputStream inputStream = new FileInputStream(file); + //将商品图片,商品名字画到模版图中 + byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName); + MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), "image/jpeg", imageData); + //存储分享图 + storageService.store(multipartFile, getKeyName(goodId)); + } catch (WxErrorException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String getShareImageUrl(String goodId) { + return storageService.generateUrl(getKeyName(goodId)); + } + + private String getKeyName(String goodId) { + return "GOOD_QCODE_" + goodId; + } + + /** + * 将商品图片,商品名字画到模版图中 + * + * @param qrCodeImg 二维码图片 + * @param goodPicUrl 商品图片地址 + * @param goodName 商品名称 + * @return + * @throws IOException + */ + private byte[] drawPicture(InputStream qrCodeImg, String goodPicUrl, String goodName) throws IOException { + //底图 + ClassPathResource redResource = new ClassPathResource("back.jpg"); + BufferedImage red = ImageIO.read(redResource.getInputStream()); + + //商品图片 + URL avatarUrl = new URL(goodPicUrl); + BufferedImage goodImage = ImageIO.read(avatarUrl); + + //小程序二维码 +// URL qrCodeUrl = new URL(qrCodeImg); + BufferedImage qrCodeImage = ImageIO.read(qrCodeImg); + + + // --- 画图 --- + + //底层空白 bufferedImage + BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); + + //画上图片 + drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight()); + + //画上商品图片 + drawImgInImg(baseImage, goodImage, 24, 24, 520, 520); + + + //画上小程序二维码 + drawImgInImg(baseImage, qrCodeImage, 143, 770, 280, 280); + + + //写上商品名称 + drawTextInImg(baseImage, goodName, 143, 614); + + + //转jpg + BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage + .getHeight(), BufferedImage.TYPE_3BYTE_BGR); + result.getGraphics().drawImage(baseImage, 0, 0, null); + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + ImageIO.write(result, "jpg", bs); + + //最终byte数组 + return bs.toByteArray(); + } + + private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) { + Graphics2D g2D = (Graphics2D) baseImage.getGraphics(); + g2D.setColor(new Color(167, 136, 69)); + g2D.setFont(new Font("黑体", Font.PLAIN, 42)); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2D.drawString(textToWrite, x, y); + g2D.dispose(); + } + + private void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite, int x, int y, int width, int heigth) { + Graphics2D g2D = (Graphics2D) baseImage.getGraphics(); + g2D.drawImage(imageToWrite, x, y, width, heigth, null); + g2D.dispose(); + } +} diff --git a/litemall-core/src/main/resources/back.jpg b/litemall-core/src/main/resources/back.jpg new file mode 100644 index 00000000..159bfdac Binary files /dev/null and b/litemall-core/src/main/resources/back.jpg differ diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java index eca36c4d..ec70e2c6 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java @@ -2,12 +2,10 @@ package org.linlinjava.litemall.wx.web; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import me.chanjar.weixin.common.exception.WxErrorException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.linlinjava.litemall.core.notify.NotifyService; import org.linlinjava.litemall.core.notify.NotifyType; -import org.linlinjava.litemall.core.notify.SmsResult; import org.linlinjava.litemall.core.util.CharUtil; import org.linlinjava.litemall.core.util.JacksonUtil; import org.linlinjava.litemall.core.util.RegexUtil; @@ -137,7 +135,7 @@ public class WxAuthController { WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code); sessionKey = result.getSessionKey(); openId = result.getOpenid(); - } catch (WxErrorException e) { + } catch (Exception e) { e.printStackTrace(); } diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxGoodsController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxGoodsController.java index 19940bf4..1d4dfd2e 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxGoodsController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxGoodsController.java @@ -3,6 +3,7 @@ package org.linlinjava.litemall.wx.web; import com.mysql.jdbc.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.linlinjava.litemall.core.qcode.QCodeService; import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.db.domain.*; import org.linlinjava.litemall.db.service.*; @@ -49,6 +50,8 @@ public class WxGoodsController { private LitemallSearchHistoryService searchHistoryService; @Autowired private LitemallGoodsSpecificationService goodsSpecificationService; + @Autowired + private QCodeService qCodeService; /** @@ -147,6 +150,9 @@ public class WxGoodsController { data.put("attribute", goodsAttributeList); data.put("brand", brand); + //商品分享图片地址 + data.put("shareImage", qCodeService.getShareImageUrl(info.getId().toString())); + return ResponseUtil.ok(data); } diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java index 1599cc74..b3ce5268 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java @@ -548,7 +548,7 @@ public class WxOrderController { String orderSn = result.getOutTradeNo(); String payId = result.getTransactionId(); // 分转化成元 - String totalFee = BaseWxPayResult.feeToYuan(result.getTotalFee()); + String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee()); LitemallOrder order = orderService.findBySn(orderSn); if (order == null) { diff --git a/pom.xml b/pom.xml index aa99675a..9ef2bd8d 100644 --- a/pom.xml +++ b/pom.xml @@ -86,13 +86,13 @@ com.github.binarywang weixin-java-pay - 3.0.0 + 3.1.0 com.github.binarywang weixin-java-miniapp - 3.0.0 + 3.1.0