yujian
2019-05-20 c4d752a1d340652d9c7d2abb5abff65cdee40d69
邀请素材管理、邀请素材画图
9个文件已修改
437 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/controller/client/ShareController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/dynamic/DynamicInfo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/dynamic/DynamicInfoServiceImpl.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/QrCodeServiceImpl.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/SpreadUserImgServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/dynamic/DynamicInfoService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/QrCodeService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/SpreadUserImgService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/ImageUtil.java 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/ShareController.java
@@ -800,10 +800,33 @@
                    data.put("inviteLink", shortLink);
                    data.put("inviteCode", inviteCode);
                    data.put("helpLink", configService.get("invite_help_link"));
                    // 邀请图片
                    // 邀请背景图片
                    List<GoodsPicture> imgs = dynamicInfo.getImgs();
                    String imgLink = spreadUserImgService.getInviteImg(uid, imgs.get(0).getUrl(), inviteCode);
                    String bgUrl = imgs.get(0).getUrl();
                    // 用户信息
                    UserInfo userInfo = userInfoService.selectByPKey(uid);
                    String portrait = userInfo.getPortrait();
                    // 画邀请图片
                    if (StringUtil.isNullOrEmpty(dynamicInfo.getInviteMaterialId())) {
                        String imgLink = spreadUserImgService.getInviteImg(bgUrl,uid, portrait, inviteCode);
                    data.put("imgLink", imgLink);
                    } else {
                        String title ="";
                        List<ClientTextStyleVO> listTitle = dynamicInfo.getTitle();
                        if (listTitle != null && listTitle.size() > 0) {
                            for (ClientTextStyleVO textStyleVO : listTitle) {
                                title += textStyleVO.getContent();
                            }
                        }
                        title = title.replace("【邀请码】", inviteCode);
                        title = title.replace("【邀请链接】", UserUtil.getInviteShortLink(uid));
                        String imgLink = spreadUserImgService.getInviteImgToGreet(bgUrl,uid, portrait, inviteCode, title, new Date());
                        data.put("imgLink", imgLink);
                    }
                    
                    //  邀请规则
                    BusinessSystem system = new BusinessSystem();
fanli/src/main/java/com/yeshi/fanli/entity/dynamic/DynamicInfo.java
@@ -91,6 +91,18 @@
    @Field("activityId")
    private Long activityId;
    // 邀请素材id
    @Field("inviteMaterialId")
    private String inviteMaterialId;
    public String getInviteMaterialId() {
        return inviteMaterialId;
    }
    public void setInviteMaterialId(String inviteMaterialId) {
        this.inviteMaterialId = inviteMaterialId;
    }
    public DynamicInfo() {
    }
fanli/src/main/java/com/yeshi/fanli/service/impl/dynamic/DynamicInfoServiceImpl.java
@@ -1,5 +1,6 @@
package com.yeshi.fanli.service.impl.dynamic;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
@@ -21,6 +22,7 @@
import com.yeshi.fanli.entity.bus.clazz.GoodsClass;
import com.yeshi.fanli.entity.dynamic.DynamicInfo;
import com.yeshi.fanli.entity.dynamic.GoodsPicture;
import com.yeshi.fanli.entity.dynamic.InviteMaterial;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBriefExtra;
import com.yeshi.fanli.entity.taobao.TaoBaoShop;
@@ -30,10 +32,12 @@
import com.yeshi.fanli.service.inter.activity.ActivityUserService;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.dynamic.DynamicInfoService;
import com.yeshi.fanli.service.inter.dynamic.InviteMaterialService;
import com.yeshi.fanli.service.inter.goods.TaoBaoGoodsBriefService;
import com.yeshi.fanli.service.inter.hongbao.HongBaoManageService;
import com.yeshi.fanli.service.inter.taobao.TaoBaoShopService;
import com.yeshi.fanli.service.inter.taobao.dataoke.DaTaoKeGoodsService;
import com.yeshi.fanli.service.inter.user.QrCodeService;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
@@ -74,6 +78,13 @@
    
    @Resource
    private TaoBaoShopService taoBaoShopService;
    @Resource
    private InviteMaterialService inviteMaterialService;
    @Resource
    private QrCodeService qrCodeService;
    
    @Override
    public void insert(DynamicInfo record) {
@@ -748,4 +759,79 @@
            e.printStackTrace();
        }
    }
    @Override
    public void insertTimeInvite() {
        InviteMaterial inviteMaterial = inviteMaterialService.getInviteMaterial();
        if (inviteMaterial == null) {
            return;
        }
        String materialId = inviteMaterial.getId();
        String content = inviteMaterial.getText();
        if (!StringUtil.isNullOrEmpty(content)) {
            DynamicInfo dynamicTxt= new DynamicInfo();
            dynamicTxt.setId(UUID.randomUUID().toString().replace("-", ""));
            dynamicTxt.setInviteMaterialId(materialId);
            dynamicTxt.setClassId(4L);
            dynamicTxt.setSubclassId(0L);
            dynamicTxt.setShowType(DynamicInfo.SHOW_TYPE_ZERO);
            dynamicTxt.setShareType(DynamicInfo.SHARE_TYPE_INVITE);
            dynamicTxt.setUser(activityUserService.listRand(1).get(0));
            dynamicTxt.setShareCount(1000 + (int) (Math.random() * 8000));
            dynamicTxt.setCreateTime(new Date());
            dynamicTxt.setUpdateTime(new Date());
            ClientTextStyleVO row1 = new ClientTextStyleVO();
            row1.setColor("#333333");
            row1.setContent(content);
            List<ClientTextStyleVO> listtitle = new ArrayList<ClientTextStyleVO>();
            listtitle.add(row1);
            dynamicTxt.setTitle(listtitle);
            // 空数据
            List<GoodsPicture> listImg = new ArrayList<GoodsPicture>();
            dynamicTxt.setImgs(listImg);
            dynamicInfoDao.insert(dynamicTxt);
        }
        String picture = inviteMaterial.getPicture();
        if (!StringUtil.isNullOrEmpty(picture)) {
            DynamicInfo dynamicPic = new DynamicInfo();
            dynamicPic.setId(UUID.randomUUID().toString().replace("-", ""));
            dynamicPic.setInviteMaterialId(materialId);
            dynamicPic.setClassId(4L);
            dynamicPic.setSubclassId(0L);
            dynamicPic.setShowType(DynamicInfo.SHOW_TYPE_ONE);
            dynamicPic.setShareType(DynamicInfo.SHARE_TYPE_INVITE);
            dynamicPic.setUser(activityUserService.listRand(1).get(0));
            dynamicPic.setShareCount(1000 + (int) (Math.random() * 8000));
            dynamicPic.setCreateTime(new Date());
            dynamicPic.setUpdateTime(new Date());
            try {
                // 画图
                String url = qrCodeService.drawInviteToGreet(picture, null, null, null, content, new Date());
                List<ClientTextStyleVO> listtitle = new ArrayList<ClientTextStyleVO>();
                dynamicPic.setTitle(listtitle);
                GoodsPicture p2 = new GoodsPicture();
                p2.setW(100);
                p2.setH(100);
                p2.setUrl(url);
                List<GoodsPicture> listImg = new ArrayList<GoodsPicture>();
                listImg.add(p2);
                dynamicPic.setImgs(listImg);
                dynamicInfoDao.insert(dynamicPic);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 更新素材状态
        inviteMaterialService.updateState(1, materialId);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/QrCodeServiceImpl.java
@@ -4,10 +4,14 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.QRCodeUtil;
import org.yeshi.utils.tencentcloud.COSManager;
import com.yeshi.fanli.dao.mybatis.share.ShareMapper;
import com.yeshi.fanli.service.inter.user.QrCodeService;
@@ -16,9 +20,6 @@
import com.yeshi.fanli.util.FileUtil;
import com.yeshi.fanli.util.ImageUtil;
import com.yeshi.fanli.util.StringUtil;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.QRCodeUtil;
import org.yeshi.utils.tencentcloud.COSManager;
@Service
public class QrCodeServiceImpl implements QrCodeService {
@@ -130,4 +131,77 @@
        return null;
    }
    @Override
    public String drawInviteToGreet(String url, Long uid, String portrait, String inviteCode, String content,
            Date date) throws IOException {
        if (StringUtil.isNullOrEmpty(url)) {
            return null;
        }
        String targetPath = null;
        String erCodeTempPath = null;
        InputStream erCodeInputStream  = null; // 二维码
        InputStream portraitInputStream = null; // 头像
        InputStream urlInputStream = HttpUtil.getAsInputStream(url); // 背景
        if (uid == null) {
            targetPath = FileUtil.getCacheDir() + "/share_official" + System.currentTimeMillis() + ".jpg";
            // 官方 邀请码(无效的)
            inviteCode = "FLQAPP";
            // 官方二维码
            erCodeInputStream = ImageUtil.class.getClassLoader().getResourceAsStream("image/official.png");
            // 官方默认头像
            portraitInputStream = ImageUtil.class.getClassLoader().getResourceAsStream("image/official_icon.png");
        } else {
            targetPath = FileUtil.getCacheDir() + "/share_" + uid + "_" + System.currentTimeMillis() + ".jpg";
            erCodeTempPath = FileUtil.getCacheDir() + "/" + uid + "_" + System.currentTimeMillis() + ".jpg";
            String erCode = HttpUtil.getShortLink("http://" + Constant.wxGZConfig.getLoginHost() + "/"
                    + Constant.systemCommonConfig.getProjectName() + "/client/threeShareNew?uid=" + uid);
            // 生成
            try {
                QRCodeUtil.getInstance(250).encode(erCode, erCodeTempPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
            erCodeInputStream = new FileInputStream(new File(erCodeTempPath));
        }
        // 开始根据 url(背景图), qrCode(二维码), portrait(头像) 生成图片
        ImageUtil.drawInviteToGreet(urlInputStream, portraitInputStream, erCodeInputStream, targetPath, inviteCode, content, date);
        // 上传文件
        if (new File(targetPath).exists() && new File(targetPath).length() > 0) {
            // 将url 转为 md5 让到下面中添加 在比较md5的值
            int index = url.lastIndexOf("/");
            String newUrl = url.substring(index + 1);
            String urlMd5 = newUrl.substring(0, newUrl.lastIndexOf("."));
            // 上传文件相对位置
            String fileUrl= null;
            if (uid == null) {
                fileUrl="ercode/" + "ercode_official" + "_" + urlMd5 + ".jpg";
            } else {
                fileUrl="ercode/" + "ercode_" + uid + "_" + urlMd5 + ".jpg";
                if (new File(erCodeTempPath).exists())
                    new File(erCodeTempPath).delete();
            }
            String imgUrl = COSManager.getInstance().uploadFile(new File(targetPath), fileUrl).getUrl();
            if (new File(targetPath).exists())
                new File(targetPath).delete();
            return imgUrl;
        }
        return null;
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/SpreadUserImgServiceImpl.java
@@ -252,8 +252,13 @@
    
    @Override
    public String getInviteImg(Long uid, String bgImg, String inviteCode) throws Exception {
        UserInfo user = userInfoDao.find(UserInfo.class, uid);
        return qrCodeService.drawInviteQrCode(bgImg, uid, user.getPortrait(), inviteCode);
    public String getInviteImg(String bgImg, Long uid, String portrait, String inviteCode) throws Exception {
        return qrCodeService.drawInviteQrCode(bgImg, uid, portrait, inviteCode);
    }
    @Override
    public String getInviteImgToGreet(String bgImg, Long uid,  String portrait, String inviteCode, String content, Date date) throws Exception {
        return qrCodeService.drawInviteToGreet(bgImg, uid,portrait, inviteCode, content, date);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/inter/dynamic/DynamicInfoService.java
@@ -78,4 +78,9 @@
     */
    public void deleteActivity(Long activityId);
    /**
     * 定时更新邀请素材信息
     */
    public void insertTimeInvite();
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/QrCodeService.java
@@ -1,6 +1,7 @@
package com.yeshi.fanli.service.inter.user;
import java.io.IOException;
import java.util.Date;
public interface QrCodeService {
@@ -37,4 +38,18 @@
     */
    String drawInviteQrCode(String url, Long uid, String portrait, int erCodePostionX, int erCodePostionY,
            int erCodeSize,String inviteCode) throws IOException;
    /**
     * 邀请问候
     * @param url 背景图链接
     * @param uid  用户id 为空时默认官网
     * @param portrait   头像          为空时默认官网
     * @param inviteCode 邀请码      为空时默认官网
     * @param content  图片文字内容
     * @param date   日期
     * @return
     * @throws IOException
     */
    public String drawInviteToGreet(String url, Long uid, String portrait, String inviteCode, String content, Date date)
            throws IOException;
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/SpreadUserImgService.java
@@ -1,5 +1,6 @@
package com.yeshi.fanli.service.inter.user;
import java.util.Date;
import java.util.List;
public interface SpreadUserImgService {
@@ -49,7 +50,28 @@
     */
    String getUserSpreadImg(Long uid, String bgImg, int erCodePostionX, int erCodePostionY, int erCodeSize);
    /**
     *  根据图片画二维码
     * @param uid
     * @param bgImg
     * @param inviteCode
     * @return
     * @throws Exception
     */
    String getInviteImg(String bgImg, Long uid, String portrait, String inviteCode) throws Exception;
    
    String getInviteImg(Long uid, String bgImg, String inviteCode) throws Exception;
    /**
     * 邀请图片 问候
     * @param bgImg
     * @param uid
     * @param portrait
     * @param inviteCode
     * @param content
     * @param date
     * @return
     * @throws Exception
     */
    public String getInviteImgToGreet(String bgImg, Long uid, String portrait, String inviteCode, String content, Date date)
            throws Exception;
}
fanli/src/main/java/com/yeshi/fanli/util/ImageUtil.java
@@ -22,12 +22,15 @@
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.imageio.ImageIO;
import org.yeshi.utils.DateLunarUtil;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.entity.DateInfo;
import com.yeshi.fanli.entity.bus.activity.RecommendActivityTaoBaoGoods;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
@@ -1172,4 +1175,178 @@
        return new int[] { width, height };
    }
    /**
     * 绘制邀请问候图
     * @param bgPigInStream  背景图
     * @param portraitInStream  用户头像
     * @param erCodeInStream    二维码
     * @param targetPath    路径
     * @param inviteCode    邀请码
     * @param content       文字内容
     * @param date            显示日历
     * @throws IOException
     */
    public static void drawInviteToGreet(InputStream bgPigInStream, InputStream portraitInStream,
            InputStream erCodeInStream, String targetPath, String inviteCode, String content, Date date)
            throws IOException {
        // 背景图片
        BufferedImage bgImage = ImageIO.read(bgPigInStream);
        final BufferedImage targetImg = new BufferedImage(bgImage.getWidth(), bgImage.getHeight(),
                BufferedImage.TYPE_INT_RGB);
        HashMap<Key, Object> mapH = new HashMap<Key, Object>();
        mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)  
        mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿 
        // 画 背景图片
        final Graphics2D g2d = targetImg.createGraphics();
        g2d.drawImage(bgImage, 0, 0, bgImage.getWidth(), bgImage.getHeight(), null);
        g2d.setRenderingHints(mapH);
        // 画 蒙层
        BufferedImage mengCeng = ImageIO
                .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/invite/mc.png"));
        g2d.drawImage(mengCeng, 0, bgImage.getHeight() / 2, bgImage.getWidth(), bgImage.getHeight() / 2, null);
        int width = bgImage.getWidth();
        int height = bgImage.getHeight();
        int pX = width - 250;
        int pY = height - 290; // 320
        int size = 210; // 230
        // 画 二维码
        BufferedImage qrCodeImage = ImageIO.read(erCodeInStream);
        qrCodeImage = ImageUtil.qrCodeImage(g2d, qrCodeImage, pX, pY, size, size); // 二维码长宽
        // 230*230
        // 画 头像
        int portraitSize = size * 5 / 23;
        int pPX = pX + size / 2 - portraitSize / 2;
        int pPY = pY + size / 2 - portraitSize / 2;
        BufferedImage portraitImg = ImageIO.read(portraitInStream);
        portraitImg = ImageUtil.portraitImg(g2d, portraitImg, pPX, pPY, portraitSize, portraitSize);// 头像长宽
        // 文字白色
        Color color = new Color(255, 255, 255);
        String os = System.getProperty("os.name");
        String fontBoldPath = "/usr/share/fonts/yahei.ttf";
        if (os.toLowerCase().startsWith("win")) {
            fontBoldPath = "D:/yahei.ttf";
        }
        Font boldFont = null;
        // 画邀请码(邀请码的大小与字体固定)
        if (!StringUtil.isNullOrEmpty(inviteCode)) {
            String st = "邀请码:" + inviteCode;
            try {
                boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(32.0f);
            } catch (FontFormatException e) {
                e.printStackTrace();
            }
            g2d.setFont(boldFont);
            g2d.setColor(new Color(255, 255, 255));
            FontMetrics fm = g2d.getFontMetrics(boldFont);
            int textLength = fm.stringWidth(st);
            int ax = (width - textLength) - 30;
            int ay = bgImage.getHeight() - 50 + boldFont.getSize() / 2 - 5;
            g2d.setColor(new Color(255, 255, 255));
            g2d.drawString(st, ax, ay);
        }
        // 左边距
        int padding_left = 30;
        // 日历
        try {
            if (date == null) {
                date = new Date();
            }
            boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(36.0f);
            g2d.setFont(boldFont);
            g2d.setColor(color);
            g2d.setRenderingHints(mapH);
            DateInfo dateInfo = DateLunarUtil.getDateInfo(date);
            // 农历
            g2d.drawString(dateInfo.getLunar_month() + dateInfo.getLunar_day(), padding_left, height - 80);
            // 天干地支
            g2d.drawString(dateInfo.getAgenary_month() + " " + dateInfo.getAgenary_day(), padding_left, height - 140);
            // 当前日期
            Font boldFontMax = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(100.0f);
            g2d.setFont(boldFontMax);
            if (dateInfo.getDay() < 10) {
                g2d.drawString("0" + dateInfo.getDay().toString(), padding_left, height - 200);
            } else {
                g2d.drawString(dateInfo.getDay().toString(), padding_left, height - 200);
            }
            String theDate = "";
            if (dateInfo.getMonth() < 10) {
                theDate = "/0";
            } else {
                theDate = "/";
            }
            theDate += dateInfo.getMonth() + "/" + dateInfo.getYear() + " " + dateInfo.getWeekDay();
            g2d.setFont(boldFont);
            g2d.drawString(theDate, padding_left + boldFontMax.getSize() + 15, height - 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!StringUtil.isNullOrEmpty(content)) {
            // 文字内容
            try {
                boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(36.0f);
                g2d.setFont(boldFont);
                g2d.setColor(color);
                g2d.setRenderingHints(mapH);
                int lineHeight = 70;
                int lineTextLength = 19;
                if (content.length() <= lineTextLength) {
                    g2d.drawString(content, padding_left, height - 350);
                } else {
                    String text = "";
                    int mod = content.length() % lineTextLength;
                    if (mod == 0) {
                        text = content.substring(content.length() - lineTextLength, content.length());
                        content = content.substring(0, content.length() - lineTextLength);
                    } else {
                        text = content.substring(content.length() - mod, content.length());
                        content = content.substring(0, content.length() - mod);
                    }
                    g2d.drawString(text, padding_left, height - 350);
                    int i = 1;
                    while (true) {
                        if (content.length() <= 17) {
                            g2d.drawString(content, padding_left, height - 350 - lineHeight * i);
                            break;
                        } else {
                            text = content.substring(content.length() - lineTextLength, content.length());
                            content = content.substring(0, content.length() - lineTextLength);
                            g2d.drawString(text, padding_left, height - 350 - lineHeight * i);
                            i++;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        OutputStream out = new FileOutputStream(new File(targetPath));
        ImageIO.write(targetImg, "JPEG", out);
        out.flush();
        out.close();
    }
}