浏览代码

添加生成商品朋友圈分享图(带二维码,扫码可以直接进入小程序指定商品位置)

Menethil 7 年之前
父节点
当前提交
264c50e195

+ 30 - 23
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<String, Integer> 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<String, Integer> 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<LitemallCategory> l1CatList = categoryService.queryL1();
         List<CatVo> 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<LitemallCategory> l2CatList = categoryService.queryByPid(l1.getId());
             List<CatVo> 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<LitemallBrand> list = brandService.all();
         List<Map<String, Object>> brandList = new ArrayList<>(l1CatList.size());
-        for(LitemallBrand brand : list){
+        for (LitemallBrand brand : list) {
             Map<String, Object> b = new HashMap<>(2);
             b.put("value", brand.getId());
             b.put("label", brand.getName());
@@ -251,7 +258,7 @@ public class AdminGoodsController {
         }
 
         Map<String, Object> 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<String, Object> data = new HashMap<>();
-        data.put("goods" ,goods);
+        data.put("goods", goods);
         data.put("specifications", specifications);
         data.put("products", products);
         data.put("attributes", attributes);

+ 6 - 0
litemall-core/pom.xml

@@ -81,6 +81,12 @@
             <artifactId>weixin-java-pay</artifactId>
             <version>3.0.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>5.0.7.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 1 - 2
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();
         }
     }

+ 129 - 0
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();
+    }
+}

二进制
litemall-core/src/main/resources/back.jpg


+ 1 - 3
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();
         }
 

+ 6 - 0
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);
     }
 

+ 1 - 1
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) {

+ 2 - 2
pom.xml

@@ -86,13 +86,13 @@
             <dependency>
                 <groupId>com.github.binarywang</groupId>
                 <artifactId>weixin-java-pay</artifactId>
-                <version>3.0.0</version>
+                <version>3.1.0</version>
             </dependency>
 
             <dependency>
                 <groupId>com.github.binarywang</groupId>
                 <artifactId>weixin-java-miniapp</artifactId>
-                <version>3.0.0</version>
+                <version>3.1.0</version>
             </dependency>
         </dependencies>
     </dependencyManagement>