admin
2019-09-05 fdfd8e3a55428bf877c0ca93914c8509309da54a
抖音广告监测
9个文件已修改
6个文件已添加
719 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/controller/DouYinCallBackController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v1/UserMsgController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/GoodsControllerV2.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/msg/UserSystemMsgMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/ad/DouYinUserActionInfo.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/ad/DouYinClickEvent.java 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/job/TaoLiJinJob.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/msg/UserSystemMsgMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/msg/UserSystemMsgServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/Constant.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/ad/DouYinAdUtil.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/vo/goods/OtherInfo.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/vo/goods/RewardCouponVO.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/HttpUtil.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/wx/WXPayUtil.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/DouYinCallBackController.java
New file
@@ -0,0 +1,27 @@
package com.yeshi.fanli.controller;
import java.io.PrintWriter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.google.gson.Gson;
import com.yeshi.fanli.entity.ad.DouYinClickEvent;
import com.yeshi.fanli.log.LogHelper;
@Controller
@RequestMapping("ad/callback/douyin")
public class DouYinCallBackController {
    /**
     * 抖音下载回调
     *
     * @param out
     */
    @RequestMapping("monitor")
    public void download(DouYinClickEvent event, PrintWriter out) {
        LogHelper.test(new Gson().toJson(event));
        out.print("success");
    }
}
fanli/src/main/java/com/yeshi/fanli/controller/client/v1/UserMsgController.java
@@ -492,6 +492,9 @@
    public void getHomeMsgList(AcceptData acceptData, Long uid, int page, HttpSession session, PrintWriter out) {
        if (uid != null && uid == 0)
            uid = null;
        if (uid != null)
            userSystemMsgService.syncSystemZNX(uid);
        String device = acceptData.getDevice();
        if (device == null || device.trim().length() == 0) {
            out.print(JsonUtil.loadFalseResult("设备号不能为空"));
@@ -659,6 +662,9 @@
    public void getHomeMsgListNew(AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid != null && uid == 0)
            uid = null;
        if (uid != null) {
            userSystemMsgService.syncSystemZNX(uid);
        }
        List<UserMsgCenter> listCenter = new ArrayList<>();
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/GoodsControllerV2.java
@@ -25,6 +25,7 @@
import com.yeshi.fanli.entity.bus.user.ShamUser;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserMoneyExtra;
import com.yeshi.fanli.entity.common.JumpDetailV2;
import com.yeshi.fanli.entity.goods.CollectionGoodsV2;
import com.yeshi.fanli.entity.jd.JDGoods;
import com.yeshi.fanli.entity.system.BusinessSystem;
@@ -39,6 +40,7 @@
import com.yeshi.fanli.exception.taobao.TaobaoGoodsDownException;
import com.yeshi.fanli.exception.taobao.TaobaoGoodsUpdateException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.service.inter.config.ConfigService;
import com.yeshi.fanli.service.inter.config.SystemClientParamsService;
@@ -62,6 +64,7 @@
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.UserMoneyExtraService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TaoBaoConstant;
@@ -84,6 +87,7 @@
import com.yeshi.fanli.vo.goods.GoodsDetailVO;
import com.yeshi.fanli.vo.goods.MoneyInfoVO;
import com.yeshi.fanli.vo.goods.OtherInfo;
import com.yeshi.fanli.vo.goods.RewardCouponVO;
import com.yeshi.fanli.vo.goods.ShareVO;
import com.yeshi.fanli.vo.goods.ShopInfoVO;
import com.yeshi.fanli.vo.msg.ClientTextStyleVO;
@@ -173,7 +177,10 @@
    @Resource
    private IntegralGetService integralGetService;
    @Resource
    private JumpDetailV2Service jumpDetailV2Service;
    /**
     * 淘宝商品详情
     * 
@@ -529,7 +536,15 @@
                else
                    goodsDetail.setZkPrice(goodsDetail.getZkPrice().subtract(tljHongBao));
            }
        } else {// 普通购买
            OtherInfo otherInfo = new OtherInfo();
            RewardCouponVO rewardCoupon = new RewardCouponVO();
            rewardCoupon.setJumpDetail(jumpDetailV2Service.getByTypeCache("integralExchange"));
            rewardCoupon.setMaxMoney("¥" + MoneyBigDecimalUtil.mul(TaoBaoUtil.getGoodsHongBaoMoney(goods, fanLiRate),
                    Constant.MAX_REWARD_RATE));
            rewardCoupon.setDesc("用返利奖励券最高返");
            otherInfo.setRewardCoupon(rewardCoupon);
            goodsDetail.setOtherInfo(otherInfo);
        }
        extraVO.setFanliValid(fanliValid);
        extraVO.setShareValid(shareValid);
@@ -609,6 +624,16 @@
        BigDecimal fanLiRate = hongBaoManageService.getFanLiRate();
        BigDecimal shareRate = hongBaoManageService.getShareRate();
        GoodsDetailVO goodsDetail = GoodsDetailVOFactory.convertJDGoods(jdGoods, fanLiRate, shareRate);
        // 附加信息
        OtherInfo otherInfo = new OtherInfo();
        RewardCouponVO rewardCoupon = new RewardCouponVO();
        rewardCoupon.setJumpDetail(jumpDetailV2Service.getByTypeCache("integralExchange"));
        rewardCoupon.setMaxMoney(
                "¥" + MoneyBigDecimalUtil.mul(JDUtil.getGoodsFanLiMoney(jdGoods, fanLiRate), Constant.MAX_REWARD_RATE));
        rewardCoupon.setDesc("用返利奖励券最高返");
        otherInfo.setRewardCoupon(rewardCoupon);
        goodsDetail.setOtherInfo(otherInfo);
        CouponInfoVO couponInfo = goodsDetail.getCouponInfo();
        if (couponInfo != null) {
@@ -744,6 +769,17 @@
        BigDecimal fanLiRate = hongBaoManageService.getFanLiRate();
        BigDecimal shareRate = hongBaoManageService.getShareRate();
        GoodsDetailVO goodsDetail = GoodsDetailVOFactory.convertPDDGoods(pddGoods, fanLiRate, shareRate);
        // 附加信息
        OtherInfo otherInfo = new OtherInfo();
        RewardCouponVO rewardCoupon = new RewardCouponVO();
        rewardCoupon.setJumpDetail(jumpDetailV2Service.getByTypeCache("integralExchange"));
        rewardCoupon.setMaxMoney("¥" + MoneyBigDecimalUtil.mul(PinDuoDuoUtil.getGoodsFanLiMoney(pddGoods, fanLiRate),
                Constant.MAX_REWARD_RATE));
        rewardCoupon.setDesc("用返利奖励券最高返");
        otherInfo.setRewardCoupon(rewardCoupon);
        goodsDetail.setOtherInfo(otherInfo);
        CouponInfoVO couponInfo = goodsDetail.getCouponInfo();
        PDDPromotionUrl convertUrl = null;
        if (couponInfo != null) {
@@ -1069,7 +1105,7 @@
        data.put("native", true);
        data.put("jumpLink", jumpLink);
        out.print(JsonUtil.loadTrueResult(data));
        // 获得金币
        integralGetService.addCouponRebate(uid);
    }
@@ -1114,7 +1150,7 @@
        data.put("jumpLink", convertUrl.getUrl());
        data.put("nativeJumpLink", PinDuoDuoUtil.getAndroidNativeURI(convertUrl.getUrl()));
        out.print(JsonUtil.loadTrueResult(data));
        // 获得金币
        integralGetService.addCouponRebate(uid);
    }
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/msg/UserSystemMsgMapper.java
@@ -4,6 +4,7 @@
import org.apache.ibatis.annotations.Param;
import com.beust.jcommander.Parameter;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.msg.UserSystemMsg;
@@ -33,7 +34,7 @@
     * @param id
     * @return
     */
    UserSystemMsg selectBySystemZNXId(@Param("id")Long id);
    UserSystemMsg selectBySystemZNXId(@Param("id")Long id,@Param("uid") long uid);
    /**
     * 获取最近一条消息
fanli/src/main/java/com/yeshi/fanli/dto/ad/DouYinUserActionInfo.java
New file
@@ -0,0 +1,116 @@
package com.yeshi.fanli.dto.ad;
/**
 * 抖音用户行为参数
 *
 * @author Administrator
 *
 */
public class DouYinUserActionInfo {
    // 0: 激活
    // 1: 注册
    // 2: 付费
    // 3: 表单
    // 4: 咨询
    // 5: 有效咨询
    // 6: 次留
    // 19: 有效获客
    // 20:app内下单
    // 21:app内访问
    // 22:app内添加购物车
    // 23:app内付费
    // 25: 关键行为
    // 29:app内详情页到站uv 35: 表单提交
    public static int EVENT_TYPE_ACTIVE = 0;// 激活
    public static int EVENT_TYPE_REGISTER = 1;// 注册
    public static int EVENT_TYPE_CILIU = 6;// 次日留存
    public static int EVENT_TYPE_ORDER = 20;// 下单
    private String callback;
    private String muid;// 安卓:imei号取md5sum摘要;IOS取idfa原值
    private String imei;// imei号取md5sum摘要
    private String idfa;// IOS取idfa原值
    private int os;// 0: android 1: ios 3:others或为空
    private String source;// 比如来自talkingdata,可以填TD,广告主可自行命名
    private long convTime;// UTC时间戳
    private int eventType;
    public DouYinUserActionInfo(String callback, String muid, int os, long convTime,
            int eventType) {
        this.callback = callback;
        this.muid = muid;
        this.os = os;
        this.convTime = convTime;
        this.eventType = eventType;
    }
    public DouYinUserActionInfo() {
    }
    public String getCallback() {
        return callback;
    }
    public void setCallback(String callback) {
        this.callback = callback;
    }
    public String getMuid() {
        return muid;
    }
    public void setMuid(String muid) {
        this.muid = muid;
    }
    public String getImei() {
        return imei;
    }
    public void setImei(String imei) {
        this.imei = imei;
    }
    public String getIdfa() {
        return idfa;
    }
    public void setIdfa(String idfa) {
        this.idfa = idfa;
    }
    public int getOs() {
        return os;
    }
    public void setOs(int os) {
        this.os = os;
    }
    public String getSource() {
        return source;
    }
    public void setSource(String source) {
        this.source = source;
    }
    public long getConvTime() {
        return convTime;
    }
    public void setConvTime(long convTime) {
        this.convTime = convTime;
    }
    public int getEventType() {
        return eventType;
    }
    public void setEventType(int eventType) {
        this.eventType = eventType;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/ad/DouYinClickEvent.java
New file
@@ -0,0 +1,207 @@
package com.yeshi.fanli.entity.ad;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
/**
 * 抖音广告点击事件记录
 *
 * @author Administrator
 *
 */
@Document(collection="adDouYinClick")
public class DouYinClickEvent {
    public final static String MONITOR__LINK__PARAMS = "aid=__AID__&aidName=__AID__NAME__&campaignId=__CAMPAIGN__ID__&cid=__CID__&csite=__CSITE__&ctype=__CTYPE__&mac=__MAC__&mac1=__MAC1__&ua=__UA__&idfa=__IDFA__&imei=__IMEI__&uuid=__UUID__&androidId=__ANDROIDID__&openUDID=__OPENUDID__&os=__OS__&ip=__IP__&ts=__TS__&convertId=__CONVERT__ID __&callback=__CALLBACK__PARAM __";// 监测链接
    @Field
    private String aid; // 广告计划id 原值
    @Field
    private String aidName; // 广告计划名称 url编码
    @Field
    private String campaignId; // 广告组id 原值
    @Field
    private String cid; // 广告创意id 原值
    @Field
    private int csite; // 广告投放位置 1:今日头条 10001:西瓜视频 30001:火山小视频 40001:抖音
    @Field
    private int ctype; // 创意样式 2=小图模式 3=大图模式 4=组图模式 5=视频
    @Field
    private String mac; // MAC地址 去除分隔符 ":",(采用获取原始值)取 md5sum            // 摘要(备注:入网硬件地址)例:38978B891A08
    @Field
    private String mac1; // 用户终端的eth0接口的MAC地址 保留分隔符 ":",(采用获取原始值)取 md5sum
    @Field                        // 摘要(备注:入网硬件地址) 例:38:97:8B:89:1A:08
    private String ua; // 客户端上报数据时http的header中的user_agent urlencode编码
    @Field
    private String idfa; // iOS IDFA适用ios6及以上系统 原值
    @Field
    private String imei; // 用户终端的15位数字IMEI
    @Field                // 取md5sum摘要(双卡手机可能会有多个IMEI,因此可能存在获取IMEI不唯一的情况)如果头条未能成功获取设备imei,此处可能为空
    private String uuid; // 用户终端的UUID(用户终端的15位数字IMEI)
    @Field                // 原值(安卓手机系统生成的设备ID)如果头条未能成功获取设备imei,此处可能为空
    private String androidId; // 手机android_id。该设备识别号可能为空,与设 备可能存在多对一或一对多的关系
    @Field                            // 安卓手机为androidid md5加密 iOS设备为openudid md5加密
    private String openUDID; // OPENUDID(安卓和IOS手机均有) 原值(通过第三方的openudid SDK生成)
    @Field
    private int os; // 客户端操作系统 0=android 1=IOS 3=OTHERS或为空
    @Field
    private String ip; // 媒体投放系统获取的用户终端的公共IP地址 A.B.C.D(4段分点)
    @Field
    private long ts; // 客户端发生广告点击事件的时间 UNIX时间戳
    @Field
    private String convertId; // 转化id 原值
    @Field
    private String callback;// 回调参数(方案二) 见后文
    public String getAid() {
        return aid;
    }
    public void setAid(String aid) {
        this.aid = aid;
    }
    public String getAidName() {
        return aidName;
    }
    public void setAidName(String aidName) {
        this.aidName = aidName;
    }
    public String getCampaignId() {
        return campaignId;
    }
    public void setCampaignId(String campaignId) {
        this.campaignId = campaignId;
    }
    public String getCid() {
        return cid;
    }
    public void setCid(String cid) {
        this.cid = cid;
    }
    public int getCsite() {
        return csite;
    }
    public void setCsite(int csite) {
        this.csite = csite;
    }
    public int getCtype() {
        return ctype;
    }
    public void setCtype(int ctype) {
        this.ctype = ctype;
    }
    public String getMac() {
        return mac;
    }
    public void setMac(String mac) {
        this.mac = mac;
    }
    public String getMac1() {
        return mac1;
    }
    public void setMac1(String mac1) {
        this.mac1 = mac1;
    }
    public String getUa() {
        return ua;
    }
    public void setUa(String ua) {
        this.ua = ua;
    }
    public String getIdfa() {
        return idfa;
    }
    public void setIdfa(String idfa) {
        this.idfa = idfa;
    }
    public String getImei() {
        return imei;
    }
    public void setImei(String imei) {
        this.imei = imei;
    }
    public String getUuid() {
        return uuid;
    }
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }
    public String getAndroidId() {
        return androidId;
    }
    public void setAndroidId(String androidId) {
        this.androidId = androidId;
    }
    public String getOpenUDID() {
        return openUDID;
    }
    public void setOpenUDID(String openUDID) {
        this.openUDID = openUDID;
    }
    public int getOs() {
        return os;
    }
    public void setOs(int os) {
        this.os = os;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public long getTs() {
        return ts;
    }
    public void setTs(long ts) {
        this.ts = ts;
    }
    public String getConvertId() {
        return convertId;
    }
    public void setConvertId(String convertId) {
        this.convertId = convertId;
    }
    public String getCallback() {
        return callback;
    }
    public void setCallback(String callback) {
        this.callback = callback;
    }
}
fanli/src/main/java/com/yeshi/fanli/job/TaoLiJinJob.java
@@ -171,8 +171,25 @@
    public void autoAddTLJBuyGoods2() {
        if (!Constant.IS_TASK)
            return;
        LogHelper.test("自购立减开始选品");
        String day = TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyy-MM-dd");
        List<TaoBaoGoodsBrief> list = tljBuyGoodsService.listPreGoods(1);
        // 重试3次
        List<TaoBaoGoodsBrief> list = null;
        try {
            list = tljBuyGoodsService.listPreGoods(1);
        } catch (Exception e) {
        }
        if (list == null || list.size() == 0)
            try {
                list = tljBuyGoodsService.listPreGoods(1);
            } catch (Exception e) {
            }
        if (list == null || list.size() == 0)
            try {
                list = tljBuyGoodsService.listPreGoods(1);
            } catch (Exception e) {
            }
        LogHelper.test("自购立减备选商品数量:" + list.size());
        Collections.shuffle(list);
        List<TaoBaoUnionConfig> configList = taoBaoUnionConfigService
fanli/src/main/java/com/yeshi/fanli/mapping/msg/UserSystemMsgMapper.xml
@@ -55,8 +55,10 @@
        select
        <include refid="Base_Column_List" />
        from yeshi_ec_user_msg_system where ms_system_znx_id =
        #{id,jdbcType=BIGINT}
        #{id,jdbcType=BIGINT} and ms_uid=#{uid}
    </select>
    <select id="selectLatestUserSystemMsg" resultMap="BaseResultMap"
        parameterType="java.lang.Long">
fanli/src/main/java/com/yeshi/fanli/service/impl/msg/UserSystemMsgServiceImpl.java
@@ -6,6 +6,7 @@
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yeshi.fanli.dao.mybatis.UserInfoMapper;
import com.yeshi.fanli.dao.mybatis.msg.UserSystemMsgMapper;
@@ -34,6 +35,7 @@
    @Resource
    private SystemZnxService systemZnxService;
    @Transactional
    @Override
    public void addUserSystemMsg(Long uid, UserSystemMsgTypeEnum type, String title, String content, int timeTag,
            SystemZnx sz) throws UserSystemMsgException {
@@ -41,7 +43,7 @@
            throw new UserSystemMsgException(1, "信息不完整");
        UserSystemMsg msg = new UserSystemMsg();
        if (sz != null) {
            if (userSystemMsgMapper.selectBySystemZNXId(sz.getId()) == null) {
            if (userSystemMsgMapper.selectBySystemZNXId(sz.getId(), uid) == null) {
                msg.setCreateTime(new Date(sz.getCreateTime()));
                msg.setRead(false);
                msg.setSolved(false);
@@ -49,6 +51,8 @@
                msg.setUser(new UserInfo(uid));
                msg.setType(type);
                msg.setTimeTag(timeTag);
                msg.setTitle(sz.getTitle());
                msg.setContent(sz.getContent());
            } else
                throw new UserSystemMsgException(1, "消息已存在");
        } else {
@@ -121,10 +125,11 @@
        List<SystemZnx> list = systemZnxService.listbyCreateTime(createTime);
        if (list != null && list.size() > 0) {
            for (SystemZnx znx : list) {
                UserSystemMsg msg = userSystemMsgMapper.selectBySystemZNXId(znx.getId());
                UserSystemMsg msg = userSystemMsgMapper.selectBySystemZNXId(znx.getId(), uid);
                if (msg == null)
                    try {
                        addUserSystemMsg(uid, UserSystemMsgTypeEnum.common, null, null, UserSystemMsg.TIME_TAG_COMMON, znx);
                        addUserSystemMsg(uid, UserSystemMsgTypeEnum.common, null, null, UserSystemMsg.TIME_TAG_COMMON,
                                znx);
                    } catch (UserSystemMsgException e) {
                        e.printStackTrace();
                    }
fanli/src/main/java/com/yeshi/fanli/util/Constant.java
@@ -1,5 +1,6 @@
package com.yeshi.fanli.util;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
@@ -79,6 +80,9 @@
    public static final String TAOBAO_AUTH_APPSECRET = "e0a2e05deabf5ce039b52e5b492d5382";
    public static final String TAOBAO_RELATION_PID_DEFAULT = "mm_124933865_56750082_87140050199";
    public static final String TAOBAO_SPECIAL_PID_DEFAULT = "mm_124933865_56750082_89555600043";
    //奖励券最高比例
   public static final BigDecimal MAX_REWARD_RATE=new BigDecimal("0.35");
    // 返回给客户端的账号封禁提示语
    public static final String FORBIDDEN_USER_REASON_DESC = "你的账号或绑定的第三方账号已被封禁,封禁原因可在帮助中心的相关规则中参看,如有疑问或申诉解除封禁请联系客服";
fanli/src/main/java/com/yeshi/fanli/util/ad/DouYinAdUtil.java
New file
@@ -0,0 +1,115 @@
package com.yeshi.fanli.util.ad;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.StringUtil;
import com.yeshi.fanli.dto.ad.DouYinUserActionInfo;
public class DouYinAdUtil {
    public final static String SIGN_KEY = "tdqaWqs-Xkkxe-nea-UDsPtnorzpARzgB";
    // 上传用户行为
    private static void postUserAction(DouYinUserActionInfo info, String signKey) {
        String url = "http://ad.toutiao.com/track/activate/";
        Map<String, String> map = new HashMap<>();
        map.put("callback", info.getCallback());
        map.put("muid", info.getMuid());
        map.put("imei", info.getImei());
        map.put("idfa", info.getIdfa());
        map.put("os", info.getOs() + "");
        map.put("source", info.getSource());
        map.put("conv_time", info.getConvTime() + "");
        map.put("event_type", info.getEventType() + "");
        url += "?";
        for (Iterator<String> its = map.keySet().iterator(); its.hasNext();) {
            String key = its.next();
            url += key + "=" + map.get(key) + "&";
        }
        if (url.endsWith("&"))
            url = url.substring(0, url.length() - 1);
        String sign = StringUtil.Md5(url + signKey);
        url += "&sign=" + sign;
        String result = HttpUtil.post(url);
        System.out.println(result);
    }
    /**
     * 激活
     *
     * @param callBack
     */
    public static void activeAndroid(String callBack, String imei, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, StringUtil.Md5(imei), 0,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_ACTIVE);
        postUserAction(info, SIGN_KEY);
    }
    public static void activeIOS(String callBack, String idfa, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, idfa, 1,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_ACTIVE);
        postUserAction(info, SIGN_KEY);
    }
    /**
     * 注册
     */
    public static void registerAndroid(String callBack, String imei, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, StringUtil.Md5(imei), 0,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_REGISTER);
        postUserAction(info, SIGN_KEY);
    }
    public static void registerIOS(String callBack, String idfa, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, idfa, 1,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_REGISTER);
        postUserAction(info, SIGN_KEY);
    }
    /**
     * 有效下单
     */
    public static void validOrderAndroid(String callBack, String imei, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, StringUtil.Md5(imei), 0,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_ORDER);
        postUserAction(info, SIGN_KEY);
    }
    public static void validOrderIOS(String callBack, String idfa, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, idfa, 1,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_ORDER);
        postUserAction(info, SIGN_KEY);
    }
    /**
     * 次日留存
     */
    public static void retainedAndroid(String callBack, String imei, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, StringUtil.Md5(imei), 0,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_CILIU);
        postUserAction(info, SIGN_KEY);
    }
    public static void retainedIOS(String callBack, String idfa, Long convTime) {
        DouYinUserActionInfo info = new DouYinUserActionInfo(callBack, idfa, 1,
                convTime == null ? System.currentTimeMillis() / 1000 : convTime / 1000,
                DouYinUserActionInfo.EVENT_TYPE_CILIU);
        postUserAction(info, SIGN_KEY);
    }
}
fanli/src/main/java/com/yeshi/fanli/vo/goods/OtherInfo.java
@@ -8,23 +8,34 @@
/**
 * 其他信息
 *
 * @author Administrator
 *
 */
public class OtherInfo implements Serializable{
public class OtherInfo implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    // 推广红包
    @Expose
    private SpreadHongBao spreadHongBao;
    private SpreadHongBao spreadHongBao;
    // 自购立减
    @Expose
    private ReduceHongBao reduceHongBao;
    @Expose
    private RewardCouponVO rewardCoupon;
    public RewardCouponVO getRewardCoupon() {
        return rewardCoupon;
    }
    public void setRewardCoupon(RewardCouponVO rewardCoupon) {
        this.rewardCoupon = rewardCoupon;
    }
    public SpreadHongBao getSpreadHongBao() {
        return spreadHongBao;
    }
@@ -39,8 +50,6 @@
    public void setReduceHongBao(ReduceHongBao reduceHongBao) {
        this.reduceHongBao = reduceHongBao;
    }
    }
}
fanli/src/main/java/com/yeshi/fanli/vo/goods/RewardCouponVO.java
New file
@@ -0,0 +1,48 @@
package com.yeshi.fanli.vo.goods;
import com.google.gson.annotations.Expose;
import com.yeshi.fanli.entity.common.JumpDetailV2;
public class RewardCouponVO {
    @Expose
    private String maxMoney;
    @Expose
    private String desc;
    @Expose
    private JumpDetailV2 jumpDetail;
    @Expose
    private String params;
    public String getMaxMoney() {
        return maxMoney;
    }
    public void setMaxMoney(String maxMoney) {
        this.maxMoney = maxMoney;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public JumpDetailV2 getJumpDetail() {
        return jumpDetail;
    }
    public void setJumpDetail(JumpDetailV2 jumpDetail) {
        this.jumpDetail = jumpDetail;
    }
    public String getParams() {
        return params;
    }
    public void setParams(String params) {
        this.params = params;
    }
}
utils/src/main/java/org/yeshi/utils/HttpUtil.java
@@ -9,8 +9,11 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.util.Iterator;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
@@ -24,6 +27,7 @@
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@@ -31,6 +35,9 @@
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
@@ -533,4 +540,43 @@
        }
        return null;
    }
    @SuppressWarnings("deprecation")
    public static String httpsPost(String url, String body, String pwd, InputStream cert) throws Exception {
        String result = "";
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        InputStream instream = cert;
        try {
            keyStore.load(instream, pwd.toCharArray());
        } finally {
            instream.close();
        }
        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, pwd.toCharArray()).build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httppost = new HttpPost(url);
            httppost.setHeader("Content-Type", "text/html;charset=UTF-8");
            System.out.println("executing request" + httppost.getRequestLine());
            httppost.setEntity(new StringEntity(body, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = convertInputStreamToString(entity.getContent());
                }
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
        return result;
    }
}
utils/src/main/java/org/yeshi/utils/wx/WXPayUtil.java
New file
@@ -0,0 +1,44 @@
package org.yeshi.utils.wx;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.StringUtil;
/**
 * 微信支付帮助类
 *
 * @author Administrator
 *
 */
public class WXPayUtil {
    public static String payToOpenId(String appId, String openId, String mchId, String key, String pwd,
            InputStream cert, String orderNo, BigDecimal money, String desc, String ip) {
        Map<String, String> map = new HashMap<>();
        map.put("mch_appid", appId);
        map.put("mchid", mchId);
        map.put("nonce_str", StringUtil.getRandomCode(32));
        map.put("partner_trade_no", orderNo);
        map.put("openid", openId);
        map.put("check_name", "NO_CHECK");
        map.put("amount", money.multiply(new BigDecimal(100)).intValue() + "");
        map.put("desc", desc);
        map.put("spbill_create_ip", ip);
        map.put("sign", WXUtil.getSignMD5(map, key));
        String entity = WXUtil.loadWXMessage(map);
        try {
            String result = HttpUtil.httpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers",
                    entity, pwd, cert);
            System.out.println(result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}