海豚精灵:https://www.whhtjl.com;优课GO:https://mgo.whhtjl.com;张新民;财务报表分析

我们先看效果图:

项目地址:https://mgo.whhtjl.com/coursedetails/4216

我这里后端使用的SpringBoot,Maven项目,代码如下:

<!--公众号(包括订阅号和服务号) -->
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>3.9.0</version>
</dependency>

在application.properties中配置相关信息

#微信公众号
wx.mp.appId=xxxxxxxxxxxx
wx.mp.secret=xxxxxxxxxxxxxxxxxxxxxx
wx.mp.subscribeUri=https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIxMTM3NzcxMw==&scene=%s#wechat_redirect

创建需要的实体类

package com.ltf.entity;import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;/*** 第三方登录用户实体类* @author xhz**/
@Data
@EqualsAndHashCode(callSuper = false)
public class UserProfile implements Serializable{private static final long serialVersionUID = 1L;private int id;//主键private String nickName;//属性名称如token,昵称private int gender;//性别(1:男;2:女)private String openId;//第三方keyprivate String unionId;//仅供微信使用private String accessToken;//仅供QQ使用private String profileType;//第三方类型:WXHD(微信海报裂变活动)private int userId;//用户idprivate Date profileDate;//添加时间private String avatar;//第三方头像private String valueTwo;//第三方key辅助private boolean subscribe;//是否关注公众号}
package com.ltf.entity;import java.io.Serializable;
import java.util.Date;
import lombok.Data;/*** 活动* @author ltf**/
@Data
public class WxTaskDTO implements Serializable{private static final long serialVersionUID = 1L;private int taskId;private int taskCourseId;private String taskSubject;private Date inittime;private Date endtime;private String content;private String templateactorurl;private String templatefinishurl;private String templatefinishurl2;private String templatefinishurl3;private int counts;private int counts2;private int counts3;private String hbinfo;}
package com.ltf.entity;import java.io.Serializable;
import java.util.Date;
import lombok.Data;/*** 活动* @author ltf**/
@Data
public class WxTaskProgressDTO implements Serializable{private static final long serialVersionUID = 1L;private int id;private int taskId;private int initUserId;private int pUserId;private Date cctime;}
package com.ltf.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 文件上传* @author xhz**/
@Data
@Component
@ConfigurationProperties(prefix = "youkego.file")
public class FileConfig {private String uploadPath;//上传路径private String username;//用户名private String password;//密码private String rootDirectory;//根目录private String  hdImages;//海报裂变路径}

创建dao层

package com.ltf.dao;import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.ltf.entity.UserProfile;/*** 用户第三方登录dao层* @author xhz**/
@Mapper
public interface UserProfileDao {//表名String TABLE_NAME = "edu_user_profile";//插入的字段String INSERT_FIELDS = " nick_name, gender, open_id, union_id, access_token, profile_type, user_id, profile_date, avatar, value_two,subscribe ";//查找的字段String SELECT_FIELDS = " id, " + INSERT_FIELDS;/***  修改用户第三方登录信息* @param userProfile*/public void updateUserProfile(UserProfile userProfile);/*** 更新微信openId查询唯一用户* @param openId* @return*/@Select({"select ",SELECT_FIELDS," from ",TABLE_NAME," where open_id=#{openId}"})public UserProfile queryUserProfileByOpenId(String openId);}
package com.ltf.dao;import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.ltf.entity.WxTaskDTO;/*** 微信海报裂变活动* @author ltf**/
@Mapper
public interface WxTaskDao {//表名String TABLE_NAME = "wxtask";//插入的字段String INSERT_FIELDS = " taskCourseId, taskSubject, inittime, endtime, content, templateactorurl, templatefinishurl, templatefinishurl2, templatefinishurl3, counts, counts2,counts3, hbinfo";//查找的字段String SELECT_FIELDS = " taskId, " + INSERT_FIELDS;/*** 根据taskId查找* @param id* @return*/@Select({"select", SELECT_FIELDS, " from ", TABLE_NAME, " where taskId=#{taskId}"})WxTaskDTO getWxTaskInfoByTaskId(int taskId);@Select({"select", SELECT_FIELDS, " from ", TABLE_NAME, " where endtime>now()"})List<WxTaskDTO> getWxTaskInfoActivty();}
package com.ltf.dao;import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import com.ltf.entity.WxTaskProgressDTO;/*** 微信海报裂变活动* @author ltf**/
@Mapper
public interface WxTaskProgressDao {//表名String TABLE_NAME = "wxtaskprogress";//插入的字段String INSERT_FIELDS = " taskId, initUserId, pUserId, cctime";//查找的字段String SELECT_FIELDS = " id, " + INSERT_FIELDS;/*** 根据taskId查找* @param id* @return*/@Select({"select "+SELECT_FIELDS+" from wxtaskprogress where id=#{id}"})WxTaskProgressDTO getWxTaskInfoProcessByTaskId(int id);@Select({"select "+SELECT_FIELDS+" from wxtaskprogress where taskId=#{taskId} and pUserId=#{pUserId}"})WxTaskProgressDTO getWxTaskInfoProcessByTPID(int taskId,int pUserId);/*** 插入一条记录* @return*/@Insert(value = { "insert into "+TABLE_NAME+"("+INSERT_FIELDS+") values(#{taskId},#{initUserId},#{pUserId},NOW())"})@Options(useGeneratedKeys=true, keyColumn="id", keyProperty="id")void insertWxTaskProcess(WxTaskProgressDTO dto);/*** 查询完成数量* @param taskId* @param initUserId* @return*/@Select({"select count(1) as fcounts from wxtaskprogress where taskId=#{taskId} and initUserId=#{initUserId}"})int selectFinshCounts(int taskId,int initUserId);}

创建service类

package com.ltf.service;import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.ltf.common.CacheConstans;
import com.ltf.common.CommonConstants;
import com.ltf.dao.UserProfileDao;
import com.ltf.entity.UserProfile;
import com.ltf.utils.DateUtils;
import com.ltf.utils.MD5;
import com.ltf.utils.ObjectUtils;
import com.ltf.utils.StringUtils;/*** 用户第三方登录service层* @author xhz**/
@Service
public class UserProfileService {private static final Logger logger = LoggerFactory.getLogger(UserProfileService.class);@Autowiredprivate UserProfileDao userProfileDao;/*** 活动海报,不形成上下级绑定关系* @param userProfile* @return*/public Map<String,Object> autoRegisterByWxHd(UserProfile userProfile) {Map<String, Object> map = new HashMap<String, Object>();try {UserProfile queryUserProfile = userProfileDao.queryUserProfileByOpenId(userProfile.getOpenId());if (ObjectUtils.isNotNull(queryUserProfile)&& ObjectUtils.isNotNull(queryUserProfile.getUserId())&& queryUserProfile.getUserId()> 0) {if (StringUtils.isNotEmpty(userProfile.getValueTwo())&& StringUtils.isEmpty(queryUserProfile.getValueTwo())) {queryUserProfile.setValueTwo(userProfile.getValueTwo());}}userProfile.setProfileDate(new Date());// 下载图片userProfile.setAvatar(StringUtils.isNotEmpty(userProfile.getAvatar())?userProfile.getAvatar():"https://xxxxxxxxx/xxxxxx/htjl.jpg");// 如果已经有数据if (ObjectUtils.isNotNull(queryUserProfile)&&queryUserProfile.getUserId() == 0) {// 未绑定用户 更新库中 userProfileuserProfile.setId(queryUserProfile.getId());userProfile.setUserId(queryUserProfile.getUserId());//System.out.println("更新用户"+queryUserProfile);userProfileDao.updateUserProfile(userProfile);return map;} else {//System.out.println("老用户无需添加或者更新");}} catch (Exception e) {logger.error("UserProfileService.autoRegisterByWxHd()----error", e);}return map;}}

创建海报裂变控制层

package com.ltf.controller;import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ltf.config.FileConfig;
import com.ltf.dao.IWxPushKfMessage;
import com.ltf.dao.SysWxOpencofigDao;
import com.ltf.dao.UserDao;
import com.ltf.dao.WxAuthinfoDao;
import com.ltf.dao.WxTaskDao;
import com.ltf.dao.WxTaskProgressDao;
import com.ltf.entity.User;
import com.ltf.entity.UserProfile;
import com.ltf.entity.WxAuthinfoDTO;
import com.ltf.entity.WxTaskDTO;
import com.ltf.entity.WxTaskProgressDTO;
import com.ltf.service.UserProfileService;
import com.ltf.utils.StringUtils;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.open.api.WxOpenService;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;@Controller
@RequestMapping("/xwyz")
public class WxOpenController {private final Logger logger = LoggerFactory.getLogger(this.getClass());private static final Map<String, WxMpMessageRouter> wxOpenMpMessageRouterMap = new Hashtable<String, WxMpMessageRouter>();private static final Map<String, String> auth_refresh_tocken_Map = new Hashtable<String, String>();@Autowiredprivate IWxPushKfMessage iWxPushKfMessage;@Autowiredprivate WxOpenService wxOpenService;@Autowiredprivate WxAuthinfoDao wxAuthinfo;@Autowiredprivate SysWxOpencofigDao sysWxOpencofigDao;@Autowiredprivate UserProfileService userProfileService;@Autowiredprivate WxTaskDao wxTaskDao;@Autowiredprivate WxTaskProgressDao wxTaskProgressDao;@Autowiredprivate UserDao userDao;@Autowiredprivate WxMpService jsWxMpService;@Autowiredprivate FileConfig fileConfig;@RequestMapping("{appId}/callback")public void callback(@RequestBody(required = false) String requestBody, @PathVariable("appId") String appId,@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp,@RequestParam("nonce") String nonce, @RequestParam("openid") String openid,@RequestParam("encrypt_type") String encType, @RequestParam("msg_signature") String msgSignature,HttpServletResponse response) {this.logger.info("\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);if (!StringUtils.equalsIgnoreCase("aes", encType)|| !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");}// aes加密的消息WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody,wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);if (StringUtils.isEmpty(wxOpenService.getWxOpenConfigStorage().getAuthorizerRefreshToken(appId))) {String appId_token = getWxMpAuthRefreshTockenByAppid(appId);wxOpenService.getWxOpenConfigStorage().setAuthorizerRefreshToken(appId, appId_token);}WxMpXmlOutMessage outMessage = getWxMpMessageRouterByAppid(appId).route(inMessage);if (outMessage != null) {try {response.getWriter().write(outMessage.toEncryptedXml(wxOpenService.getWxOpenConfigStorage().getWxMpConfigStorage(appId)));} catch (IOException e) {e.printStackTrace();}}}private String getWxMpAuthRefreshTockenByAppid(String appId) {String token = auth_refresh_tocken_Map.get(appId);if (StringUtils.isEmpty(token)) {token = wxAuthinfo.selectWxAuthinfo(appId);auth_refresh_tocken_Map.put(appId, token);}return token;}public WxMpMessageRouter getWxMpMessageRouterByAppid(String appId) {WxMpMessageRouter wxMpMessageRouter = wxOpenMpMessageRouterMap.get(appId);if (wxMpMessageRouter == null) {synchronized (wxOpenMpMessageRouterMap) {wxMpMessageRouter = wxOpenMpMessageRouterMap.get(appId);if (wxMpMessageRouter == null) {wxMpMessageRouter = new WxMpMessageRouter(wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId));wxOpenMpMessageRouterMap.put(appId, wxMpMessageRouter);addTxtMsgRouter(appId, wxMpMessageRouter);addEventRouter(appId, wxMpMessageRouter);}}}return wxMpMessageRouter;}private void addEventRouter(final String appId, WxMpMessageRouter wxMpMessageRouter) {WxMpMessageHandler handler = new WxMpMessageHandler() {public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {WxMpXmlOutTextMessage m = null;// 订阅事件if (wxMessage.getEvent().equals(WxConsts.EventType.SUBSCRIBE)) {if (wxMessage.getEventKey().startsWith("qrscene_") && wxMessage.getTicket() != null) {System.out.println("用户未关注时,进行关注后的事件推送 扫描推送");actorService(wxMpService, wxMessage, true);}} else if (wxMessage.getEvent().equals(WxConsts.EventType.SCAN)) {// 扫码 用户已关注时的事件推送if (wxMessage.getEventKey() != null || wxMessage.getTicket() != null) {actorService(wxMpService, wxMessage, true);}} else if (wxMessage.getEvent().equals(WxConsts.EventType.CLICK)) {// 自定义菜单点击事件if (wxMessage.getEventKey() != null && !wxMessage.getEventKey().equals("")) {System.out.println("事件KEY值,与自定义菜单接口中KEY值对应");}} else if (wxMessage.getEvent().equals(WxConsts.EventType.VIEW)) {System.out.println("点击菜单跳转链接时的事件推送");}return m;}};wxMpMessageRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).handler(handler).end();}private void addTxtMsgRouter(final String appId, WxMpMessageRouter wxMpMessageRouter) {WxMpMessageHandler handler = new WxMpMessageHandler() {public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {WxMpXmlOutTextMessage m = null;String keys = wxMessage.getContent();if (keys.startsWith("xxxxx")&& wxMessage.getFromUser().equals("DSFGDFNMHJJHJ")) {actorService(wxMpService, wxMessage, false);}return m;}};wxMpMessageRouter.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).handler(handler).end();}/*** 注意 这里的代码 是非常的不规范,目前没有精力管这些,后续有必要在调整* * @param authorizationCode* @return*/@RequestMapping("/oauthInfo")public void oauthInfo(@RequestParam("auth_code") String authorizationCode, HttpServletRequest request,HttpServletResponse response) {try {WxOpenQueryAuthResult queryAuthResult = wxOpenService.getWxOpenComponentService().getQueryAuth(authorizationCode);String appId = queryAuthResult.getAuthorizationInfo().getAuthorizerAppid();WxOpenAuthorizerInfoResult info = wxOpenService.getWxOpenComponentService().getAuthorizerInfo(appId);WxAuthinfoDTO dto = new WxAuthinfoDTO();String func_info = "";List<Integer> list = info.getAuthorizationInfo().getFuncInfo();for (Integer integer : list) {func_info += integer + ",";}func_info = func_info.substring(0, func_info.length() - 1);dto.setWxappid(info.getAuthorizationInfo().getAuthorizerAppid());dto.setFuncInfo(func_info);dto.setNickName(info.getAuthorizerInfo().getNickName());dto.setHeadImg(info.getAuthorizerInfo().getHeadImg());dto.setServiceTypeInfo(info.getAuthorizerInfo().getServiceTypeInfo());dto.setVerifyTypeInfo(info.getAuthorizerInfo().getVerifyTypeInfo());dto.setUserName(info.getAuthorizerInfo().getUserName());dto.setPrincipalName(info.getAuthorizerInfo().getPrincipalName());dto.setOpenStore(info.getAuthorizerInfo().getBusinessInfo().get("open_store"));dto.setOpenScan(info.getAuthorizerInfo().getBusinessInfo().get("open_scan"));dto.setOpenCard(info.getAuthorizerInfo().getBusinessInfo().get("open_card"));dto.setOpenPay(info.getAuthorizerInfo().getBusinessInfo().get("open_pay"));dto.setOpenShake(info.getAuthorizerInfo().getBusinessInfo().get("open_shake"));dto.setAlias(info.getAuthorizerInfo().getAlias());dto.setQrcodeUrl(info.getAuthorizerInfo().getQrcodeUrl());dto.setAuthorizerRefreshToken(info.getAuthorizationInfo().getAuthorizerRefreshToken());wxAuthinfo.insertAuthinfo(dto);} catch (WxErrorException e) {e.printStackTrace();}try {response.setContentType("text/html;charset=UTF-8");response.sendRedirect("https://xxxxxxxxxxx.com/");} catch (IOException e) {e.printStackTrace();}}private void actorService(WxMpService wxMpService, WxMpXmlMessage wxMessage, boolean isdefault) {try {WxMpUser userInfo = wxMpService.getUserService().userInfo(wxMessage.getFromUser());String keys = wxMessage.getContent();if (!isdefault&&keys.startsWith("xxxxxxxxx")) {keys =keys.substring(8);} else {if (wxMessage.getEventKey().startsWith("qrscene_") && wxMessage.getTicket() != null) {keys = wxMessage.getEventKey().substring(8);} else {keys = wxMessage.getEventKey();}}UserProfile userProfile = new UserProfile();userProfile.setNickName(StringUtils.filterEmoji(userInfo.getNickname()));userProfile.setGender(userInfo.getSex());userProfile.setAvatar(userInfo.getHeadImgUrl());userProfile.setOpenId(userInfo.getOpenId());userProfile.setUnionId(userInfo.getUnionId());userProfile.setProfileType("WXHD");userProfile.setSubscribe(true);userProfileService.autoRegisterByWxHd(userProfile);if (StringUtils.isNotEmpty(keys) && keys.contains("&")) {String[] array = keys.split("&");int taskId = Integer.parseInt(array[0]);int initUserId = Integer.parseInt(array[1]);WxTaskDTO wxTask = wxTaskDao.getWxTaskInfoByTaskId(taskId);// 活动时间过期了Date curTime = new Date();String nickName=StringUtils.filterEmoji(userInfo.getNickname());if(nickName==null||"".equals(nickName.trim())) nickName="❤";if (wxTask.getEndtime().getTime() < curTime.getTime()) {String content = "亲,{nickname},该活动已结束,请添加客服whhtjl,咨询最新活动~~";sendActorMessage(wxMpService, userInfo.getOpenId(), nickName, content);return;}User user = userDao.selectUserByWxOpendId(userInfo.getOpenId());if (user != null) {int pUserId = user.getId();// 理论上 user 是一定存在的 自动注册了if (pUserId == initUserId && isdefault) {// 测试流程所以注释了String content = "亲,自己不能助力自己哦~~,快去邀请好友吧~";sendActorMessage(wxMpService, userInfo.getOpenId(), userProfile.getNickName(), content);return;}WxTaskProgressDTO wxProgress = wxTaskProgressDao.getWxTaskInfoProcessByTPID(taskId, pUserId);if (wxProgress != null) {// 已经助力过了 同一个活动只能给1个用户助力String content = "亲,{nickname},您已经给其他人助力过了! 同一个活动只能给1个用户助力哦!";sendActorMessage(wxMpService, userInfo.getOpenId(), userProfile.getNickName(), content);} else {// 助力+1WxTaskProgressDTO dto=new WxTaskProgressDTO();dto.setTaskId(taskId);dto.setInitUserId(initUserId);dto.setPUserId(pUserId);dto.setCctime(new Date());wxTaskProgressDao.insertWxTaskProcess(dto);// 判断是否达成目标,并给予消息提示User init_user = userDao.getUserById(initUserId);System.out.println("被识别者:"+init_user.getUserName()+"="+init_user.getOpenId());int fcounts = wxTaskProgressDao.selectFinshCounts(taskId, initUserId);if (fcounts < wxTask.getCounts()) {String content = nickName+"已成功为您助力!\n\n再邀请"+(wxTask.getCounts()-fcounts)+"人助力即可成功领取!加油鸭~~";sendActorMessage(wxMpService, init_user.getOpenId(), init_user.getUserName(), content);} else {String content = nickName+"已成功为您助力!\n\n";content += "恭喜您已成功完成任务\n\n ☞<a href=\"" + wxTask.getTemplateactorurl() + "\">点击领取课程礼包</a>";sendActorMessage(wxMpService, init_user.getOpenId(), init_user.getUserName(), content);}String content = wxTask.getContent();content=content.replaceAll("nickName",  nickName);content=content.replaceAll("initName",  init_user.getUserName());content=content.replaceAll("totalCount",  wxTask.getCounts()+"");content=content.replaceAll("<br>", "\n");sendActorMessage(wxMpService, userInfo.getOpenId(), nickName, content);}}String scene_id=taskId+"&"+user.getId();// 自己的海报autoWxTaskHb(wxMpService, scene_id, taskId, wxTask, userInfo);}} catch (WxErrorException e) {e.printStackTrace();}}private void sendActorMessage(WxMpService wxMpService, String actor, String initnickName, String actorcontent) {WxMpKefuMessage messageInfo = new WxMpKefuMessage();messageInfo.setToUser(actor);messageInfo.setMsgType(WxConsts.KefuMsgType.TEXT);String content = actorcontent.replace("{nickname}", initnickName);messageInfo.setContent(content);try {wxMpService.getKefuService().sendKefuMessage(messageInfo);} catch (WxErrorException e) {e.printStackTrace();}}private void autoWxTaskHb(WxMpService wxMpService, String scene_id, int taskId, WxTaskDTO wxTask,WxMpUser userInfo) {try {String webPath = fileConfig.getHdImages();String posInfo = wxTask.getHbinfo();JSONObject hbInfo = JSON.parseObject(posInfo);String url = hbInfo.getString("url");String hz=url.substring(url.lastIndexOf("."));String outFilePathName = webPath + "/" + taskId + "/" + scene_id + hz;String dirPath = webPath + "/" + taskId + "/";File upload = new File(webPath, "/" + taskId + "/");if (!upload.exists())upload.mkdirs();WxMpQrCodeTicket ticker = wxMpService.getQrcodeService().qrCodeCreateLastTicket(scene_id);File coderFile = wxMpService.getQrcodeService().qrCodePicture(ticker);// 裁剪版 尽量简化FileOutputStream out = new FileOutputStream(outFilePathName);String backFileName="template"+hz;String backFilePathName=dirPath+backFileName;File backImageFile=new File(backFilePathName);if(!backImageFile.exists()) {download(url, backFileName,dirPath);backImageFile=new File(backFilePathName);}BufferedImage backImage = ImageIO.read(backImageFile);BufferedImage outImage = new BufferedImage(backImage.getWidth(), backImage.getHeight(),backImage.getType());Graphics dec = outImage.getGraphics();// 输出背景dec.drawImage(backImage, 0, 0, backImage.getWidth(), backImage.getHeight(), null);// 输出二维码BufferedImage tickImage = ImageIO.read(coderFile);dec.drawImage(tickImage, hbInfo.getJSONObject("qr_pos").getIntValue("x"),hbInfo.getJSONObject("qr_pos").getIntValue("y"), hbInfo.getJSONObject("qr_pos").getIntValue("w"),hbInfo.getJSONObject("qr_pos").getIntValue("h"), null);dec.dispose();// 输出整个图片ImageIO.write(outImage, hz.substring(1), out);outImage.flush();out.close();File file = new File(outFilePathName);WxMediaUploadResult wxResult = wxMpService.getMaterialService().mediaUpload(WxConsts.MaterialType.IMAGE,file);// 生成海报WxMpKefuMessage message = new WxMpKefuMessage();message.setToUser(userInfo.getOpenId());message.setMsgType(wxResult.getType());message.setMediaId(wxResult.getMediaId());wxMpService.getKefuService().sendKefuMessage(message);} catch (WxErrorException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 获取远程网络图片信息* * @param imageURL* @return*/private void download(String urlString, String filename, String savePath) throws Exception {URL url = new URL(urlString);URLConnection con = url.openConnection();con.setConnectTimeout(5 * 1000);InputStream is = con.getInputStream();byte[] bs = new byte[1024];int len;File sf = new File(savePath);if (!sf.exists()) {sf.mkdirs();}OutputStream os = new FileOutputStream(sf.getPath() + "/" + filename);// 开始读取while ((len = is.read(bs)) != -1) {os.write(bs, 0, len);}// 完毕,关闭所有链接os.close();is.close();}}

如何使用Java技术实现微信公众号海报裂变功能相关推荐

  1. java程序集成微信公众号模板消息功能

    要在 Java 程序中集成微信公众号模板消息功能,您需要按照以下步骤进行: 在微信公众平台上申请并获取您的公众号的 appid 和 appsecret. 使用 appid 和 appsecret 调用 ...

  2. java开发的微信公众号服务端生产环境中的两个大坑

    摘要: 我们开发的公众号,由于将功能开发完毕后,未对服务进行压力测试,因此用到的组件中的参数值全是默认的,服务上线后一段时间运行得倒没什么问题,随着服务得访问量增加,一些多线程并发的问题就逐步暴露出来 ...

  3. Java实现微信公众号客服功能和本地联调

    Java实现微信公众号客服功能 微信公众平台设置 生产环境 公众号 设置 [开发]–> [基本配置]–> [服务器配置] 注: a.服务器地址(URL) 是开发者用来接收微信消息和事件的接 ...

  4. 微信开发(3):微信公众号发现金红包功能开发,利用第三方SDK实现(Java)

    最近需求是 用户兑换微信红包,需要一些验证,加密,以及证书: 工欲善其事必先利其器 感谢前辈的微信SDK 已经维护三年了,还在维护中! 官方文档走一波 文档还是一如既往的 坑人啊,写的很简单,对简单明 ...

  5. vue 公众号扫描_vue编写微信公众号打开相机功能

    vue编写微信公众号打开相机功能,什么都不多说直接上代码 页面布局代码 class="previewer-demo-img" :key="index" :src ...

  6. 手把手教大家搭建微信公众号查题功能

    手把手教大家搭建微信公众号查题功能 本平台优点: 多题库查题.独立后台.响应速度快.全网平台可查.功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 题库:题库后台(点击跳转) ...

  7. 公众号分享页面php,微信公众号网页分享功能开发的示例代码

    现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接: 上面这个是微信的js-SDK页面分享给微信好友在聊天列表中显示的 ...

  8. 实现微信公众号评论回复功能

    最近做一个项目,实现类似微信公众号评论回复功能,如图所示: 大概分以下几个组件: 表情包组件: <template><div class="showEmjio" ...

  9. 如何给微信公众号增加留言功能?

    很多新注册了公众号的人却发现,微信公众号的留言功能没有了. 这是什么情况? 没有留言功能,我花费了N久时间精心写出来的文章只能自嗨吗? 原来腾讯从2018年3月起,取消了新注册的微信公众号的留言功能. ...

最新文章

  1. Linux的概念与体系 2. Linux文件管理(转载)
  2. nagios-3种报警方式–声音–email/邮件—短信
  3. Linux 软件看门狗 watchdog 喂狗
  4. hadoop 自定义数据类型
  5. agent python实现 建模_零基础三天学会Python爬虫(第二天)
  6. 区块链 FISCO BCOS学习文章(2)-FISCO BCOS怎么搭建
  7. 只知道人工智能远远不够 下一件大事将是边缘计算!
  8. 【三级网络技术】IP地址聚合考点
  9. 手把手教你如何自制目标检测框架(从理论到实现)
  10. Android底部菜单栏(图片+文字)
  11. mysql大小写转换函数_MySQL字母大小写转换函数UPPER(s)、UCASE(s)、LOWER(s)和LCASE(s)
  12. 1334177-81-9,S-acetyl-PEG8-alcohol乙酰硫基可以脱保护生成巯基
  13. 【AWS系列】第四讲:什么是 AWS Serverless
  14. k线符号图解大全_股市k线图各种符号意义?k线符号图解大全!
  15. 微信小程序预览 word、excel、ppt、pdf 等文件
  16. 计算机毕业设计(42)java小程序毕设作品之小说电子书阅读小程序系统
  17. Pytorch note
  18. 嘉奥(JAO.CC)办公用品专营店的网店策划
  19. verilog编程always@()内部敏感时钟不能出现时钟的上升和下降沿,行为级仿真可行,但不可综合
  20. python获取mysql中的数据供js调用_python 读取mysql数据至csv文件中,并发送邮件

热门文章

  1. SFT-250手提式安全轴流风机
  2. SwitchyOmega+Pac
  3. 校园计算机网的使用方法,校园无线网使用指南
  4. C#通过adb传输安卓设备数据
  5. js字符串如何拼接java代码_[Java教程]js拼接字符串传值,子窗口传值
  6. Surging学习笔记(一)
  7. Qualcomm 7X7 ASF锐化原理
  8. 临沂鸿蒙文化城在哪,在桑干河南舜都与鸿蒙寺遗址上
  9. 数据爆炸别担心,华为云大数据BI解决方案为你排忧解难
  10. linux创建虚拟环境(python虚拟环境)