yujian
2020-06-01 d48079c9eeec9c4f19f550a44d461275b4a31fd4
云发单
10个文件已修改
52个文件已添加
6023 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/DynamicControllerV2.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/UserCloudControllerV2.java 766 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/dynamic/GoodsEvaluateDao.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudGoodsMapper.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudGroupMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudManageMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudMapper.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudOrderMapper.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/user/cloud/UserCloudSendContentDao.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/user/cloud/UserCloudSendRecordDao.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/QrcodeLoginDTO.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/RobotInfoDTO.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/WeiXinGroupDTO.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/mq/user/body/UserCloudMQMsg.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/CloudOrderMenuEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloud.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudGoods.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudGroup.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudManage.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudOrder.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudSendContent.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudSendRecord.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudGoodsException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudGroupException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudOrderException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/job/UserCloudJob.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/log/LogHelper.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudGoodsMapper.xml 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudGroupMapper.xml 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudManageMapper.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudMapper.xml 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudOrderMapper.xml 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/goods/ShareGoodsTextTemplateServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/QrCodeServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudGoodsServiceImpl.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudGroupServiceImpl.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudManageServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudOrderServiceImpl.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudSendContentServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudSendRecordServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudServiceImpl.java 897 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/goods/ShareGoodsTextTemplateService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/QrCodeService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudGoodsService.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudGroupService.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudManageService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudOrderService.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudSendContentService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudSendRecordService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudService.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/manger/alipay/UserCloudAlipayManager.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/ImageToBase64.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/ImageUtil.java 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/aitaoker/AitaokerApiUtil.java 506 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/alipay/AliPaySignUtil.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/alipay/AlipayApi.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/alipay/AlipayWapConfig.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/mybatishandler/CloudOrderMenuEnumHandler.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/vo/user/cloud/UserCloudInfoVO.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/resource/log4j.properties 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/DynamicControllerV2.java
@@ -55,6 +55,7 @@
import com.yeshi.fanli.entity.taobao.TaoBaoLink;
import com.yeshi.fanli.exception.goods.ConvertLinkExceptionException;
import com.yeshi.fanli.exception.share.ShareGoodsException;
import com.yeshi.fanli.exception.user.cloud.UserCloudException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.common.JumpDetailV2Service;
import com.yeshi.fanli.service.inter.config.ConfigService;
@@ -71,6 +72,7 @@
import com.yeshi.fanli.service.inter.user.QrCodeService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudService;
import com.yeshi.fanli.service.inter.user.tb.UserExtraTaoBaoInfoService;
import com.yeshi.fanli.service.manger.goods.ConvertLinkManager;
import com.yeshi.fanli.util.Constant;
@@ -158,6 +160,9 @@
    @Resource
    private CommonShareInfoService commonShareInfoService;
    @Resource
    private UserCloudService userCloudService;
    @Resource(name = "taskExecutor")
    private TaskExecutor executor;
@@ -1102,7 +1107,7 @@
            } else {
                newText = newText.replace("[券后价]", MoneyBigDecimalUtil.getWithNoZera(goods.getCouponPrice()) + "");
            }
            newText.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
            newText = newText.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
        }
        JSONObject data = new JSONObject();
@@ -1611,4 +1616,5 @@
            }
        });
    }
}
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/UserCloudControllerV2.java
New file
@@ -0,0 +1,766 @@
package com.yeshi.fanli.controller.client.v2;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yeshi.utils.DateUtil;
import org.yeshi.utils.JsonUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.yeshi.fanli.dto.ConfigParamsDTO;
import com.yeshi.fanli.dto.aitaoker.QrcodeLoginDTO;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloud;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
import com.yeshi.fanli.entity.goods.CommonGoods;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.exception.taobao.TaoKeApiException;
import com.yeshi.fanli.exception.taobao.TaobaoGoodsDownException;
import com.yeshi.fanli.exception.user.cloud.UserCloudException;
import com.yeshi.fanli.exception.user.cloud.UserCloudGoodsException;
import com.yeshi.fanli.exception.user.cloud.UserCloudGroupException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.order.OrderHongBaoMoneyComputeService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGoodsService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGroupService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudManageService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudOrderService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudService;
import com.yeshi.fanli.service.manger.alipay.UserCloudAlipayManager;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.aitaoker.AitaokerApiUtil;
import com.yeshi.fanli.util.factory.goods.GoodsDetailVOFactory;
import com.yeshi.fanli.util.taobao.TaoKeApiUtil;
import com.yeshi.fanli.vo.goods.GoodsDetailVO;
import com.yeshi.fanli.vo.user.cloud.UserCloudInfoVO;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@Controller
@RequestMapping("api/v2/user/cloud")
public class UserCloudControllerV2 {
    @Resource
    private UserCloudService userCloudService;
    @Resource
    private UserCloudOrderService userCloudOrderService;
    @Resource
    private UserCloudGroupService userCloudGroupService;
    @Resource
    private UserCloudGoodsService userCloudGoodsService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private OrderHongBaoMoneyComputeService orderHongBaoMoneyComputeService;
    @Resource
    private UserCloudManageService userCloudManageService;
    @Resource
    private UserCloudAlipayManager userCloudAlipayManager;
    /**
     * 查询开通记录
     *
     * @param callback
     * @param acceptData
     * @param page
     * @param uid
     * @param out
     */
    @RequestMapping(value = "getOrderRecord")
    public void getOrderRecord(String callback, AcceptData acceptData, Integer page, Long uid, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (page == null)
            page = 1;
        // 查询成功记录
        int state = 1;
        List<UserCloudOrder> list = userCloudOrderService.getOrderRecord(page, Constant.PAGE_SIZE, uid, state);
        if (list == null)
            list = new ArrayList<>();
        GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
        gsonBuilder.registerTypeAdapter(BigDecimal.class, new JsonSerializer<BigDecimal>() {
            @Override
            public JsonElement serialize(BigDecimal value, Type theType, JsonSerializationContext context) {
                if (value == null) {
                    return new JsonPrimitive("");
                } else {
                    // 保留2位小数
                    value = value.setScale(2, BigDecimal.ROUND_DOWN);
                    return new JsonPrimitive(value.toString());
                }
            }
        }).registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
            @Override
            public JsonElement serialize(Date value, Type theType, JsonSerializationContext context) {
                if (value == null) {
                    return new JsonPrimitive("");
                } else {
                    return new JsonPrimitive(TimeUtil.formatDate(value));
                }
            }
        });
        long count = userCloudOrderService.countOrderRecord(uid, state);
        JSONObject data = new JSONObject();
        data.put("count", count);
        data.put("list", gsonBuilder.create().toJson(list));
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(data));
    }
    /**
     * 获取开通信息
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestMapping(value = "getCloudInfo")
    public void getCloudInfo(String callback, AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        UserInfo userInfo = userInfoService.getUserByIdWithMybatis(uid);
        if (userInfo == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户信息不存在"));
            return;
        }
        UserCloudInfoVO cloudInfoVO = new UserCloudInfoVO();
        cloudInfoVO.setNickName(userInfo.getNickName());
        cloudInfoVO.setPortrait(userInfo.getPortrait());
        cloudInfoVO.setOpenState(0); // 未开通
        // 是否开通
        UserCloud userCloud = userCloudService.getLastByUid(uid);
        if (userCloud == null) {
            cloudInfoVO.setOpenState(0); // 未开通
        } else {
            Date endTime = userCloud.getEndTime();
            if (endTime != null && endTime.getTime() > java.lang.System.currentTimeMillis()) {
                cloudInfoVO.setOpenState(1); // 还未过期
                // 登录微信
                cloudInfoVO.setWxName(userCloud.getWxName());
                if (userCloud.getStartTime() != null)
                    cloudInfoVO.setOpenTime(TimeUtil.formatDateDot(userCloud.getStartTime()));
                if (userCloud.getEndTime() != null) {
                    try {
                        cloudInfoVO.setCountdown(DateUtil.daysBetween2(new Date(), userCloud.getEndTime()) + "");
                    } catch (Exception e) {
                        LogHelper.errorDetailInfo(e);
                    }
                }
                Integer robotId = userCloud.getRobotId();
                // 检测是否已登录
                if (AitaokerApiUtil.onlineCheck(robotId)) {
                    boolean circle = false;
                    List<UserCloudGroup> listGroup = new ArrayList<>();
                    List<UserCloudGroup> list = userCloudGroupService.listByUid(uid);
                    if (list != null && list.size() > 0) {
                        for (UserCloudGroup cloudGroup : list) {
                            if (cloudGroup.getType() == UserCloudGroup.TYPE_CIRCLE) {
                                if (cloudGroup.getState() != null)
                                    circle = cloudGroup.getState();
                            } else {
                                listGroup.add(cloudGroup);
                            }
                        }
                    }
                    cloudInfoVO.setLoginState(true);
                    cloudInfoVO.setCircle(circle);
                    cloudInfoVO.setListGroup(listGroup);
                }
            }
        }
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(cloudInfoVO));
    }
    /**
     * 获取登录二维码
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestMapping(value = "getQrcodeMaclogin")
    public void getQrcodeMaclogin(String callback, AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        UserCloud userCloud = userCloudService.getValidByUid(uid);
        if (userCloud == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "未开通云发单"));
            return;
        }
        // 机器人ID
        Integer robotId = userCloud.getRobotId();
        if (robotId == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "正在开通中,如有疑问请联系客服"));
            return;
        }
        // 获取登录URL
        QrcodeLoginDTO maclogin = AitaokerApiUtil.getQrcodeMaclogin(userCloud.getRobotId());
        if (maclogin == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "获取登录二维码失败"));
            return;
        }
        JSONObject data = new JSONObject();
        data.put("wId", maclogin.getwId());
        data.put("qrCodeUrl", maclogin.getQrCodeUrl());
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(data));
    }
    /**
     * 检测是否微信登录
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param wId
     * @param out
     */
    @RequestMapping(value = "macloginCheck")
    public void macloginCheck(String callback, AcceptData acceptData, Long uid, String wId, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        UserCloud userCloud = userCloudService.getValidByUid(uid);
        if (userCloud == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "云发单开通已过期"));
            return;
        }
        // 机器人ID
        Integer robotId = userCloud.getRobotId();
        if (robotId == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "正在开通中,如有疑问请联系客服"));
            return;
        }
        boolean state = false;
        JSONObject data = new JSONObject();
        QrcodeLoginDTO dto = AitaokerApiUtil.getQrcodeMacloginCheck(robotId, wId);
        if (dto != null) {
            try {
                // 更新微信信息
                userCloudService.updateWXInfo(uid, dto.getWcId(), dto.getNickName(), dto.getHeadUrl());
            } catch (UserCloudException e) {
                JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, e.getMsg()));
                return;
            }
            state = true;
            boolean circle = false;
            List<UserCloudGroup> listGroup = new ArrayList<>();
            List<UserCloudGroup> list = userCloudGroupService.listByUid(uid);
            if (list != null && list.size() > 0) {
                for (UserCloudGroup cloudGroup : list) {
                    if (cloudGroup.getType() == UserCloudGroup.TYPE_CIRCLE) {
                        if (cloudGroup.getState() != null)
                            circle = cloudGroup.getState();
                    } else {
                        listGroup.add(cloudGroup);
                    }
                }
            }
            data.put("wxName", dto.getNickName());
            data.put("circle", circle);
            data.put("listGroup", listGroup);
        }
        data.put("state", state);
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(data));
    }
    /**
     * 退出登录
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param out
     */
    @RequestMapping(value = "macloginOffline")
    public void macloginOffline(String callback, AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        UserCloud userCloud = userCloudService.getLastByUid(uid);
        if (userCloud == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("云发单开通已过期"));
            return;
        }
        // 机器人ID
        Integer robotId = userCloud.getRobotId();
        if (robotId == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "未绑定机器人"));
            return;
        }
        // 退出机器人
        boolean offline = AitaokerApiUtil.macloginOffline(robotId);
        if (offline) {
            JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("退出成功"));
        } else {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("退出失败"));
        }
    }
    /**
     * 切换朋友圈状态
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param id
     * @param out
     */
    @RequestMapping(value = "switchCircleState")
    public void switchCircleState(String callback, AcceptData acceptData, Long uid, Boolean state, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (state == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "状态不能为空"));
            return;
        }
        try {
            userCloudGroupService.switchCircleState(uid, state);
        } catch (UserCloudGroupException e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(e.getMsg()));
        }
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("操作成功"));
    }
    /**
     * 检测是否微信登录
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param wId
     * @param out
     */
    @RequestMapping(value = "searchGroup")
    public void searchGroup(String callback, AcceptData acceptData, Long uid, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        try {
            // 重新获取群列表
            userCloudService.searchGroup(uid);
            // 获取最新群
            List<UserCloudGroup> list = userCloudGroupService.listGroupByUid(uid);
            if (list == null)
                list = new ArrayList<>();
            JSONObject data = new JSONObject();
            data.put("listGroup", list);
            JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(data));
        } catch (UserCloudException e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, e.getMsg()));
        }
    }
    /**
     * 设置状态
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param type
     * @param out
     */
    @RequestMapping(value = "switchGroupState")
    public void switchGroupState(String callback, AcceptData acceptData, Long uid, Long id, Boolean state,
            PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (id == null || state == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "参数不能为空"));
            return;
        }
        try {
            userCloudGroupService.switchGroupState(uid, id, state);
        } catch (UserCloudGroupException e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(e.getMsg()));
        }
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("操作成功"));
    }
    /**
     * 获取云发单库商品
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param page
     * @param out
     */
    @RequestMapping(value = "getGoodsList")
    public void getGoodsList(String callback, AcceptData acceptData, Long uid, Integer page, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (page == null)
            page = 1;
        List<UserCloudGoods> list = userCloudGoodsService.listByUid((page - 1) * Constant.PAGE_SIZE, Constant.PAGE_SIZE,
                uid);
        if (list == null)
            list = new ArrayList<>();
        JSONArray array = new JSONArray();
        JSONObject data = new JSONObject();
        if (list.size() > 0) {
            List<Long> listGid = new ArrayList<Long>();
            for (UserCloudGoods cloudGoods : list) {
                CommonGoods commonGoods = cloudGoods.getCommonGoods();
                if (commonGoods == null) {
                    continue;
                }
                listGid.add(commonGoods.getGoodsId());
            }
            // API网络接口验证是否在售
            List<TaoBaoGoodsBrief> listTaoKeGoods = null;
            try {
                listTaoKeGoods = TaoKeApiUtil.getBatchGoodsInfo(listGid);
            } catch (TaoKeApiException e) {
                e.printStackTrace();
            } catch (TaobaoGoodsDownException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Gson gson = JsonUtil.getConvertBigDecimalToStringSubZeroBuilder(new GsonBuilder())
                    .excludeFieldsWithoutExposeAnnotation().setDateFormat("yyyy-MM-dd").create();
            ConfigParamsDTO paramsDTO = orderHongBaoMoneyComputeService.getShowComputeRate(acceptData.getPlatform(),
                    acceptData.getVersion());
            for (UserCloudGoods cloudGoods : list) {
                CommonGoods commonGoods = cloudGoods.getCommonGoods();
                if (commonGoods == null) {
                    continue;
                }
                // 淘宝商品验证在售
                if (commonGoods.getGoodsType() == Constant.SOURCE_TYPE_TAOBAO) {
                    if (listTaoKeGoods != null && listTaoKeGoods.size() > 0) {
                        int state = 1; // 默认停售
                        Long goodsId = commonGoods.getGoodsId();
                        for (TaoBaoGoodsBrief taoKeGoods : listTaoKeGoods) {
                            Long auctionId = taoKeGoods.getAuctionId();
                            if (goodsId == auctionId || goodsId.equals(auctionId)) {
                                state = 0; // 在售
                                break;
                            }
                        }
                        commonGoods.setState(state);
                    }
                }
                // 判断是否已分享, 已分享显示已下架
                Integer state = cloudGoods.getState();
                if (state != null && state == UserCloudGoods.STATE_SHARED) {
                    Integer goodsState = commonGoods.getState();
                    if (goodsState != null && goodsState != 1) {
                        commonGoods.setState(2);
                    }
                }
                GoodsDetailVO detailVO = GoodsDetailVOFactory.convertCommonGoods(commonGoods, paramsDTO);
                detailVO.setId(commonGoods.getId());
                JSONObject dataObject = new JSONObject();
                dataObject.put("id", cloudGoods.getId());
                dataObject.put("goods", gson.toJson(detailVO));
                array.add(dataObject);
            }
        }
        // 第一页返回设置信息
        if (page == 1) {
            boolean custom = false;
            boolean official = false;
            UserCloudManage cloudManage = userCloudManageService.selectByPrimaryKey(uid);
            if (cloudManage != null) {
                if (cloudManage.getOfficial() != null)
                    official = cloudManage.getOfficial();
                if (cloudManage.getCustom() != null)
                    custom = cloudManage.getCustom();
            }
            data.put("custom", custom);
            data.put("official", official);
        }
        data.put("count", userCloudGoodsService.countByUid(uid));
        data.put("list", array);
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult(data));
    }
    /**
     * 添加、取消发单库
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param goodsId
     * @param goodsType
     * @param out
     */
    @RequestMapping(value = "accordGoods")
    public void accordGoods(String callback, AcceptData acceptData, Long uid, Long goodsId, Integer goodsType,
            PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("用户未登录"));
            return;
        }
        if (goodsType == null || goodsId == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "参数不完整"));
            return;
        }
        try {
            boolean state = false;
            UserCloudGoods cloudGoods = userCloudGoodsService.getByUidAndGoods(uid, goodsId, goodsType);
            if (cloudGoods != null) { // 取消加入选品库
                userCloudGoodsService.deleteByPrimaryKeyAndUid(cloudGoods.getId(), uid);
            } else { // 加入选品库
                Set<Long> set = new HashSet<Long>();
                set.add(goodsId);
                userCloudGoodsService.addGoods(uid, set, goodsType);
                state = true;
            }
            JSONObject data = new JSONObject();
            data.put("state", state);
            out.print(JsonUtil.loadTrueResult(data));
        } catch (UserCloudGoodsException e) {
            out.print(JsonUtil.loadFalseResult(e.getMsg()));
        } catch (Exception e) {
            out.print(JsonUtil.loadFalseResult("操作失败"));
            LogHelper.errorDetailInfo(e);
            ;
        }
    }
    /**
     * 添加、取消发单库
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param goodsId
     * @param goodsType
     * @param out
     */
    @RequestMapping(value = "deleteGoods")
    public void deleteGoods(String callback, AcceptData acceptData, Long uid, Long id, PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("用户未登录"));
            return;
        }
        if (id == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "参数不完整"));
            return;
        }
        userCloudGoodsService.deleteByPrimaryKeyAndUid(id, uid);
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("操作成功"));
    }
    /**
     * 设置状态
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param type
     * @param out
     */
    @RequestMapping(value = "switchState")
    public void switchState(String callback, AcceptData acceptData, Long uid, Integer type, Boolean state,
            PrintWriter out) {
        if (uid == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
            return;
        }
        if (type == 1) {
            userCloudManageService.save(uid, state, null);
        } else {
            userCloudManageService.save(uid, null, state);
        }
        JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("操作成功"));
    }
    /**
     * 云发单支付
     *
     * @param callback
     * @param acceptData
     * @param uid
     * @param type       机器人类型
     * @param response
     * @param out
     */
    @RequestMapping(value = "pay")
    public void pay(String callback, AcceptData acceptData, Long uid, String type, HttpServletResponse response,
            PrintWriter out) {
        try {
            if (uid == null) {
                JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "用户未登录"));
                return;
            }
            if (StringUtil.isNullOrEmpty(type)) {
                JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "请选择云发单套餐"));
                return;
            }
            // 创建支付信息
            String alipayForm = userCloudAlipayManager.getAlipayForm(uid, type);
            // 返回信息
            response.setContentType("text/html;charset=utf-8");
            PrintWriter print = response.getWriter();
            StringBuilder builder = new StringBuilder();
            builder.append("<html><head><title>alipay</title></head>");
            builder.append("<body>" + alipayForm + "</body></html>");
            JsonUtil.printMode(print, callback, builder.toString());
            print.close();
        } catch (Exception e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "创建支付信息失败"));
            LogHelper.errorDetailInfo(e);
        }
    }
    /**
     * 支付完成
     *
     * @param callback
     * @param acceptData
     * @param id
     * @param out
     */
    @RequestMapping(value = "payEnd")
    public void payEnd(String callback, AcceptData acceptData, Long id, PrintWriter out) {
        if (id == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "参数信息缺失"));
            return;
        }
        try {
            userCloudAlipayManager.tradeQueryByOrderId(id);
        } catch (Exception e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(1, "检测失败"));
            LogHelper.errorDetailInfo(e);
        }
    }
    /**
     * 动态一键发单
     * @param callback
     * @param acceptData
     * @param uid
     * @param id
     * @param out
     */
    @RequestMapping(value = "sendCircle")
    public void sendCircle(String callback, AcceptData acceptData, Long uid, String id,    PrintWriter out) {
        if (uid == null || StringUtil.isNullOrEmpty(id)) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("参数不能为空"));
            return;
        }
        try {
            userCloudService.sendByDynamic(uid, id);
            JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("一键发单成功"));
        } catch (UserCloudException e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(e.getCode(),e.getMsg()));
        }
    }
    /**
     * 商品详情一键发单
     * @param callback
     * @param acceptData
     * @param uid
     * @param goodsId
     * @param goodsType
     * @param out
     */
    @RequestMapping(value = "sendGoods")
    public void sendCircle(String callback, AcceptData acceptData, Long uid, Long goodsId, Integer goodsType, PrintWriter out) {
        if (uid == null || goodsId == null || goodsType == null) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult("参数不能为空"));
            return;
        }
        try {
            userCloudService.sendCustomGoods(uid, goodsId, goodsType);
            JsonUtil.printMode(out, callback, JsonUtil.loadTrueResult("一键发单成功"));
        } catch (UserCloudException e) {
            JsonUtil.printMode(out, callback, JsonUtil.loadFalseResult(e.getCode(),e.getMsg()));
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/dao/dynamic/GoodsEvaluateDao.java
@@ -294,4 +294,29 @@
        
        return mongoTemplate.find(query, GoodsEvaluate.class);
    }
    /**
     * 根据起始时间查询
     * @param date
     * @return
     */
    public List<GoodsEvaluate> listByStartTime(Date date) {
        List<Criteria> list = new ArrayList<Criteria>();
        list.add(Criteria.where("startTime").gt(new Date()));
        list.add(Criteria.where("startTime").lte(date));
        list.add(new Criteria().orOperator(Criteria.where("type").is("single"),
                    new Criteria().andOperator(Criteria.where("type").is("single"))));
        Query query = new Query();
        if (list.size() > 0) {
            Criteria[] cas = new Criteria[list.size()];
            for (int i = 0; i < list.size(); i++)
                cas[i] = list.get(i);
            query.addCriteria(new Criteria().andOperator(cas));
        }
        return mongoTemplate.find(query, GoodsEvaluate.class);
    }
}
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudGoodsMapper.java
New file
@@ -0,0 +1,58 @@
package com.yeshi.fanli.dao.mybatis.user.cloud;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods;
public interface UserCloudGoodsMapper extends BaseMapper<UserCloudGoods> {
    /**
     * 删除
     * @param id
     * @param uid
     */
    void deleteByPrimaryKeyAndUid(@Param("id") Long id, @Param("uid") Long uid);
    /**
     * 查询列表
     * @param start
     * @param count
     * @param uid
     * @return
     */
    List<UserCloudGoods> listByUid(@Param("start") long start, @Param("count") int count,
            @Param("uid") Long uid);
    long countByUid(@Param("uid") Long uid);
    /**
     * 根据商品信息查询
     * @param uid
     * @param goodsId
     * @param goodsType
     * @return
     */
    UserCloudGoods getByUidAndGoods(@Param("uid")Long uid,@Param("goodsId") Long goodsId,
            @Param("goodsType") Integer goodsType);
    /**
     * 根据简版商品id查询
     * @param uid
     * @param commonId
     * @return
     */
    UserCloudGoods getByUidAndCommonGoodsId(@Param("uid")Long uid,@Param("commonId") Long commonId);
    /**
     * 查询未分享商品
     * @param uid
     * @return
     */
    List<UserCloudGoods> listByNotShare(@Param("uid")Long uid);
}
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudGroupMapper.java
New file
@@ -0,0 +1,44 @@
package com.yeshi.fanli.dao.mybatis.user.cloud;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
public interface UserCloudGroupMapper extends BaseMapper<UserCloudGroup> {
    /**
     * 根据uid清空群
     * @param uid
     * @return
     */
    void deleteGroupByUid(@Param("uid") Long uid);
    /**
     * 根据uid查询
     * @param uid
     * @return
     */
    List<UserCloudGroup> listByUidAndType(@Param("uid") Long uid, @Param("type") Integer type);
    /**
     * 根据uid查询
     * @param uid
     * @return
     */
    List<UserCloudGroup> listByUid(@Param("uid") Long uid);
    /**
     * 根据uid查询
     * @param uid
     * @return
     */
    List<UserCloudGroup> listGroupByUid(@Param("uid") Long uid);
}
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudManageMapper.java
New file
@@ -0,0 +1,8 @@
package com.yeshi.fanli.dao.mybatis.user.cloud;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage;
public interface UserCloudManageMapper extends BaseMapper<UserCloudManage> {
}
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudMapper.java
New file
@@ -0,0 +1,37 @@
package com.yeshi.fanli.dao.mybatis.user.cloud;
import org.apache.ibatis.annotations.Param;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloud;
public interface UserCloudMapper extends BaseMapper<UserCloud> {
    /**
     * 查询有效信息
     * @return
     */
    UserCloud getValidByUid(@Param("uid") Long uid);
    /**
     * 查询有效信息
     * @return
     */
    UserCloud getLastByUid(@Param("uid") Long uid);
    /**
     * 统计所有记录
     * @param uid
     * @return
     */
    Long countByUid(@Param("uid") Long uid);
    /**
     * 查询有效信息
     * @return
     */
    UserCloud getByOrderId(@Param("orderId") Long orderId);
}
fanli/src/main/java/com/yeshi/fanli/dao/mybatis/user/cloud/UserCloudOrderMapper.java
New file
@@ -0,0 +1,60 @@
package com.yeshi.fanli.dao.mybatis.user.cloud;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.yeshi.fanli.dao.BaseMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
public interface UserCloudOrderMapper extends BaseMapper<UserCloudOrder> {
    /**
     * 查询用于更新余额-锁定
     * @param id
     * @return
     */
    UserCloudOrder selectForUpdate(long id);
    /**
     * 查询后一条支付完成的
     * @param uid
     * @param type
     * @return
     */
    UserCloudOrder getLastOrderByPayEnd(@Param("uid") Long uid, @Param("type")String type);
    /**
     * 查询后一条支付完成的
     * @param uid
     * @param type
     * @return
     */
    UserCloudOrder getLastOrderByUnpaid(@Param("uid") Long uid, @Param("type")String type);
    /**
     * 查询订单记录
     * @param start
     * @param count
     * @param uid
     * @param state
     * @return
     */
    List<UserCloudOrder> getOrderRecord(@Param("start") long start, @Param("count") int count, @Param("uid")Long uid, @Param("state")Integer state);
    /**
     * 查询订单记录
     * @param uid
     * @param state
     * @return
     */
    Long countOrderRecord(@Param("uid")Long uid, @Param("state")Integer state);
    /**
     * 查询近一个小时未支付
     * @return
     */
    List<UserCloudOrder> getLasthourByUnpaid();
}
fanli/src/main/java/com/yeshi/fanli/dao/user/cloud/UserCloudSendContentDao.java
New file
@@ -0,0 +1,13 @@
package com.yeshi.fanli.dao.user.cloud;
import org.springframework.stereotype.Repository;
import com.yeshi.fanli.dao.MongodbBaseDao;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendContent;
@Repository
public class UserCloudSendContentDao  extends MongodbBaseDao<UserCloudSendContent> {
}
fanli/src/main/java/com/yeshi/fanli/dao/user/cloud/UserCloudSendRecordDao.java
New file
@@ -0,0 +1,30 @@
package com.yeshi.fanli.dao.user.cloud;
import java.util.List;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import com.yeshi.fanli.dao.MongodbBaseDao;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendRecord;
@Repository
public class UserCloudSendRecordDao  extends MongodbBaseDao<UserCloudSendRecord> {
    /**
     * 查询已发送id
     * @param uid
     * @param sendId
     * @param sendOrigin
     * @return
     */
    public List<UserCloudSendRecord> listByUidAndSendId(Long uid, String sendId, String sendOrigin){
        Query query = new Query();
        query.addCriteria(Criteria.where("uid").is(uid));
        query.addCriteria(Criteria.where("sendId").is(sendId));
        query.addCriteria(Criteria.where("sendOrigin").is(sendOrigin));
        return findList(query);
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/QrcodeLoginDTO.java
New file
@@ -0,0 +1,73 @@
package com.yeshi.fanli.dto.aitaoker;
import com.google.gson.annotations.SerializedName;
public class QrcodeLoginDTO {
    @SerializedName("wId")
    private String wId; // 实例Id
    @SerializedName("qrCodeUrl")
    private String qrCodeUrl; // 二维码链接
    @SerializedName("wcId")
    private String wcId; // 微信ID
    @SerializedName("nickName")
    private String nickName;
    @SerializedName("headUrl")
    private String headUrl;
    @SerializedName("data")
    private String data;
    public String getwId() {
        return wId;
    }
    public void setwId(String wId) {
        this.wId = wId;
    }
    public String getQrCodeUrl() {
        return qrCodeUrl;
    }
    public void setQrCodeUrl(String qrCodeUrl) {
        this.qrCodeUrl = qrCodeUrl;
    }
    public String getWcId() {
        return wcId;
    }
    public void setWcId(String wcId) {
        this.wcId = wcId;
    }
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
    public String getHeadUrl() {
        return headUrl;
    }
    public void setHeadUrl(String headUrl) {
        this.headUrl = headUrl;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/RobotInfoDTO.java
New file
@@ -0,0 +1,172 @@
package com.yeshi.fanli.dto.aitaoker;
import com.google.gson.annotations.SerializedName;
public class RobotInfoDTO {
    @SerializedName("id")
    private Integer id;
    @SerializedName("uid")
    private String uid;
    @SerializedName("wechatrobot")
    private String wechatrobot;
    @SerializedName("amount")
    private String amount;
    @SerializedName("amount_used")
    private String amountUsed;
    @SerializedName("group_num")
    private Integer groupNum; //最大群数
    @SerializedName("passwd")
    private String passwd;
    @SerializedName("nickname")
    private String nickname;
    @SerializedName("c_uid")
    private String cUid;
    @SerializedName("login_status")
    private String loginStatus;
    @SerializedName("end_time")
    private String endTime; //到期时间 1590139325
    @SerializedName("wId")
    private String remark;
    @SerializedName("wId")
    private String wcId; //微信实例id
    @SerializedName("agent_uid")
    private String agentUid; //代理id
    @SerializedName("is_enabled")
    private String isEnabled; //0 正常 1暂停
    public String getUid() {
        return uid;
    }
    public void setUid(String uid) {
        this.uid = uid;
    }
    public String getWechatrobot() {
        return wechatrobot;
    }
    public void setWechatrobot(String wechatrobot) {
        this.wechatrobot = wechatrobot;
    }
    public String getAmountUsed() {
        return amountUsed;
    }
    public void setAmountUsed(String amountUsed) {
        this.amountUsed = amountUsed;
    }
    public Integer getGroupNum() {
        return groupNum;
    }
    public void setGroupNum(Integer groupNum) {
        this.groupNum = groupNum;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public String getcUid() {
        return cUid;
    }
    public void setcUid(String cUid) {
        this.cUid = cUid;
    }
    public String getLoginStatus() {
        return loginStatus;
    }
    public void setLoginStatus(String loginStatus) {
        this.loginStatus = loginStatus;
    }
    public String getEndTime() {
        return endTime;
    }
    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
    public String getWcId() {
        return wcId;
    }
    public void setWcId(String wcId) {
        this.wcId = wcId;
    }
    public String getAgentUid() {
        return agentUid;
    }
    public void setAgentUid(String agentUid) {
        this.agentUid = agentUid;
    }
    public String getIsEnabled() {
        return isEnabled;
    }
    public void setIsEnabled(String isEnabled) {
        this.isEnabled = isEnabled;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAmount() {
        return amount;
    }
    public void setAmount(String amount) {
        this.amount = amount;
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/aitaoker/WeiXinGroupDTO.java
New file
@@ -0,0 +1,42 @@
package com.yeshi.fanli.dto.aitaoker;
import com.google.gson.annotations.SerializedName;
public class WeiXinGroupDTO {
    // 群id
    @SerializedName("userName")
    private String groupId;
    // 群昵称
    @SerializedName("nickName")
    private String groupName;
    // 群头像
    @SerializedName("smallHead")
    private String groupHead;
    public String getGroupId() {
        return groupId;
    }
    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }
    public String getGroupName() {
        return groupName;
    }
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }
    public String getGroupHead() {
        return groupHead;
    }
    public void setGroupHead(String groupHead) {
        this.groupHead = groupHead;
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/mq/user/body/UserCloudMQMsg.java
New file
@@ -0,0 +1,48 @@
package com.yeshi.fanli.dto.mq.user.body;
import com.yeshi.fanli.dto.mq.BaseMQMsgBody;
/**
 * 用户云发单
 *
 * @author Administrator
 *
 */
public class UserCloudMQMsg extends BaseMQMsgBody {
    private Long uid;// 用户ID
    private String id;// 发圈id 、 商品库id
    private Integer type;// 类型
    public UserCloudMQMsg(Long uid, String id, Integer type) {
        super();
        this.uid = uid;
        this.id = id;
        this.type = type;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/CloudOrderMenuEnum.java
New file
@@ -0,0 +1,48 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import com.yeshi.fanli.util.StringUtil;
public enum CloudOrderMenuEnum {
    robotMonth(20.00, 1, 1, "机器人月套餐");
    private double money;
    private Integer type;
    private Integer month;
    private String desc;
    private CloudOrderMenuEnum(double money, Integer type, Integer month, String desc) {
        this.money = money;
        this.type = type;
        this.month = month;
        this.desc = desc;
    }
    public double getMoney() {
        return money;
    }
    public Integer getType() {
        return type;
    }
    public Integer getMonth() {
        return month;
    }
    public String getDesc() {
        return desc;
    }
    public static CloudOrderMenuEnum  getMenuEnum(String type) {
        if (StringUtil.isNullOrEmpty(type))
            return null;
        CloudOrderMenuEnum[] array = CloudOrderMenuEnum.values();
        for (CloudOrderMenuEnum menuEnum: array) {
            if(menuEnum.name().equals(type))
                return menuEnum;
        }
        return null;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloud.java
New file
@@ -0,0 +1,161 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import org.yeshi.utils.mybatis.Column;
import org.yeshi.utils.mybatis.Table;
/**
 * 用户云发单
 *
 * @author Administrator
 *
 */
@Table("yeshi_ec_user_cloud")
public class UserCloud {
    @Column(name = "uc_id")
    private Long id;
    @Column(name = "uc_uid")
    private Long uid;
    @Column(name = "uc_order_id")
    private Long orderId;
    @Column(name = "uc_group_num")
    private Integer groupNum; // 群数量
    @Column(name = "uc_start_time")
    private Date startTime; // 开始时间
    @Column(name = "uc_end_time")
    private Date endTime; // 结束时间
    @Column(name = "uc_wx_id")
    private String wxId; // 微信号
    @Column(name = "uc_wx_name")
    private String wxName; // 微信昵称
    @Column(name = "uc_wx_portrait")
    private String wxPortrait;// 微信头像
    @Column(name = "uc_robot_id")
    private Integer robotId; // 机器人id
    @Column(name = "uc_robot_type")
    private Integer robotType; // 机器人类型
    @Column(name = "uc_create_time")
    private Date createTime;
    @Column(name = "uc_update_time")
    private Date updateTime;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public Long getOrderId() {
        return orderId;
    }
    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }
    public Date getStartTime() {
        return startTime;
    }
    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
    public Date getEndTime() {
        return endTime;
    }
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }
    public String getWxId() {
        return wxId;
    }
    public void setWxId(String wxId) {
        this.wxId = wxId;
    }
    public String getWxName() {
        return wxName;
    }
    public void setWxName(String wxName) {
        this.wxName = wxName;
    }
    public String getWxPortrait() {
        return wxPortrait;
    }
    public void setWxPortrait(String wxPortrait) {
        this.wxPortrait = wxPortrait;
    }
    public Integer getRobotId() {
        return robotId;
    }
    public void setRobotId(Integer robotId) {
        this.robotId = robotId;
    }
    public Integer getRobotType() {
        return robotType;
    }
    public void setRobotType(Integer robotType) {
        this.robotType = robotType;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public Integer getGroupNum() {
        return groupNum;
    }
    public void setGroupNum(Integer groupNum) {
        this.groupNum = groupNum;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudGoods.java
New file
@@ -0,0 +1,95 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import org.yeshi.utils.mybatis.Column;
import org.yeshi.utils.mybatis.Table;
import com.google.gson.annotations.Expose;
import com.yeshi.fanli.entity.goods.CommonGoods;
/**
 * 发单商品库
 *
 * @author Administrator
 *
 */
@Table("yeshi_ec_user_cloud_goods")
public class UserCloudGoods {
    public static int STATE_NORMAL = 0;// 初始
    public static int STATE_SHARED = 1;// 1已分享
    @Expose
    @Column(name = "ug_id")
    private Long id;
    @Column(name = "ug_uid")
    private Long uid; // 用户id
    @Expose
    @Column(name = "ug_common_id")
    private CommonGoods commonGoods;
    @Expose
    @Column(name = "ug_state")
    private Integer state; // 状态
    @Column(name = "ug_send_time")
    private Date sendTime; // 发送时间
    @Column(name = "ug_create_time")
    private Date createTime;
    @Column(name = "ug_update_time")
    private Date updateTime;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public CommonGoods getCommonGoods() {
        return commonGoods;
    }
    public void setCommonGoods(CommonGoods commonGoods) {
        this.commonGoods = commonGoods;
    }
    public Integer getState() {
        return state;
    }
    public void setState(Integer state) {
        this.state = state;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudGroup.java
New file
@@ -0,0 +1,108 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import org.yeshi.utils.mybatis.Column;
import org.yeshi.utils.mybatis.Table;
/**
 * 用户云发单-群
 *
 * @author Administrator
 *
 */
@Table("yeshi_ec_user_cloud_group")
public class UserCloudGroup {
    public final static int TYPE_CIRCLE = 1; // 朋友圈
    public final static int TYPE_GROUP = 2; // 微信群
    @Column(name = "ucg_id")
    private Long id;
    @Column(name = "ucg_uid")
    private Long uid;
    @Column(name = "ucg_type")
    private Integer type;
    @Column(name = "ucg_state")
    private Boolean state; // 状态
    @Column(name = "ucg_group_id")
    private String groupId; // 群id
    @Column(name = "ucg_group_name")
    private String groupName; // 群名称
    @Column(name = "ucg_create_time")
    private Date createTime;
    @Column(name = "ucg_update_time")
    private Date updateTime;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public Boolean getState() {
        return state;
    }
    public void setState(Boolean state) {
        this.state = state;
    }
    public String getGroupName() {
        return groupName;
    }
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public String getGroupId() {
        return groupId;
    }
    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudManage.java
New file
@@ -0,0 +1,72 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import org.yeshi.utils.mybatis.Column;
import org.yeshi.utils.mybatis.Table;
/**
 * 发单商品库
 *
 * @author Administrator
 *
 */
@Table("yeshi_ec_user_cloud_manage")
public class UserCloudManage {
    @Column(name = "ucm_uid")
    private Long id;
    @Column(name = "ucm_official")
    private Boolean official;
    @Column(name = "ucm_custom")
    private Boolean custom; // 状态
    @Column(name = "ucm_create_time")
    private Date createTime;
    @Column(name = "ucm_update_time")
    private Date updateTime;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Boolean getOfficial() {
        return official;
    }
    public void setOfficial(Boolean official) {
        this.official = official;
    }
    public Boolean getCustom() {
        return custom;
    }
    public void setCustom(Boolean custom) {
        this.custom = custom;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudOrder.java
New file
@@ -0,0 +1,111 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.math.BigDecimal;
import java.util.Date;
import org.yeshi.utils.mybatis.Column;
import org.yeshi.utils.mybatis.Table;
import com.google.gson.annotations.Expose;
/**
 * 用户云发单
 *
 * @author Administrator
 *
 */
@Table("yeshi_ec_user_cloud_order")
public class UserCloudOrder {
    @Column(name = "crd_id")
    private Long id;
    @Column(name = "crd_uid")
    private Long uid;
    @Expose
    @Column(name = "crd_money")
    private BigDecimal money;
    @Column(name = "crd_type")
    private CloudOrderMenuEnum type; // 订单类型
    @Column(name = "crd_state")
    private Boolean state; // 支付状态
    @Expose
    @Column(name = "crd_desc") // 描述
    private String desc;
    @Expose
    @Column(name = "crd_create_time")
    private Date createTime;
    @Column(name = "crd_update_time")
    private Date updateTime;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public BigDecimal getMoney() {
        return money;
    }
    public void setMoney(BigDecimal money) {
        this.money = money;
    }
    public CloudOrderMenuEnum getType() {
        return type;
    }
    public void setType(CloudOrderMenuEnum type) {
        this.type = type;
    }
    public Boolean getState() {
        return state;
    }
    public void setState(Boolean state) {
        this.state = state;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudSendContent.java
New file
@@ -0,0 +1,127 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document(collection = "userCloudSendContent")
public class UserCloudSendContent {
    public final static String TYPE_CIRCLE = "circle"; // 朋友圈
    public final static String TYPE_GROUP = "group"; // 微信群
    @Id
    private String id;
    @Field
    private String pid;
    @Field
    private Long uid;
    @Field
    private String type;
    @Field
    private String groupId; // 群id
    @Field
    private String title;
    @Field
    private String videoUrl;
    @Field
    private String picUrl;
    @Field
    private List<String> comments;
    @Field
    private boolean state; // 是否发送成功
    @Field
    private Date createTime; // 发送时间
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPid() {
        return pid;
    }
    public void setPid(String pid) {
        this.pid = pid;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getGroupId() {
        return groupId;
    }
    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getVideoUrl() {
        return videoUrl;
    }
    public void setVideoUrl(String videoUrl) {
        this.videoUrl = videoUrl;
    }
    public String getPicUrl() {
        return picUrl;
    }
    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
    }
    public List<String> getComments() {
        return comments;
    }
    public void setComments(List<String> comments) {
        this.comments = comments;
    }
    public boolean isState() {
        return state;
    }
    public void setState(boolean state) {
        this.state = state;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/cloud/UserCloudSendRecord.java
New file
@@ -0,0 +1,127 @@
package com.yeshi.fanli.entity.bus.user.cloud;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
/**
 * 用户粉丝统计记录-每日
 *
 * @author Administrator
 *
 */
@Document(collection = "userCloudSendRecord")
public class UserCloudSendRecord {
    public final static int SEND_WAY_AUTO = 1; // 官方自动
    public final static int SEND_WAY_MANUAL = 2; // 手动
    public final static String ORIGIN_STORE = "store"; // 商品库
    public final static String ORIGIN_EVALUATE = "evaluate"; // 发圈内容
    @Id
    private String id;
    @Field
    @Indexed
    private Long uid;
    @Field
    private Integer robotId;
    @Field
    private String wxId; // 微信id
    @Field
    @Indexed
    private String sendId; // 发送id
    @Field
    private String sendOrigin; // 内容来源
    @Field
    private String goodsId; // 商品id
    @Field
    private String goodsType; // 商品类型
    @Field
    private Integer sendWay; // 发送方式
    @Field
    private Date sendTime; // 发送时间
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public String getSendId() {
        return sendId;
    }
    public void setSendId(String sendId) {
        this.sendId = sendId;
    }
    public String getSendOrigin() {
        return sendOrigin;
    }
    public void setSendOrigin(String sendOrigin) {
        this.sendOrigin = sendOrigin;
    }
    public Integer getSendWay() {
        return sendWay;
    }
    public void setSendWay(Integer sendWay) {
        this.sendWay = sendWay;
    }
    public Date getSendTime() {
        return sendTime;
    }
    public void setSendTime(Date sendTime) {
        this.sendTime = sendTime;
    }
    public String getGoodsId() {
        return goodsId;
    }
    public void setGoodsId(String goodsId) {
        this.goodsId = goodsId;
    }
    public String getGoodsType() {
        return goodsType;
    }
    public void setGoodsType(String goodsType) {
        this.goodsType = goodsType;
    }
    public Integer getRobotId() {
        return robotId;
    }
    public void setRobotId(Integer robotId) {
        this.robotId = robotId;
    }
    public String getWxId() {
        return wxId;
    }
    public void setWxId(String wxId) {
        this.wxId = wxId;
    }
}
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudException.java
New file
@@ -0,0 +1,16 @@
package com.yeshi.fanli.exception.user.cloud;
import com.yeshi.fanli.exception.BaseException;
public class UserCloudException extends BaseException {
    private static final long serialVersionUID = 1L;
    public UserCloudException(int code, String msg) {
        super(code, msg);
    }
    public UserCloudException() {
        super();
    }
}
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudGoodsException.java
New file
@@ -0,0 +1,16 @@
package com.yeshi.fanli.exception.user.cloud;
import com.yeshi.fanli.exception.BaseException;
public class UserCloudGoodsException extends BaseException {
    private static final long serialVersionUID = 1L;
    public UserCloudGoodsException(int code, String msg) {
        super(code, msg);
    }
    public UserCloudGoodsException() {
        super();
    }
}
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudGroupException.java
New file
@@ -0,0 +1,16 @@
package com.yeshi.fanli.exception.user.cloud;
import com.yeshi.fanli.exception.BaseException;
public class UserCloudGroupException extends BaseException {
    private static final long serialVersionUID = 1L;
    public UserCloudGroupException(int code, String msg) {
        super(code, msg);
    }
    public UserCloudGroupException() {
        super();
    }
}
fanli/src/main/java/com/yeshi/fanli/exception/user/cloud/UserCloudOrderException.java
New file
@@ -0,0 +1,16 @@
package com.yeshi.fanli.exception.user.cloud;
import com.yeshi.fanli.exception.BaseException;
public class UserCloudOrderException extends BaseException {
    private static final long serialVersionUID = 1L;
    public UserCloudOrderException(int code, String msg) {
        super(code, msg);
    }
    public UserCloudOrderException() {
        super();
    }
}
fanli/src/main/java/com/yeshi/fanli/job/UserCloudJob.java
New file
@@ -0,0 +1,75 @@
package com.yeshi.fanli.job;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
import com.yeshi.fanli.service.inter.dynamic.GoodsEvaluateService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudOrderService;
import com.yeshi.fanli.service.manger.alipay.UserCloudAlipayManager;
import com.yeshi.fanli.util.Constant;
@Component
public class UserCloudJob {
    @Resource
    private UserCloudOrderService userCloudOrderService;
    @Resource
    private UserCloudAlipayManager userCloudAlipayManager;
    @Resource
    private GoodsEvaluateService goodsEvaluateService;
    /**
     * 每十分钟检测是否付款
     */
    @Scheduled(cron = "0 0/10 * * * ? ")
    public  void tradeQuery() {
        if (!Constant.IS_TASK) {
            return;
        }
        List<UserCloudOrder> list = userCloudOrderService.getLasthourByUnpaid();
        if (list == null || list.size() == 0)
            return;
        for (UserCloudOrder cloudOrder: list) {
            try {
                userCloudAlipayManager.tradeQueryByOrderId(cloudOrder.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 定时检测是否存在新的发圈
     */
    @Scheduled(cron = "0 0/20 * * * ? ")
    public  void dailyCount() {
        if (!Constant.IS_TASK) {
            return;
        }
        List<UserCloudOrder> list = userCloudOrderService.getLasthourByUnpaid();
        if (list == null || list.size() == 0)
            return;
        for (UserCloudOrder cloudOrder: list) {
            try {
                userCloudAlipayManager.tradeQueryByOrderId(cloudOrder.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/log/LogHelper.java
@@ -51,6 +51,9 @@
    private static Logger teamLogger = Logger.getLogger("teamLog");
    
    
    private static Logger cloudLogger = Logger.getLogger("cloudLog");
    public static void userProtocolListen(Object obj) {
        userProtocolListenLog.info(obj);
    }
@@ -109,7 +112,12 @@
        vipInfoLogger.info(obj);
    }
    public static void cloudInfo(String info) {
        if (info != null)
            cloudLogger.info(info);
    }
    /**
     * 登录信息
     * 
@@ -247,5 +255,5 @@
        String content = String.format("链接:%s  参数:%s  响应时间:%s", url, paramsStr, time + "");
        requestTimeLogger.info(content);
    }
}
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudGoodsMapper.xml
New file
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudGoodsMapper">
  <resultMap id="BaseResultMap" type="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods">
    <id column="ug_id" property="id" jdbcType="BIGINT"/>
    <result column="ug_uid" property="uid" jdbcType="BIGINT"/>
    <result column="ug_state" property="state" jdbcType="INTEGER"/>
    <result column="ug_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="ug_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
    <association property="commonGoods" column="ug_common_id" javaType="com.yeshi.fanli.entity.goods.CommonGoods"
        select="com.yeshi.fanli.dao.mybatis.goods.CommonGoodsMapper.selectByPrimaryKey" />
  </resultMap>
  <sql id="Base_Column_List">ug_id,ug_uid,ug_common_id,ug_state,ug_create_time,ug_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/>from yeshi_ec_user_cloud_goods where ug_id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from yeshi_ec_user_cloud_goods where ug_id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_goods (ug_id,ug_uid,ug_common_id,ug_state,ug_create_time,ug_update_time) values (#{id,jdbcType=BIGINT},#{uid,jdbcType=BIGINT},#{commonGoods.id,jdbcType=BIGINT},#{state,jdbcType=INTEGER},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_goods
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">ug_id,</if>
      <if test="uid != null">ug_uid,</if>
      <if test="commonGoods != null">ug_common_id,</if>
      <if test="state != null">ug_state,</if>
      <if test="createTime != null">ug_create_time,</if>
      <if test="updateTime != null">ug_update_time,</if>
    </trim>values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="uid != null">#{uid,jdbcType=BIGINT},</if>
      <if test="commonGoods != null">#{commonGoods.id,jdbcType=BIGINT},</if>
      <if test="state != null">#{state,jdbcType=INTEGER},</if>
      <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods">update yeshi_ec_user_cloud_goods set ug_uid = #{uid,jdbcType=BIGINT},ug_common_id = #{commonGoods.id,jdbcType=BIGINT},ug_state = #{state,jdbcType=INTEGER},ug_create_time = #{createTime,jdbcType=TIMESTAMP},ug_update_time = #{updateTime,jdbcType=TIMESTAMP} where ug_id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods">update yeshi_ec_user_cloud_goods
    <set>
      <if test="uid != null">ug_uid=#{uid,jdbcType=BIGINT},</if>
      <if test="commonGoods != null">ug_common_id=#{commonGoods.id,jdbcType=BIGINT},</if>
      <if test="state != null">ug_state=#{state,jdbcType=INTEGER},</if>
      <if test="createTime != null">ug_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">ug_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where ug_id = #{id,jdbcType=BIGINT}
  </update>
   <delete id="deleteByPrimaryKeyAndUid">
           delete from yeshi_ec_user_cloud_goods where ug_id = #{id} AND ug_uid = #{uid}
   </delete>
   <select id="listByUid" resultMap="BaseResultMap">
     SELECT * FROM yeshi_ec_user_cloud_goods  tg
     LEFT JOIN  `yeshi_ec_common_goods` cg ON tg.`ug_common_id` = cg.`cg_id`
     WHERE tg.`ug_uid` = #{uid}
     ORDER BY  cg.cg_state, tg.ug_state, tg.`ug_update_time` DESC
     LIMIT #{start},#{count}
   </select>
   <select id="countByUid" resultType="java.lang.Long">
     SELECT IFNULL(count(ug_id),0) FROM yeshi_ec_user_cloud_goods  tg
     WHERE tg.`ug_uid` = #{uid}
   </select>
   <select id="getByUidAndGoods" resultMap="BaseResultMap">
        SELECT *  FROM `yeshi_ec_user_cloud_goods` g
        LEFT JOIN  `yeshi_ec_common_goods` c ON g.`ug_common_id` = c.`cg_id`
        WHERE g.`ug_uid` = #{uid} AND c.`cg_goods_id`= #{goodsId}  AND c.cg_goods_type = #{goodsType}
        LIMIT 1
   </select>
    <select id="getByUidAndCommonGoodsId" resultMap="BaseResultMap">
        SELECT *  FROM `yeshi_ec_user_cloud_goods` g
        WHERE g.`ug_uid` = #{uid} AND  g.ug_common_id = #{commonId}
        LIMIT 1
   </select>
    <select id="listByNotShare" resultMap="BaseResultMap">
        SELECT *  FROM `yeshi_ec_user_cloud_goods` g
        WHERE g.`ug_uid` = #{uid} AND  g.ug_state = 0
   </select>
</mapper>
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudGroupMapper.xml
New file
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudGroupMapper">
 <resultMap id="BaseResultMap" type="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup">
    <id column="ucg_id" property="id" jdbcType="BIGINT"/>
    <result column="ucg_uid" property="uid" jdbcType="BIGINT"/>
    <result column="ucg_type" property="type" jdbcType="INTEGER"/>
    <result column="ucg_state" property="state" jdbcType="BOOLEAN"/>
    <result column="ucg_group_id" property="groupId" jdbcType="VARCHAR"/>
    <result column="ucg_group_name" property="groupName" jdbcType="VARCHAR"/>
    <result column="ucg_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="ucg_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
  </resultMap>
  <sql id="Base_Column_List">ucg_id,ucg_uid,ucg_type,ucg_state,ucg_group_id,ucg_group_name,ucg_create_time,ucg_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/>from yeshi_ec_user_cloud_group where ucg_id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from yeshi_ec_user_cloud_group where ucg_id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_group (ucg_id,ucg_uid,ucg_type,ucg_state,ucg_group_id,ucg_group_name,ucg_create_time,ucg_update_time) values (#{id,jdbcType=BIGINT},#{uid,jdbcType=BIGINT},#{type,jdbcType=INTEGER},#{state,jdbcType=BOOLEAN},#{groupId,jdbcType=VARCHAR},#{groupName,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_group
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">ucg_id,</if>
      <if test="uid != null">ucg_uid,</if>
      <if test="type != null">ucg_type,</if>
      <if test="state != null">ucg_state,</if>
      <if test="groupId != null">ucg_group_id,</if>
      <if test="groupName != null">ucg_group_name,</if>
      <if test="createTime != null">ucg_create_time,</if>
      <if test="updateTime != null">ucg_update_time,</if>
    </trim>values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="uid != null">#{uid,jdbcType=BIGINT},</if>
      <if test="type != null">#{type,jdbcType=INTEGER},</if>
      <if test="state != null">#{state,jdbcType=BOOLEAN},</if>
      <if test="groupId != null">#{groupId,jdbcType=VARCHAR},</if>
      <if test="groupName != null">#{groupName,jdbcType=VARCHAR},</if>
      <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup">update yeshi_ec_user_cloud_group set ucg_uid = #{uid,jdbcType=BIGINT},ucg_type = #{type,jdbcType=INTEGER},ucg_state = #{state,jdbcType=BOOLEAN},ucg_group_id = #{groupId,jdbcType=VARCHAR},ucg_group_name = #{groupName,jdbcType=VARCHAR},ucg_create_time = #{createTime,jdbcType=TIMESTAMP},ucg_update_time = #{updateTime,jdbcType=TIMESTAMP} where ucg_id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup">update yeshi_ec_user_cloud_group
    <set>
      <if test="uid != null">ucg_uid=#{uid,jdbcType=BIGINT},</if>
      <if test="type != null">ucg_type=#{type,jdbcType=INTEGER},</if>
      <if test="state != null">ucg_state=#{state,jdbcType=BOOLEAN},</if>
      <if test="groupId != null">ucg_group_id=#{groupId,jdbcType=VARCHAR},</if>
      <if test="groupName != null">ucg_group_name=#{groupName,jdbcType=VARCHAR},</if>
      <if test="createTime != null">ucg_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">ucg_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where ucg_id = #{id,jdbcType=BIGINT}
  </update>
  <delete id="deleteGroupByUid">
    delete from yeshi_ec_user_cloud_group where ucg_uid = #{uid} AND ucg_type = 2
  </delete>
  <select id="listByUid" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_group d
    WHERE d.`ucg_uid` = #{uid}
  </select>
  <select id="listGroupByUid" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_group d
    WHERE d.`ucg_uid` = #{uid} AND d.ucg_type = 2
  </select>
   <select id="listByUidAndType" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_group d
    WHERE d.`ucg_uid` = #{uid} AND d.ucg_type = #{type}
  </select>
</mapper>
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudManageMapper.xml
New file
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudManageMapper">
  <resultMap id="BaseResultMap" type="com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage">
    <id column="ucm_uid" property="id" jdbcType="BIGINT"/>
    <result column="ucm_official" property="official" jdbcType="BOOLEAN"/>
    <result column="ucm_custom" property="custom" jdbcType="BOOLEAN"/>
    <result column="ucm_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="ucm_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
  </resultMap>
  <sql id="Base_Column_List">ucm_uid,ucm_official,ucm_custom,ucm_create_time,ucm_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/>from yeshi_ec_user_cloud_manage where ucm_uid = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from yeshi_ec_user_cloud_manage where ucm_uid = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_manage (ucm_uid,ucm_official,ucm_custom,ucm_create_time,ucm_update_time) values (#{id,jdbcType=BIGINT},#{official,jdbcType=BOOLEAN},#{custom,jdbcType=BOOLEAN},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_manage
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">ucm_uid,</if>
      <if test="official != null">ucm_official,</if>
      <if test="custom != null">ucm_custom,</if>
      <if test="createTime != null">ucm_create_time,</if>
      <if test="updateTime != null">ucm_update_time,</if>
    </trim>values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="official != null">#{official,jdbcType=BOOLEAN},</if>
      <if test="custom != null">#{custom,jdbcType=BOOLEAN},</if>
      <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage">update yeshi_ec_user_cloud_manage set ucm_official = #{official,jdbcType=BOOLEAN},ucm_custom = #{custom,jdbcType=BOOLEAN},ucm_create_time = #{createTime,jdbcType=TIMESTAMP},ucm_update_time = #{updateTime,jdbcType=TIMESTAMP} where ucm_uid = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage">update yeshi_ec_user_cloud_manage
    <set>
      <if test="official != null">ucm_official=#{official,jdbcType=BOOLEAN},</if>
      <if test="custom != null">ucm_custom=#{custom,jdbcType=BOOLEAN},</if>
      <if test="createTime != null">ucm_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">ucm_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where ucm_uid = #{id,jdbcType=BIGINT}
  </update>
</mapper>
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudMapper.xml
New file
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudMapper">
  <resultMap id="BaseResultMap" type="com.yeshi.fanli.entity.bus.user.cloud.UserCloud">
    <id column="uc_id" property="id" jdbcType="BIGINT"/>
    <result column="uc_uid" property="uid" jdbcType="BIGINT"/>
    <result column="uc_order_id" property="orderId" jdbcType="BIGINT"/>
    <result column="uc_group_num" property="groupNum" jdbcType="INTEGER"/>
    <result column="uc_start_time" property="startTime" jdbcType="TIMESTAMP"/>
    <result column="uc_end_time" property="endTime" jdbcType="TIMESTAMP"/>
    <result column="uc_wx_id" property="wxId" jdbcType="VARCHAR"/>
    <result column="uc_wx_name" property="wxName" jdbcType="VARCHAR"/>
    <result column="uc_wx_portrait" property="wxPortrait" jdbcType="VARCHAR"/>
    <result column="uc_robot_id" property="robotId" jdbcType="INTEGER"/>
    <result column="uc_robot_type" property="robotType" jdbcType="INTEGER"/>
    <result column="uc_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="uc_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
  </resultMap>
  <sql id="Base_Column_List">uc_id,uc_uid,uc_order_id,uc_group_num,uc_start_time,uc_end_time,uc_wx_id,uc_wx_name,uc_wx_portrait,uc_robot_id,uc_robot_type,uc_create_time,uc_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/>from yeshi_ec_user_cloud where uc_id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from yeshi_ec_user_cloud where uc_id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloud" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud (uc_id,uc_uid,uc_order_id,uc_group_num,uc_start_time,uc_end_time,uc_wx_id,uc_wx_name,uc_wx_portrait,uc_robot_id,uc_robot_type,uc_create_time,uc_update_time) values (#{id,jdbcType=BIGINT},#{uid,jdbcType=BIGINT},#{orderId,jdbcType=BIGINT},#{groupNum,jdbcType=INTEGER},#{startTime,jdbcType=TIMESTAMP},#{endTime,jdbcType=TIMESTAMP},#{wxId,jdbcType=VARCHAR},#{wxName,jdbcType=VARCHAR},#{wxPortrait,jdbcType=VARCHAR},#{robotId,jdbcType=INTEGER},#{robotType,jdbcType=INTEGER},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloud" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">uc_id,</if>
      <if test="uid != null">uc_uid,</if>
      <if test="orderId != null">uc_order_id,</if>
      <if test="groupNum != null">uc_group_num,</if>
      <if test="startTime != null">uc_start_time,</if>
      <if test="endTime != null">uc_end_time,</if>
      <if test="wxId != null">uc_wx_id,</if>
      <if test="wxName != null">uc_wx_name,</if>
      <if test="wxPortrait != null">uc_wx_portrait,</if>
      <if test="robotId != null">uc_robot_id,</if>
      <if test="robotType != null">uc_robot_type,</if>
      <if test="createTime != null">uc_create_time,</if>
      <if test="updateTime != null">uc_update_time,</if>
    </trim>values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="uid != null">#{uid,jdbcType=BIGINT},</if>
      <if test="orderId != null">#{orderId,jdbcType=BIGINT},</if>
      <if test="groupNum != null">#{groupNum,jdbcType=INTEGER},</if>
      <if test="startTime != null">#{startTime,jdbcType=TIMESTAMP},</if>
      <if test="endTime != null">#{endTime,jdbcType=TIMESTAMP},</if>
      <if test="wxId != null">#{wxId,jdbcType=VARCHAR},</if>
      <if test="wxName != null">#{wxName,jdbcType=VARCHAR},</if>
      <if test="wxPortrait != null">#{wxPortrait,jdbcType=VARCHAR},</if>
      <if test="robotId != null">#{robotId,jdbcType=INTEGER},</if>
      <if test="robotType != null">#{robotType,jdbcType=INTEGER},</if>
      <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloud">update yeshi_ec_user_cloud set uc_uid = #{uid,jdbcType=BIGINT},uc_order_id = #{orderId,jdbcType=BIGINT},uc_group_num = #{groupNum,jdbcType=INTEGER},uc_start_time = #{startTime,jdbcType=TIMESTAMP},uc_end_time = #{endTime,jdbcType=TIMESTAMP},uc_wx_id = #{wxId,jdbcType=VARCHAR},uc_wx_name = #{wxName,jdbcType=VARCHAR},uc_wx_portrait = #{wxPortrait,jdbcType=VARCHAR},uc_robot_id = #{robotId,jdbcType=INTEGER},uc_robot_type = #{robotType,jdbcType=INTEGER},uc_create_time = #{createTime,jdbcType=TIMESTAMP},uc_update_time = #{updateTime,jdbcType=TIMESTAMP} where uc_id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloud">update yeshi_ec_user_cloud
    <set>
      <if test="uid != null">uc_uid=#{uid,jdbcType=BIGINT},</if>
      <if test="orderId != null">uc_order_id=#{orderId,jdbcType=BIGINT},</if>
      <if test="groupNum != null">uc_group_num=#{groupNum,jdbcType=INTEGER},</if>
      <if test="startTime != null">uc_start_time=#{startTime,jdbcType=TIMESTAMP},</if>
      <if test="endTime != null">uc_end_time=#{endTime,jdbcType=TIMESTAMP},</if>
      <if test="wxId != null">uc_wx_id=#{wxId,jdbcType=VARCHAR},</if>
      <if test="wxName != null">uc_wx_name=#{wxName,jdbcType=VARCHAR},</if>
      <if test="wxPortrait != null">uc_wx_portrait=#{wxPortrait,jdbcType=VARCHAR},</if>
      <if test="robotId != null">uc_robot_id=#{robotId,jdbcType=INTEGER},</if>
      <if test="robotType != null">uc_robot_type=#{robotType,jdbcType=INTEGER},</if>
      <if test="createTime != null">uc_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">uc_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where uc_id = #{id,jdbcType=BIGINT}
  </update>
   <select id="getLastByUid" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud d
    WHERE d.`uc_uid` = #{uid}
    ORDER BY d.uc_id DESC
    LIMIT 1
  </select>
  <select id="getValidByUid" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud d
    WHERE d.`uc_uid` = #{uid}  AND  d.`uc_end_time` > NOW()
    LIMIT 1
  </select>
  <select id="countByUid" resultType="Long">
      SELECT COUNT(uc_id) FROM yeshi_ec_user_cloud d
    WHERE d.`uc_uid` = #{uid}
  </select>
  <select id="getByOrderId" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud d
    WHERE d.`uc_order_id` = #{orderId}
  </select>
</mapper>
fanli/src/main/java/com/yeshi/fanli/mapping/user/cloud/UserCloudOrderMapper.xml
New file
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudOrderMapper">
  <resultMap id="BaseResultMap" type="com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder">
    <id column="crd_id" property="id" jdbcType="BIGINT"/>
    <result column="crd_uid" property="uid" jdbcType="BIGINT"/>
    <result column="crd_money" property="money" jdbcType="DECIMAL"/>
    <result column="crd_state" property="state" jdbcType="BOOLEAN"/>
    <result column="crd_desc" property="desc" jdbcType="VARCHAR"/>
    <result column="crd_create_time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="crd_update_time" property="updateTime" jdbcType="TIMESTAMP"/>
    <result column="crd_type" property="type" typeHandler="com.yeshi.fanli.util.mybatishandler.CloudOrderMenuEnumHandler"/>
  </resultMap>
  <sql id="Base_Column_List">crd_id,crd_uid,crd_money,crd_type,crd_state,crd_desc,crd_create_time,crd_update_time</sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">select
    <include refid="Base_Column_List"/>from yeshi_ec_user_cloud_order where crd_id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">delete from yeshi_ec_user_cloud_order where crd_id = #{id,jdbcType=BIGINT}</delete>
  <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_order (crd_id,crd_uid,crd_money,crd_type,crd_state,crd_desc,crd_create_time,crd_update_time) values (#{id,jdbcType=BIGINT},#{uid,jdbcType=BIGINT},#{money,jdbcType=DECIMAL},#{type,jdbcType=VARCHAR},#{state,jdbcType=BOOLEAN},#{desc,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP})</insert>
  <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder" useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user_cloud_order
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">crd_id,</if>
      <if test="uid != null">crd_uid,</if>
      <if test="money != null">crd_money,</if>
      <if test="type != null">crd_type,</if>
      <if test="state != null">crd_state,</if>
      <if test="desc != null">crd_desc,</if>
      <if test="createTime != null">crd_create_time,</if>
      <if test="updateTime != null">crd_update_time,</if>
    </trim>values
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">#{id,jdbcType=BIGINT},</if>
      <if test="uid != null">#{uid,jdbcType=BIGINT},</if>
      <if test="money != null">#{money,jdbcType=DECIMAL},</if>
      <if test="type != null">#{type,jdbcType=VARCHAR},</if>
      <if test="state != null">#{state,jdbcType=BOOLEAN},</if>
      <if test="desc != null">#{desc,jdbcType=VARCHAR},</if>
      <if test="createTime != null">#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">#{updateTime,jdbcType=TIMESTAMP},</if>
    </trim>
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder">update yeshi_ec_user_cloud_order set crd_uid = #{uid,jdbcType=BIGINT},crd_money = #{money,jdbcType=DECIMAL},crd_type = #{type,jdbcType=VARCHAR},crd_state = #{state,jdbcType=BOOLEAN},crd_desc = #{desc,jdbcType=VARCHAR},crd_create_time = #{createTime,jdbcType=TIMESTAMP},crd_update_time = #{updateTime,jdbcType=TIMESTAMP} where crd_id = #{id,jdbcType=BIGINT}</update>
  <update id="updateByPrimaryKeySelective" parameterType="com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder">update yeshi_ec_user_cloud_order
    <set>
      <if test="uid != null">crd_uid=#{uid,jdbcType=BIGINT},</if>
      <if test="money != null">crd_money=#{money,jdbcType=DECIMAL},</if>
      <if test="type != null">crd_type=#{type,jdbcType=VARCHAR},</if>
      <if test="state != null">crd_state=#{state,jdbcType=BOOLEAN},</if>
      <if test="desc != null">crd_desc=#{desc,jdbcType=VARCHAR},</if>
      <if test="createTime != null">crd_create_time=#{createTime,jdbcType=TIMESTAMP},</if>
      <if test="updateTime != null">crd_update_time=#{updateTime,jdbcType=TIMESTAMP},</if>
    </set> where crd_id = #{id,jdbcType=BIGINT}
  </update>
  <select id="selectForUpdate" resultMap="BaseResultMap" parameterType="java.lang.Long">
       SELECT * from yeshi_ec_user_cloud_order where crd_id = #{id,jdbcType=BIGINT} FOR UPDATE
  </select>
  <select id="getLastOrderByPayEnd" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_order d
    WHERE d.`crd_uid` = #{uid}  AND d.`crd_type` = #{type} AND crd_state = 1
    ORDER BY d.`crd_id` DESC
    LIMIT 1
  </select>
  <select id="getLastOrderByUnpaid" resultMap="BaseResultMap">
      SELECT <include refid="Base_Column_List"/> FROM yeshi_ec_user_cloud_order d
    WHERE d.`crd_uid` = #{uid}  AND d.`crd_type` = #{type} AND crd_state = 0
    ORDER BY d.`crd_id` DESC
    LIMIT 1
  </select>
  <select id="getOrderRecord" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_order d
    WHERE d.`crd_uid` = #{uid} <if test="state != null">and d.crd_state = #{state}</if>
    ORDER BY d.`crd_id` DESC
    LIMIT #{start},#{count}
  </select>
  <select id="countOrderRecord" resultType="Long">
      SELECT count(d.`crd_id`) FROM yeshi_ec_user_cloud_order d
    WHERE d.`crd_uid` = #{uid} <if test="state != null">and d.crd_state = #{state}</if>
  </select>
  <select id="getLasthourByUnpaid" resultMap="BaseResultMap">
      SELECT * FROM yeshi_ec_user_cloud_order
    WHERE crd_state = 0 AND crd_update_time > DATE_SUB(NOW(),INTERVAL 1 HOUR)
  </select>
</mapper>
fanli/src/main/java/com/yeshi/fanli/service/impl/goods/ShareGoodsTextTemplateServiceImpl.java
@@ -704,4 +704,58 @@
        }
    }
    @Override
    public String getRecommendText(boolean coupon, String title, String sales, String couponAmount, String description) {
        String template = configService.get(ConfigKeyEnum.quickShareGoodsText.getKey());
        String recommendText = template.replace("[商品标题]", title);
        if (!coupon) {
            recommendText = recommendText.replace("推荐理由:[推荐语]", "");
            recommendText = recommendText.replace("优惠券:[券面额]元", "");
        } else {
            recommendText = recommendText.replace("[券面额]", couponAmount);
            if (!StringUtil.isNullOrEmpty(description)) {
                recommendText = recommendText.replace("[推荐语]", description);
            } else {
                recommendText = recommendText.replace("推荐理由:[推荐语]", "");
            }
        }
        if (StringUtil.isNullOrEmpty(sales)|| sales.equals("0")) {
            recommendText = recommendText.replace("销量:[销量]", "");
        } else {
            recommendText = recommendText.replace("[销量]", sales.replace("万", "w"));
        }
        return recommendText.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
    }
    @Override
    public String getCommentTextByTaoToken(boolean coupon, String taoToken, String zkPrice, String quanPrice) {
        String quickCommentText = configService.get(ConfigKeyEnum.quickShareTBCommentText.getKey());
        String commentText = quickCommentText.replace("[原价]", zkPrice);
        commentText = commentText.replace("[淘口令]", TaoBaoUtil.filterTaoToken(taoToken));
        if (!coupon) {
            commentText = commentText.replace("领券抢购", "抢购");
            commentText = commentText.replace("【券后价】[券后价]元", "");
        } else {
            commentText = commentText.replace("[券后价]", quanPrice);
        }
        return commentText.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
    }
    @Override
    public String getCommentTextByLink(boolean coupon, String link, String zkPrice, String quanPrice, ConfigKeyEnum keyEnum) {
        String quickCommentText = configService.get(keyEnum.getKey());
        String commentText = quickCommentText.replace("[原价]", zkPrice);
        commentText = commentText.replace("[链接]", link);
        if (!coupon) {
            commentText = commentText.replace("领券抢购", "抢购");
            commentText = commentText.replace("【券后价】[券后价]元", "");
        } else {
            commentText = commentText.replace("[券后价]", quanPrice);
        }
        return commentText.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/QrCodeServiceImpl.java
@@ -307,6 +307,41 @@
    
    
    @Override
    public FileUploadResult drawGoodsQuickhShare(String erCodeUrl, String portrait, String inviteCode,
            String mainPic, GoodsDetailVO goods) {
        // 二维码流
        InputStream erCodeStream = null;
        try {
            erCodeStream = QRCodeUtil.getInstance(250).encodeDeleteWhite(erCodeUrl);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        // 头像
        InputStream portraitStream = null;
        if (!StringUtil.isNullOrEmpty(portrait)) {
            try {
                portraitStream = HttpUtil.getAsInputStream(portrait);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (portraitStream == null) {
            portraitStream = ImageUtil.class.getClassLoader().getResourceAsStream("image/official_default_head.jpg");
        }
        // 画图
        InputStream drawStream = ImageUtil.drawGoodsQuickhShare(erCodeStream, portraitStream,inviteCode,mainPic, goods);
        // 上传位置
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String upPath = FilePathEnum.shareGoods.getPath() + uuid + "_" + goods.getGoodsId() + "_" + System.currentTimeMillis() + ".png";
        // 上传文件
        return COSManager.getInstance().uploadInputStream(drawStream, upPath);
    }
    @Override
    public FileUploadResult drawDynamicGoodsPoster(String erCodeUrl, String portrait, String inviteCode,
            String mainPic, GoodsDetailVO goods) {
        // 二维码流
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudGoodsServiceImpl.java
New file
@@ -0,0 +1,150 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudGoodsMapper;
import com.yeshi.fanli.dto.pdd.PDDGoodsDetail;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods;
import com.yeshi.fanli.entity.goods.CommonGoods;
import com.yeshi.fanli.entity.jd.JDGoods;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.exception.goods.CommonGoodsException;
import com.yeshi.fanli.exception.taobao.TaobaoGoodsDownException;
import com.yeshi.fanli.exception.user.cloud.UserCloudGoodsException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.goods.CommonGoodsService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGoodsService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.cache.JDGoodsCacheUtil;
import com.yeshi.fanli.util.cache.PinDuoDuoCacheUtil;
import com.yeshi.fanli.util.factory.CommonGoodsFactory;
@Service
public class UserCloudGoodsServiceImpl implements UserCloudGoodsService {
    @Resource
    private UserCloudGoodsMapper userCloudGoodsMapper;
    @Resource
    private RedisManager redisManager;
    @Resource
    private JDGoodsCacheUtil jdGoodsCacheUtil;
    @Resource
    private PinDuoDuoCacheUtil pinDuoDuoCacheUtil;
    @Resource
    private CommonGoodsService commonGoodsService;
    @Override
    public void deleteByPrimaryKeyAndUid(Long id, Long uid) {
        userCloudGoodsMapper.deleteByPrimaryKeyAndUid(id, uid);
    }
    @Override
    public UserCloudGoods selectByPrimaryKey(Long id) {
        return userCloudGoodsMapper.selectByPrimaryKey(id);
    }
    @Override
    public void updateByPrimaryKeySelective(UserCloudGoods record) {
        userCloudGoodsMapper.updateByPrimaryKeySelective(record);
    }
    @Override
    public List<UserCloudGoods> listByUid(long start, int count, Long uid) {
        return userCloudGoodsMapper.listByUid(start, count, uid);
    }
    @Override
    public List<UserCloudGoods> listByNotShare(Long uid) {
        return userCloudGoodsMapper.listByNotShare(uid);
    }
    @Override
    public long countByUid(Long uid) {
        return userCloudGoodsMapper.countByUid(uid);
    }
    @Override
    public UserCloudGoods getByUidAndGoods(Long uid, Long goodsId, Integer goodsType) {
        return userCloudGoodsMapper.getByUidAndGoods(uid, goodsId, goodsType);
    }
    @Override
    public void addGoods(Long uid, Set<Long> set, Integer goodsType) throws UserCloudGoodsException {
        if (uid == null) {
            throw new UserCloudGoodsException(1, "用户尚未登录");
        }
        if (set == null || set.size() == 0 || goodsType == null) {
            throw new UserCloudGoodsException(1, "系统参数不正确");
        }
        for (Long goodsId : set) {
            CommonGoods commonGoods = null;
            if (goodsType == Constant.SOURCE_TYPE_TAOBAO)  { // 淘宝
                try {
                    TaoBaoGoodsBrief goodsBrief = redisManager.getTaoBaoGoodsBrief(goodsId);
                    commonGoods = CommonGoodsFactory.create(goodsBrief);
                } catch (TaobaoGoodsDownException e) {
                    throw new UserCloudGoodsException(1, goodsId + "商品已下架");
                }
            } else if (goodsType == Constant.SOURCE_TYPE_JD) { // 京东
                JDGoods goods = jdGoodsCacheUtil.getGoodsInfo(goodsId);
                if (goods == null)
                    throw new UserCloudGoodsException(1, goodsId + "未找到商品信息");
                commonGoods = CommonGoodsFactory.create(goods);
            } else if (goodsType == Constant.SOURCE_TYPE_PDD) { // 拼多多
                PDDGoodsDetail goods = pinDuoDuoCacheUtil.getGoodsInfo(goodsId);
                if (goods == null)
                    throw new UserCloudGoodsException(1, goodsId + "未找到商品信息");
                commonGoods = CommonGoodsFactory.create(goods);
            }
            if (commonGoods == null) {
                LogHelper.test("云发单未找到商品详情,id=" + goodsId + "type=" + goodsType);
                continue;
            }
            try {
                commonGoodsService.addOrUpdateCommonGoods(commonGoods);
            } catch (CommonGoodsException e) {
                LogHelper.errorDetailInfo(e);
                throw new UserCloudGoodsException(1, "商品信息更新失败");
            }
            UserCloudGoods cloudGoods = userCloudGoodsMapper.getByUidAndCommonGoodsId(uid, commonGoods.getId());
            if (cloudGoods != null) {
                UserCloudGoods update = new UserCloudGoods();
                update.setId(cloudGoods.getId());
                update.setState(UserCloudGoods.STATE_NORMAL);
                update.setUpdateTime(new Date());
                userCloudGoodsMapper.updateByPrimaryKeySelective(update);
            } else {
                cloudGoods = new UserCloudGoods();
                cloudGoods.setUid(uid);
                cloudGoods.setState(UserCloudGoods.STATE_NORMAL);
                cloudGoods.setCommonGoods(commonGoods);
                cloudGoods.setCreateTime(new Date());
                cloudGoods.setUpdateTime(new Date());
                userCloudGoodsMapper.insertSelective(cloudGoods);
            }
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudGroupServiceImpl.java
New file
@@ -0,0 +1,121 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudGroupMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
import com.yeshi.fanli.exception.user.cloud.UserCloudGroupException;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGroupService;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
@Service
public class UserCloudGroupServiceImpl implements UserCloudGroupService {
    @Resource
    private UserCloudGroupMapper userCloudGroupMapper;
    @Override
    @RequestSerializableByKeyService(key = "#uid")
    public void addCircle(Long uid) {
        List<UserCloudGroup> list = userCloudGroupMapper.listByUidAndType(uid, UserCloudGroup.TYPE_CIRCLE);
        if (list != null && list.size() > 0)
            return;
        UserCloudGroup cloudGroup = new UserCloudGroup();
        cloudGroup.setUid(uid);
        cloudGroup.setType(UserCloudGroup.TYPE_CIRCLE);
        cloudGroup.setState(false);
        cloudGroup.setCreateTime(new Date());
        userCloudGroupMapper.insertSelective(cloudGroup);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    @RequestSerializableByKeyService(key = "#uid")
    public void addGroup(Long uid, String groupId, String groupName, int maxNum){
        List<UserCloudGroup> list = userCloudGroupMapper.listByUidAndType(uid, UserCloudGroup.TYPE_GROUP);
        if (list != null && list.size() > maxNum)
            return;
        boolean exist = false;
        for (UserCloudGroup userCloudGroup: list) {
            if (groupId.equals(userCloudGroup.getGroupId())) {
                exist = true;
                // 群名字变化
                if (!groupName.equals(userCloudGroup.getGroupName())) {
                    UserCloudGroup update = new UserCloudGroup();
                    update.setGroupName(groupName);
                    update.setUpdateTime(new Date());
                    userCloudGroupMapper.updateByPrimaryKeySelective(update);
                }
                break;
            }
        }
        if (exist)
            return;
        UserCloudGroup cloudGroup = new UserCloudGroup();
        cloudGroup.setUid(uid);
        cloudGroup.setType(UserCloudGroup.TYPE_GROUP);
        cloudGroup.setState(false);
        cloudGroup.setCreateTime(new Date());
        cloudGroup.setGroupId(groupId);
        cloudGroup.setGroupName(groupName);
        userCloudGroupMapper.insertSelective(cloudGroup);
    }
    @Override
    public void switchCircleState(long uid, boolean state) throws UserCloudGroupException{
        List<UserCloudGroup> list = userCloudGroupMapper.listByUidAndType(uid, UserCloudGroup.TYPE_CIRCLE);
        if (list == null || list.size() == 0)
            throw new UserCloudGroupException(1, "该记录已不存在");
        if (list.get(0).getUid() != uid)
            throw new UserCloudGroupException(1, "该记录已不存在");
        UserCloudGroup update = new UserCloudGroup();
        update.setId(list.get(0).getId());
        update.setState(state);
        update.setUpdateTime(new Date());
        userCloudGroupMapper.updateByPrimaryKeySelective(update);
    }
    @Override
    public void switchGroupState(long uid, long id, boolean state) throws UserCloudGroupException{
        UserCloudGroup cloudGroup = userCloudGroupMapper.selectByPrimaryKey(id);
        if (cloudGroup == null || cloudGroup.getUid() != uid)
            throw new UserCloudGroupException(1, "该记录已不存在");
        UserCloudGroup update = new UserCloudGroup();
        update.setId(id);
        update.setState(state);
        update.setUpdateTime(new Date());
        userCloudGroupMapper.updateByPrimaryKeySelective(update);
    }
    @Override
    public void deleteGroupByUid(Long uid){
        userCloudGroupMapper.deleteGroupByUid(uid);
    }
    @Override
    public List<UserCloudGroup> listByUid(Long uid) {
        return userCloudGroupMapper.listByUid(uid);
    }
    @Override
    public List<UserCloudGroup> listGroupByUid(Long uid) {
        return userCloudGroupMapper.listGroupByUid(uid);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudManageServiceImpl.java
New file
@@ -0,0 +1,55 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudManageMapper;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudManageService;
@Service
public class UserCloudManageServiceImpl implements UserCloudManageService {
    @Resource
    private UserCloudManageMapper userCloudManageMapper;
    @Override
    public void save(Long uid, Boolean official, Boolean custom) {
        if (uid == null)
            return;
        UserCloudManage cloudManage = userCloudManageMapper.selectByPrimaryKey(uid);
        if (cloudManage != null) {
            UserCloudManage update = new UserCloudManage();
            if (official != null)
                update.setOfficial(official);
            if (custom != null)
                update.setCustom(custom);
            update.setId(uid);
            update.setUpdateTime(new Date());
            userCloudManageMapper.updateByPrimaryKeySelective(update);
        } else {
            if (official == null)
                official = false;
            if (custom == null)
                custom = true;
            UserCloudManage manage = new UserCloudManage();
            manage.setId(uid);
            manage.setCustom(custom);
            manage.setOfficial(official);
            manage.setCreateTime(new Date());
            userCloudManageMapper.insertSelective(manage);
        }
    }
    @Override
    public UserCloudManage selectByPrimaryKey(Long uid) {
        return userCloudManageMapper.selectByPrimaryKey(uid);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudOrderServiceImpl.java
New file
@@ -0,0 +1,116 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudOrderMapper;
import com.yeshi.fanli.entity.bus.user.cloud.CloudOrderMenuEnum;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
import com.yeshi.fanli.exception.user.cloud.UserCloudOrderException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudOrderService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudService;
@Service
public class UserCloudOrderServiceImpl implements UserCloudOrderService {
    @Resource
    private UserCloudOrderMapper userCloudOrderMapper;
    @Lazy
    @Resource
    private UserCloudService userCloudService;
    @Override
    public UserCloudOrder addCloudOrder(Long uid, String type) throws UserCloudOrderException{
        if (uid == null)
            throw new UserCloudOrderException(1, "用户未登录");
        CloudOrderMenuEnum menuEnum = CloudOrderMenuEnum.getMenuEnum(type);
        if (menuEnum == null)
            throw new UserCloudOrderException(1, "请选择正确套餐");
        UserCloudOrder cloudOrder = new UserCloudOrder();
        cloudOrder.setUid(uid);
        cloudOrder.setState(false);
        cloudOrder.setType(menuEnum);
        cloudOrder.setMoney(BigDecimal.valueOf(menuEnum.getMoney()));
        cloudOrder.setCreateTime(new Date());
        cloudOrder.setUpdateTime(new Date());
        userCloudOrderMapper.insertSelective(cloudOrder);
        return cloudOrder;
    }
    @Override
    public void updateByPrimaryKeySelective(UserCloudOrder cloudOrder) {
        userCloudOrderMapper.updateByPrimaryKeySelective(cloudOrder);
    }
    @Override
    public UserCloudOrder selectByPrimaryKey(Long id) {
        return userCloudOrderMapper.selectByPrimaryKey(id);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cloudPayCloudSuccess(Long orderId) throws UserCloudOrderException{
        UserCloudOrder cloudOrder = userCloudOrderMapper.selectForUpdate(orderId);
        if (cloudOrder == null)
            throw new UserCloudOrderException(1, "订单信息不存在");
        if (cloudOrder.getState())
            return; // 已支付成功更新
        UserCloudOrder updateOrder = new UserCloudOrder();
        updateOrder.setState(true);
        updateOrder.setId(cloudOrder.getId());
        updateOrder.setUpdateTime(new Date());
        userCloudOrderMapper.updateByPrimaryKeySelective(updateOrder);
        // 创建开通信息
        try {
            userCloudService.openCloud(cloudOrder.getUid(), cloudOrder.getId(), cloudOrder.getType());
        } catch (Exception e) {
            LogHelper.error(e);
        }
    }
    @Override
    public UserCloudOrder getLastOrderByUnpaid(Long uid, String type) {
        return userCloudOrderMapper.getLastOrderByUnpaid(uid, type);
    }
    @Override
    public UserCloudOrder getLastOrderByPayEnd(Long uid, String type) {
        return userCloudOrderMapper.getLastOrderByPayEnd(uid, type);
    }
    @Override
    public List<UserCloudOrder> getOrderRecord(int page, int count, Long uid, Integer state) {
        return userCloudOrderMapper.getOrderRecord((page-1)* count, count, uid, state);
    }
    @Override
    public long countOrderRecord(Long uid, Integer state) {
        Long count = userCloudOrderMapper.countOrderRecord(uid, state);
        if (count == null)
            count = 0L;
        return count;
    }
    @Override
    public List<UserCloudOrder> getLasthourByUnpaid() {
        return userCloudOrderMapper.getLasthourByUnpaid();
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudSendContentServiceImpl.java
New file
@@ -0,0 +1,23 @@
package com.yeshi.fanli.service.impl.user.cloud;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.yeshi.fanli.dao.user.cloud.UserCloudSendContentDao;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendContent;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudSendContentService;
@Service
public class UserCloudSendContentServiceImpl implements UserCloudSendContentService {
    @Resource
    private UserCloudSendContentDao userCloudSendContentDao;
    @Override
    public UserCloudSendContent save(UserCloudSendContent record){
        return userCloudSendContentDao.save(record);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudSendRecordServiceImpl.java
New file
@@ -0,0 +1,29 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.yeshi.fanli.dao.user.cloud.UserCloudSendRecordDao;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendRecord;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudSendRecordService;
@Service
public class UserCloudSendRecordServiceImpl implements UserCloudSendRecordService {
    @Resource
    private UserCloudSendRecordDao userCloudSendRecordDao;
    @Override
    public List<UserCloudSendRecord> listByUidAndSendId(Long uid, String sendId, String sendOrigin){
        return userCloudSendRecordDao.listByUidAndSendId(uid, sendId, sendOrigin);
    }
    @Override
    public UserCloudSendRecord save(UserCloudSendRecord record){
        return userCloudSendRecordDao.save(record);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/cloud/UserCloudServiceImpl.java
New file
@@ -0,0 +1,897 @@
package com.yeshi.fanli.service.impl.user.cloud;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.BigDecimalUtil;
import org.yeshi.utils.entity.FileUploadResult;
import com.yeshi.fanli.controller.client.v2.ShareControllerV2;
import com.yeshi.fanli.dao.mybatis.user.cloud.UserCloudMapper;
import com.yeshi.fanli.dto.aitaoker.RobotInfoDTO;
import com.yeshi.fanli.dto.aitaoker.WeiXinGroupDTO;
import com.yeshi.fanli.dto.jd.JDCouponInfo;
import com.yeshi.fanli.dto.jd.JDPingouInfo;
import com.yeshi.fanli.dto.pdd.PDDGoodsDetail;
import com.yeshi.fanli.entity.bus.user.UserExtraTaoBaoInfo;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.cloud.CloudOrderMenuEnum;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloud;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendContent;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendRecord;
import com.yeshi.fanli.entity.dynamic.CommentInfo;
import com.yeshi.fanli.entity.dynamic.GoodsEvaluate;
import com.yeshi.fanli.entity.dynamic.GoodsEvaluate.EvaluateEnum;
import com.yeshi.fanli.entity.dynamic.ImgInfo;
import com.yeshi.fanli.entity.dynamic.ImgInfo.ImgEnum;
import com.yeshi.fanli.entity.goods.CommonGoods;
import com.yeshi.fanli.entity.jd.JDGoods;
import com.yeshi.fanli.entity.system.ConfigKeyEnum;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.entity.taobao.TaoBaoLink;
import com.yeshi.fanli.exception.goods.ConvertLinkExceptionException;
import com.yeshi.fanli.exception.share.ShareGoodsException;
import com.yeshi.fanli.exception.user.cloud.UserCloudException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.config.ConfigService;
import com.yeshi.fanli.service.inter.dynamic.GoodsEvaluateService;
import com.yeshi.fanli.service.inter.goods.CommonGoodsService;
import com.yeshi.fanli.service.inter.goods.ShareGoodsService;
import com.yeshi.fanli.service.inter.goods.ShareGoodsTextTemplateService;
import com.yeshi.fanli.service.inter.order.OrderHongBaoMoneyComputeService;
import com.yeshi.fanli.service.inter.order.config.HongBaoManageService;
import com.yeshi.fanli.service.inter.user.QrCodeService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGoodsService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGroupService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudSendContentService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudSendRecordService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudService;
import com.yeshi.fanli.service.inter.user.tb.UserExtraTaoBaoInfoService;
import com.yeshi.fanli.service.manger.goods.ConvertLinkManager;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.ImageToBase64;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.aitaoker.AitaokerApiUtil;
import com.yeshi.fanli.util.cache.JDGoodsCacheUtil;
import com.yeshi.fanli.util.cache.PinDuoDuoCacheUtil;
import com.yeshi.fanli.util.jd.JDApiUtil;
import com.yeshi.fanli.util.jd.JDUtil;
import com.yeshi.fanli.util.pinduoduo.PinDuoDuoApiUtil;
import com.yeshi.fanli.util.pinduoduo.PinDuoDuoUtil;
import com.yeshi.fanli.util.taobao.TaoBaoUtil;
import com.yeshi.fanli.vo.goods.GoodsDetailVO;
@Service
public class UserCloudServiceImpl implements UserCloudService {
    @Resource
    private UserCloudMapper userCloudMapper;
    @Resource
    private UserCloudGroupService userCloudGroupService;
    @Resource
    private GoodsEvaluateService goodsEvaluateService;
    @Resource
    private ConvertLinkManager convertLinkManager;
    @Resource
    private UserCloudGoodsService userCloudGoodsService;
    @Resource
    private UserInfoExtraService userInfoExtraService;
    @Resource
    private UserExtraTaoBaoInfoService userExtraTaoBaoInfoService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private ShareGoodsService shareGoodsService;
    @Resource
    private ConfigService configService;
    @Resource
    private JDGoodsCacheUtil jdGoodsCacheUtil;
    @Resource
    private PinDuoDuoCacheUtil pinDuoDuoCacheUtil;
    @Resource
    private QrCodeService qrCodeService;
    @Resource
    private RedisManager redisManager;
    @Resource
    private OrderHongBaoMoneyComputeService orderHongBaoMoneyComputeService;
    @Resource
    private HongBaoManageService hongBaoManageService;
    @Resource
    private ShareGoodsTextTemplateService shareGoodsTextTemplateService;
    @Resource
    private CommonGoodsService commonGoodsService;
    @Resource
    private UserCloudSendRecordService userCloudSendRecordService;
    @Resource
    private UserCloudSendContentService userCloudSendContentService;
    @Override
    public UserCloud getValidByUid(Long uid) {
        return userCloudMapper.getValidByUid(uid);
    }
    @Override
    public UserCloud getLastByUid(Long uid) {
        return userCloudMapper.getLastByUid(uid);
    }
    @Override
    public long countByUid(Long uid) {
        Long count = userCloudMapper.countByUid(uid);
        return count;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWXInfo(Long uid, String wxId, String wxName, String wxPortrait) throws UserCloudException {
        UserCloud userCloud = userCloudMapper.getValidByUid(uid);
        if (userCloud == null)
            throw new UserCloudException(1, "云发单已过期");
        // 更新信息
        UserCloud update = new UserCloud();
        update.setId(userCloud.getId());
        update.setWxId(wxId);
        update.setWxName(wxName);
        update.setWxPortrait(wxPortrait);
        userCloudMapper.updateByPrimaryKeySelective(update);
        // 微信号变化-清空群信息
        if (!wxId.equals(userCloud.getWxId())) {
            userCloudGroupService.deleteGroupByUid(uid);
        }
        // 加入朋友圈
        if (StringUtil.isNullOrEmpty(userCloud.getWxId())) {
            userCloudGroupService.addCircle(uid);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void openCloud(Long uid, Long orderId, CloudOrderMenuEnum menuEnum) throws UserCloudException {
        UserCloud existCloud = userCloudMapper.getByOrderId(orderId);
        if (existCloud != null) {
            return; // 该订单已处理完成
        }
        boolean renew = false;
        UserCloud userCloud = userCloudMapper.getLastByUid(uid);
        if (userCloud != null) {
            // 续费
            if (userCloud.getEndTime().getTime() > java.lang.System.currentTimeMillis())
                renew = true;
            // 验证套餐是否相同
            if (renew && userCloud.getRobotType() != menuEnum.getType()) {
                LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]已有其他云发单套餐还未结束");
                throw new UserCloudException(1, "已有其他云发单套餐还未结束");
            }
        }
        RobotInfoDTO dto = null;
        if (renew) { // 续费
            dto = AitaokerApiUtil.robotRenewals(userCloud.getRobotId(), menuEnum.getMonth());
        } else {
            dto = AitaokerApiUtil.robotCreate(menuEnum.getMonth(), menuEnum.getType(), "wechatrobot", null);
        }
        if (dto == null) {
            LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]机器人失败: 返回空值");
            throw new UserCloudException(1, "机器人获取失败");
        }
        String endTimeStr = dto.getEndTime();
        if (StringUtil.isNullOrEmpty(endTimeStr)) {
            LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]机器人失败: 返回时间为空");
            throw new UserCloudException(1, "机器人返回时间为空");
        }
        long endTime = 0;
        try {
            endTime = Long.parseLong(endTimeStr);
        } catch (Exception e) {
            LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]机器人失败: 返回时间格式不正确");
            throw new UserCloudException(1, "机器人返回时间格式不正确");
        }
        Integer robotId = dto.getId();
        if (robotId == null) {
            LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]机器人失败: 机器人ID返回为空");
            throw new UserCloudException(1, "机器人ID返回为空");
        }
        Integer groupNum = dto.getGroupNum();
        if (groupNum == null) {
            LogHelper.error("方法openCloud: [uid=" + uid + "][订单ID=" + orderId + "]机器人失败: groupNum返回为空");
            throw new UserCloudException(1, "groupNum返回为空");
        }
        UserCloud newCloud = new UserCloud();
        newCloud.setUid(uid);
        newCloud.setOrderId(orderId);
        newCloud.setGroupNum(groupNum);
        newCloud.setRobotId(robotId);
        newCloud.setRobotType(menuEnum.getType());
        newCloud.setStartTime(new Date());
        newCloud.setEndTime(new Date(endTime * 1000)); // Unix 转换 普通时间
        newCloud.setCreateTime(new Date());
        userCloudMapper.insertSelective(newCloud);
    }
    @Override
    public void searchGroup(Long uid) throws UserCloudException {
        UserCloud userCloud = userCloudMapper.getValidByUid(uid);
        if (userCloud == null)
            throw new UserCloudException(1, "云发单已过期");
        Integer robotId = userCloud.getRobotId();
        if (robotId == null)
            throw new UserCloudException(1, "云发单机器人不存在");
        List<WeiXinGroupDTO> list = AitaokerApiUtil.getContract(robotId);
        if (list == null || list.size() == 0)
            throw new UserCloudException(1, "未检索到对应群");
        for (WeiXinGroupDTO dto : list) {
            userCloudGroupService.addGroup(uid, dto.getGroupId(), dto.getGroupName(), userCloud.getGroupNum());
        }
    }
    @Override
    public void sendByDynamic(Long uid, String id) throws UserCloudException{
        sendCircleByDynamic(uid, id, UserCloudSendRecord.SEND_WAY_MANUAL);
    }
    @Override
    public void autoSendByDynamic(Long uid, String id) {
        try {
            sendCircleByDynamic(uid, id, UserCloudSendRecord.SEND_WAY_AUTO);
        } catch (UserCloudException e) {
            LogHelper.cloudInfo("autoSendByDynamic - [uid:" +uid + " 动态id:"+  id +  "]原因:"+ e.getMsg());
        }
    }
    private void sendCircleByDynamic(Long uid, String id, int way) throws UserCloudException {
        UserInfo user = userInfoService.getUserByIdWithMybatis(uid);
        if (user == null)
            throw new UserCloudException(1, "用户信息不存在");
        if (user != null && user.getState() != UserInfo.STATE_NORMAL) {
            throw new UserCloudException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
        }
        String inviteCode = userInfoExtraService.getInviteCodeByUid(uid);
        if (StringUtil.isNullOrEmpty(inviteCode))
            throw new UserCloudException(1, "邀请码未激活");
        UserExtraTaoBaoInfo taoBaoInfo = userExtraTaoBaoInfoService.getByUid(uid);
        String relationId = null;
        if (taoBaoInfo != null && taoBaoInfo.getRelationId() != null && taoBaoInfo.getRelationValid() != null
                && taoBaoInfo.getRelationValid() == true)
            relationId = taoBaoInfo.getRelationId();
        if (StringUtil.isNullOrEmpty(relationId))
            throw new UserCloudException(2, "淘宝未授权,请前往\"我的\"绑定淘宝账号");
        // 验证是否开通
        UserCloud userCloud = userCloudMapper.getValidByUid(uid);
        if (userCloud == null)
            throw new UserCloudException(1, "云发单已过期");
        Integer robotId = userCloud.getRobotId();
        if (robotId == null)
            throw new UserCloudException(1, "云发单机器人不存在");
        String wxId = userCloud.getWxId();
        if (StringUtil.isNullOrEmpty(wxId))
            throw new UserCloudException(1, "微信号缺失");
        // 验证开启状态
        List<UserCloudGroup> listGroup = userCloudGroupService.listByUid(uid);
        if (listGroup == null || listGroup.size() == 0)
            throw new UserCloudException(1, "请先添加云发单群信息");
        List<UserCloudGroup> listOpen = new ArrayList<>();
        for (UserCloudGroup cloudGrou : listGroup) {
            if (cloudGrou.getState()) {
                listOpen.add(cloudGrou);
            }
        }
        if (listOpen.size() == 0)
            throw new UserCloudException(1, "请先开启云发单群功能");
        // 验证发圈是否可行
        GoodsEvaluate evaluate = goodsEvaluateService.getById(id);
        if (evaluate == null || evaluate.getState() == 0)
            throw new UserCloudException(1, "该内容已下架");
        if (evaluate.getType() != EvaluateEnum.single && evaluate.getType() != EvaluateEnum.activity)
            throw new UserCloudException(1, "该内容不支持云发单");
        // 验证是否可转链
        List<CommentInfo> comments = evaluate.getComments();
        if (comments == null || comments.size() == 0)
            throw new UserCloudException(1, "该内容不能转链");
        boolean hasToken = false;
        List<String> listComment = new ArrayList<>();
        for (CommentInfo commentInfo : comments) {
            String comment = null;
            try {
                comment = convertLinkManager.convertLinkFromText(commentInfo.getContent(), uid, true);
                hasToken = true;
            } catch (ConvertLinkExceptionException e) {
                if (e.getCode() != ConvertLinkExceptionException.CODE_NONE) {
                    throw new UserCloudException(1, e.getMsg());
                }
            } catch (Exception e) {
                LogHelper.errorDetailInfo(e);
                throw new UserCloudException(1, "该内容包含可转链口令或链接");
            }
            if (StringUtil.isNullOrEmpty(comment))
                comment = commentInfo.getContent();
            // 替换价格
            if (evaluate.getType() == EvaluateEnum.single) {
                GoodsDetailVO goods = evaluate.getGoods();
                comment = comment.replace("[原价]", MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()) + "");
                if (!goods.isHasCoupon()) {
                    comment = comment.replace("领券抢购", "抢购");
                    comment = comment.replace("【券后价】[券后价]元", "");
                } else {
                    comment = comment.replace("[券后价]", MoneyBigDecimalUtil.getWithNoZera(goods.getCouponPrice()) + "");
                }
                comment = comment.replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n").replace("\r\n\r\n", "\r\n");
            }
            listComment.add(comment);
        }
        if (!hasToken)
            throw new UserCloudException(1, "该内容包含可转链口令或链接");
        String qrCode = null;
        ImgInfo imgVideo = null;
        List<String> listImg = new ArrayList<>();
        List<ImgInfo> imgs = evaluate.getImgList();
        if (imgs != null && imgs.size() > 0) {
            for (ImgInfo imgInfo : imgs) {
                if (imgInfo.getType() == ImgEnum.video) {
                    imgVideo = imgInfo;
                    continue;
                }
                GoodsDetailVO goodsVO = imgInfo.getGoodsVO();
                if (goodsVO == null) {
                    listImg.add(imgInfo.getUrl());
                } else {
                    String jumpLink = getJumpLink(goodsVO, user, relationId, inviteCode, imgInfo.getUrl());
                    if (!StringUtil.isNullOrEmpty(jumpLink)) {
                        qrCode = jumpLink;
                    }
                }
            }
        }
        // 保存发送记录
        UserCloudSendRecord sendRecord = new UserCloudSendRecord();
        sendRecord.setUid(uid);
        sendRecord.setSendId(id);
        sendRecord.setSendWay(way);
        sendRecord.setWxId(wxId);
        sendRecord.setRobotId(robotId);
        sendRecord.setSendTime(new Date());
        sendRecord.setSendOrigin(UserCloudSendRecord.ORIGIN_STORE);
        UserCloudSendRecord result = userCloudSendRecordService.save(sendRecord);
        String pid = result.getId();
        for (UserCloudGroup cloudGroup: listOpen) {
            String title = evaluate.getTitle();
            UserCloudSendContent sendContent = new UserCloudSendContent();
            sendContent.setPid(pid);
            sendContent.setUid(uid);
            sendContent.setGroupId(cloudGroup.getGroupId());
            sendContent.setCreateTime(new Date());
            if(cloudGroup.getType() == UserCloudGroup.TYPE_CIRCLE) { // 朋友圈
                String circleId = null;
                sendContent.setType(UserCloudSendContent.TYPE_CIRCLE);
                if (imgVideo == null) {
                    String picUrl = "";
                    if (!StringUtil.isNullOrEmpty(qrCode))
                        picUrl += qrCode;
                    if (listImg.size() > 0) {
                        for (String img: listImg) {
                            picUrl += "," + img;
                        }
                    }
                    sendContent.setTitle(title);
                    sendContent.setPicUrl(picUrl);
                    // 发送图文
                    circleId = AitaokerApiUtil.macsendCircle(robotId, title, picUrl);
                } else {
                    sendContent.setPicUrl(imgVideo.getUrl());
                    sendContent.setVideoUrl(imgVideo.getVideoUrl());
                    // 发送视频
                    circleId = AitaokerApiUtil.macsendCircleVideo(robotId, imgVideo.getVideoUrl(), imgVideo.getUrl());
                }
                // 评论文本
                if (!StringUtil.isNullOrEmpty(circleId)) {
                    sendContent.setState(true);
                    List<String> list = new ArrayList<>();
                    for (String comment: listComment) {
                        boolean macsend = AitaokerApiUtil.macsendCircleComment(robotId, wxId, circleId, comment);
                        if (macsend) {
                            list.add(comment);
                        }
                    }
                    sendContent.setComments(list);
                }
            } else { // 群
                sendContent.setType(UserCloudSendContent.TYPE_GROUP);
                // 发送文本
                if (!StringUtil.isNullOrEmpty(title)) {
                    boolean macsend = AitaokerApiUtil.macsendText(robotId, cloudGroup.getGroupId(), title);
                    if (macsend)
                        sendContent.setTitle(title);
                }
                // 发送图片
                String picurl = null;
                if (!StringUtil.isNullOrEmpty(qrCode)) {
                    picurl = qrCode;
                } else if (listImg.size() > 0) {
                    picurl = listImg.get(0);
                }
                if (!StringUtil.isNullOrEmpty(picurl)) {
                    String imgBase64 = ImageToBase64.NetImageToBase64(picurl);
                    boolean macsend = AitaokerApiUtil.macsendImgBase64(robotId, cloudGroup.getGroupId(), imgBase64);
                    if (macsend)
                        sendContent.setPicUrl(picurl);
                }
                // 评论文本
                List<String> list = new ArrayList<>();
                for (String comment: listComment) {
                    boolean macsend = AitaokerApiUtil.macsendText(robotId, cloudGroup.getGroupId(), comment);
                    if (macsend) {
                        list.add(comment);
                    }
                }
                sendContent.setState(true);
                sendContent.setComments(list);
            }
            userCloudSendContentService.save(sendContent);
        }
    }
    private String getJumpLink(GoodsDetailVO goodsVO, UserInfo user, String relationId, String inviteCode,
            String mainPic) {
        String jumpLink = null;
        if (goodsVO.getGoodsType() == Constant.SOURCE_TYPE_TAOBAO) {
            TaoBaoLink taoBaoLink = null;
            try {
                taoBaoLink = shareGoodsService.getTaoBaoLinkForShare(user.getId(), goodsVO.getGoodsId(), relationId);
            } catch (ShareGoodsException e) {
                e.printStackTrace();
            }
            jumpLink = ShareControllerV2.getERCodeContentNew(
                    configService.get(ConfigKeyEnum.taobaoShareQrcodeText.getKey()), taoBaoLink.getGoods(),
                    TaoBaoUtil.filterTaoToken(taoBaoLink.getTaoToken()));
        } else if (goodsVO.getGoodsType() == Constant.SOURCE_TYPE_JD) {
            JDGoods jdGoods = jdGoodsCacheUtil.getGoodsInfo(goodsVO.getGoodsId());
            if (jdGoods == null) {
                return null;
            }
            String couponUrl = null;
            JDCouponInfo couponInfo = JDUtil.getShowCouponInfo(jdGoods);
            if (couponInfo != null) {
                couponUrl = couponInfo.getLink();
            }
            String materialId = "https://item.jd.com/" + goodsVO.getGoodsId() + ".html";
            jumpLink = JDApiUtil.convertLinkWithSubUnionId(materialId, couponUrl, JDApiUtil.POSITION_SHARE + "",
                    user.getId() + "");
        } else if (goodsVO.getGoodsType() == Constant.SOURCE_TYPE_PDD) {
            jumpLink = PinDuoDuoApiUtil.getPromotionUrl(goodsVO.getGoodsId(), PinDuoDuoApiUtil.PID_SHARE + "",
                    user.getId() + "");
        }
        FileUploadResult uploadResult = qrCodeService.drawDynamicGoodsPoster(jumpLink, user.getPortrait(), inviteCode, mainPic, goodsVO);
        if (uploadResult != null) {
            return uploadResult.getUrl();
        }
        return null;
    }
    @Override
    public void sendCustomGoods(Long uid, Long goodsId, Integer goodsType) throws UserCloudException{
        sendCircleByGoods(uid, goodsId, goodsType, null);
    }
    @Override
    public void autoSendCustomGoods(Long uid, Long id) {
        UserCloudGoods cloudGoods = userCloudGoodsService.selectByPrimaryKey(id);
        if (cloudGoods == null) {
            return;
        }
        CommonGoods cgoods = cloudGoods.getCommonGoods();
        if (cgoods == null)
            return;
        try {
            // 发送商品
            sendCircleByGoods(uid, cgoods.getGoodsId(), cgoods.getGoodsType(), id);
            UserCloudGoods record = new UserCloudGoods();
            record.setId(id);
            record.setState(UserCloudGoods.STATE_SHARED);
            record.setUpdateTime(new Date());
            userCloudGoodsService.updateByPrimaryKeySelective(record);
        } catch (UserCloudException e) {
            LogHelper.cloudInfo("autoSendCustomGoods - [uid:" +uid + " 库id:"+  id +  "]原因:"+ e.getMsg());
        }
    }
    private void sendCircleByGoods(Long uid, Long goodsId, Integer goodsType, Long storeId) throws UserCloudException {
        // 验证是否授权
        UserInfo user = userInfoService.getUserByIdWithMybatis(uid);
        if (user == null)
            throw new UserCloudException(1, "用户信息不存在");
        if (user != null && user.getState() != UserInfo.STATE_NORMAL) {
            throw new UserCloudException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
        }
        UserExtraTaoBaoInfo taoBaoInfo = userExtraTaoBaoInfoService.getByUid(uid);
        String relationId = null;
        if (taoBaoInfo != null && taoBaoInfo.getRelationId() != null && taoBaoInfo.getRelationValid() != null
                && taoBaoInfo.getRelationValid() == true)
            relationId = taoBaoInfo.getRelationId();
        if (StringUtil.isNullOrEmpty(relationId))
            throw new UserCloudException(2, "淘宝未授权,请前往\"我的\"绑定淘宝账号");
        // 验证是否开通
        UserCloud userCloud = userCloudMapper.getValidByUid(uid);
        if (userCloud == null)
            throw new UserCloudException(1, "云发单已过期");
        Integer robotId = userCloud.getRobotId();
        if (robotId == null)
            throw new UserCloudException(1, "云发单机器人不存在");
        String wxId = userCloud.getWxId();
        if (StringUtil.isNullOrEmpty(wxId))
            throw new UserCloudException(1, "微信号缺失");
        // 验证开启状态
        List<UserCloudGroup> listGroup = userCloudGroupService.listByUid(uid);
        if (listGroup == null || listGroup.size() == 0)
            throw new UserCloudException(1, "请先添加云发单群信息");
        List<UserCloudGroup> listOpen = new ArrayList<>();
        for (UserCloudGroup cloudGrou : listGroup) {
            if (cloudGrou.getState()) {
                listOpen.add(cloudGrou);
            }
        }
        if (listOpen.size() == 0)
            throw new UserCloudException(1, "请先开启云发单群功能");
        // 保存发送记录
        UserCloudSendRecord sendRecord = new UserCloudSendRecord();
        sendRecord.setUid(uid);
        sendRecord.setGoodsId(goodsId + "");
        sendRecord.setGoodsType(goodsType + "");
        sendRecord.setWxId(wxId);
        sendRecord.setRobotId(robotId);
        sendRecord.setSendTime(new Date());
        if (storeId != null) {
            sendRecord.setSendId(storeId + "");
            sendRecord.setSendOrigin(UserCloudSendRecord.ORIGIN_STORE);
            sendRecord.setSendWay(UserCloudSendRecord.SEND_WAY_AUTO);
        } else {
            sendRecord.setSendWay(UserCloudSendRecord.SEND_WAY_MANUAL);
        }
        UserCloudSendRecord result = userCloudSendRecordService.save(sendRecord);
        if (goodsType == Constant.SOURCE_TYPE_TAOBAO) {
            sendTaoBaoGoods(user, robotId, wxId, goodsId, relationId, listOpen, result.getId());
        } else if (goodsType == Constant.SOURCE_TYPE_JD) {
            sendJDGoods(user, robotId, wxId, goodsId, relationId, listOpen, result.getId());
        } else if (goodsType == Constant.SOURCE_TYPE_PDD) {
            sendPDDGoods(user, robotId, wxId, goodsId, relationId, listOpen, result.getId());
        } else if (goodsType == Constant.SOURCE_TYPE_VIP) {
        } else if (goodsType == Constant.SOURCE_TYPE_SUNING) {
        }
    }
    /**
     * 淘宝商品信息处理
     * @param user
     * @param inviteCode
     * @param robotId
     * @param wxId
     * @param goodsId
     * @param relationId
     * @param listOpen
     * @throws UserCloudException
     */
    private void sendTaoBaoGoods(UserInfo user, int robotId, String wxId, Long goodsId, String relationId,
            List<UserCloudGroup> listOpen, String pid) throws UserCloudException {
        TaoBaoLink taoBaoLink = null;
        try {
            taoBaoLink = shareGoodsService.getTaoBaoLinkForShare(user.getId(), goodsId, relationId);
        } catch (ShareGoodsException e) {
            LogHelper.errorDetailInfo(e);
            throw new UserCloudException(1, "该商品已下架");
        }
        if (taoBaoLink == null)
            throw new UserCloudException(1, "该商品已下架");
        TaoBaoGoodsBrief goods = taoBaoLink.getGoods();
        boolean coupon = false;
        if (!StringUtil.isNullOrEmpty(goods.getCouponInfo())) {
            coupon = true;
        }
        String quanPrice = "";
        String description = "";
        String couponAmount = "";
        if (coupon) {
            description = goods.getDescription();
            quanPrice = TaoBaoUtil.getAfterUseCouplePrice(goods) + "";
            couponAmount = MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()).toString();
        }
        String sales = TaoBaoUtil.getSaleCount(goods.getBiz30day());
        // 获取推荐语
        String recommendText = shareGoodsTextTemplateService.getRecommendText(coupon, goods.getTitle(), sales,
                couponAmount, description);
        // 获取评论语
        String commentText = shareGoodsTextTemplateService.getCommentTextByTaoToken(coupon, taoBaoLink.getTaoToken(),
                goods.getZkPrice().toString(), quanPrice);
        // 云发单
        sendGoods(robotId, wxId, listOpen, recommendText, commentText,  goods.getImgList(), user.getId(), pid);
    }
    /**
     * 京东商品云发单
     * @param user
     * @param robotId
     * @param wxId
     * @param goodsId
     * @param relationId
     * @param listOpen
     * @throws UserCloudException
     */
    private void sendJDGoods(UserInfo user, int robotId, String wxId, Long goodsId, String relationId,
            List<UserCloudGroup> listOpen, String pid) throws UserCloudException {
        JDGoods jdGoods = jdGoodsCacheUtil.getGoodsInfo(goodsId);
        if (jdGoods == null)
            throw new UserCloudException(1, "该商品已下架");
        String couponUrl = null;
        JDCouponInfo couponInfo = JDUtil.getShowCouponInfo(jdGoods);
        if (couponInfo != null) {
            couponUrl = couponInfo.getLink();
        }
        String materialId = "https://item.jd.com/" + goodsId + ".html";
        String jumpLink = JDApiUtil.convertLinkWithSubUnionId(materialId, couponUrl, JDApiUtil.POSITION_SHARE + "",user.getId() + "");
        boolean coupon = false;
        if (couponInfo != null) {
            coupon = true;
        }
        String quanPrice = "";
        String couponAmount = "";
        if (coupon) {
            quanPrice = BigDecimalUtil.getWithNoZera(JDUtil.getQuanPrice(jdGoods)).toString() + "";
            couponAmount = BigDecimalUtil.getWithNoZera(couponInfo.getDiscount()).toString();
        }
        String sales = JDUtil.getSaleCount(jdGoods.getInOrderCount30Days());
        // 获取推荐语
        String recommendText = shareGoodsTextTemplateService.getRecommendText(coupon, jdGoods.getSkuName(), sales,
                couponAmount, null);
        // 获取评论语
        BigDecimal price = jdGoods.getPrice();
        JDPingouInfo pinGouInfo = jdGoods.getPinGouInfo();
        if (pinGouInfo != null) {
            price = pinGouInfo.getPingouPrice();
        }
        String zkPrice = BigDecimalUtil.getWithNoZera(price).toString();
        String commentText = shareGoodsTextTemplateService.getCommentTextByLink(coupon, jumpLink, zkPrice, quanPrice,
                ConfigKeyEnum.quickShareJDCommentText);
        // 云发单
        sendGoods(robotId, wxId, listOpen, recommendText, commentText,  jdGoods.getImageList(), user.getId(), pid);
    }
    /**
     * 京东商品云发单
     * @param user
     * @param robotId
     * @param wxId
     * @param goodsId
     * @param relationId
     * @param listOpen
     * @throws UserCloudException
     */
    private void sendPDDGoods(UserInfo user, int robotId, String wxId, Long goodsId, String relationId,
            List<UserCloudGroup> listOpen, String pid) throws UserCloudException {
        PDDGoodsDetail goods = pinDuoDuoCacheUtil.getGoodsInfo(goodsId);
        if (goods == null)
            throw new UserCloudException(1, "该商品已下架");
        String jumpLink = PinDuoDuoApiUtil.getPromotionUrl(goodsId, PinDuoDuoApiUtil.PID_SHARE + "", user.getId() + "");
        boolean coupon = true;
        if (goods.getHasCoupon() == null || !goods.getHasCoupon()) {
            coupon = false;
        }
        String quanPrice = "";
        String couponAmount = "";
        if (coupon) {
            BigDecimal hundred = new BigDecimal(100);
            BigDecimal amount = MoneyBigDecimalUtil.div(new BigDecimal(goods.getCouponDiscount()), hundred);
            quanPrice = BigDecimalUtil.getWithNoZera(amount).toString();
            couponAmount = BigDecimalUtil.getWithNoZera(PinDuoDuoUtil.getQuanPrice(goods)).toString();
        }
        String sales = goods.getSalesTip();
        if (StringUtil.isNullOrEmpty(sales)) {
            sales = "0";
        }
        // 获取推荐语
        String recommendText = shareGoodsTextTemplateService.getRecommendText(coupon, goods.getGoodsName(), sales,
                couponAmount, null);
        // 获取评论语
        String zkPrice =  MoneyBigDecimalUtil.div(new BigDecimal(goods.getMinGroupPrice()), new BigDecimal(100)).setScale(2).toString();
        String commentText = shareGoodsTextTemplateService.getCommentTextByLink(coupon, jumpLink, zkPrice, quanPrice,
                ConfigKeyEnum.quickSharePDDCommentText);
        List<String> list = null;
        String[] goodsGalleryUrls = goods.getGoodsGalleryUrls();
        if (goodsGalleryUrls != null && goodsGalleryUrls.length > 0) {
            list = Arrays.asList(goodsGalleryUrls);
        }
        // 云发单
        sendGoods(robotId, wxId, listOpen, recommendText, commentText, list, user.getId(), pid );
    }
    /**
     * 发送商品
     * @param robotId
     * @param title
     * @param comment
     * @param listImg
     * @param wxId
     * @param listOpen
     */
    private void sendGoods(int robotId,String wxId, List<UserCloudGroup> listOpen, String title,
            String comment, List<String> listImg, Long uid, String pid) {
        // 遍历群-朋友圈
        for (UserCloudGroup cloudGroup: listOpen) {
            UserCloudSendContent sendContent = new UserCloudSendContent();
            sendContent.setPid(pid);
            sendContent.setUid(uid);
            sendContent.setGroupId(cloudGroup.getGroupId());
            sendContent.setCreateTime(new Date());
            if(cloudGroup.getType() == UserCloudGroup.TYPE_CIRCLE) { // 朋友圈
                sendContent.setType(UserCloudSendContent.TYPE_CIRCLE);
                String picUrl = "";
                if (listImg.size() > 0) {
                    for (String img: listImg) {
                        picUrl += "," + img;
                    }
                }
                sendContent.setTitle(title);
                sendContent.setPicUrl(picUrl);
                // 发圈内容
                String circleId = AitaokerApiUtil.macsendCircle(robotId, title, picUrl);
                // 评论文本
                if (!StringUtil.isNullOrEmpty(circleId)) {
                    sendContent.setState(true);
                    List<String> list = new ArrayList<>();
                    boolean macsend = AitaokerApiUtil.macsendCircleComment(robotId, wxId, circleId, comment);
                    if (macsend) {
                        list.add(comment);
                    }
                    sendContent.setComments(list);
                }
            } else {
                sendContent.setType(UserCloudSendContent.TYPE_GROUP);
                // 发送文本
                if (!StringUtil.isNullOrEmpty(title)) {
                    boolean macsend = AitaokerApiUtil.macsendText(robotId, cloudGroup.getGroupId(), title);
                    if (macsend)
                        sendContent.setTitle(title);
                }
                // 发送图片
                String picurl = listImg.get(0);
                if (!StringUtil.isNullOrEmpty(picurl)) {
                    String imgBase64 = ImageToBase64.NetImageToBase64(picurl);
                    boolean macsend = AitaokerApiUtil.macsendImgBase64(robotId, cloudGroup.getGroupId(), imgBase64);
                    if (macsend)
                        sendContent.setPicUrl(picurl);
                }
                // 评论文本
                List<String> list = new ArrayList<>();
                boolean macsend = AitaokerApiUtil.macsendText(robotId, cloudGroup.getGroupId(), comment);
                if (macsend) {
                    list.add(comment);
                }
                sendContent.setState(true);
                sendContent.setComments(list);
            }
            userCloudSendContentService.save(sendContent);
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/service/inter/goods/ShareGoodsTextTemplateService.java
@@ -4,6 +4,7 @@
import com.yeshi.fanli.dto.vip.goods.VIPGoodsInfo;
import com.yeshi.fanli.entity.goods.ShareGoodsTextTemplate;
import com.yeshi.fanli.entity.jd.JDGoods;
import com.yeshi.fanli.entity.system.ConfigKeyEnum;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
import com.yeshi.fanli.exception.goods.ShareGoodsTextTemplateException;
@@ -226,5 +227,33 @@
    public void saveTemplatePDD(Long uid, String template) throws ShareGoodsTextTemplateException;
    /**
     * 获取推荐语文本
     * @param coupon
     * @param title
     * @param sales
     * @param couponAmount
     * @param description
     */
    public String getRecommendText(boolean coupon, String title, String sales, String couponAmount, String description);
    /**
     * 根据淘口令获取评论语
     * @param coupon
     * @param taoToken
     * @param zkPrice
     * @param quanPrice
     */
    public String getCommentTextByTaoToken(boolean coupon, String taoToken, String zkPrice, String quanPrice);
    /**
     * 根据链接获取评论语
     * @param coupon
     * @param link
     * @param zkPrice
     * @param quanPrice
     * @param keyEnum
     */
    public String getCommentTextByLink(boolean coupon, String link, String zkPrice, String quanPrice, ConfigKeyEnum keyEnum);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/QrCodeService.java
@@ -91,4 +91,16 @@
    public FileUploadResult drawGoodsPosterXCX(InputStream erCodeStream, UserInfo user, GoodsDetailVO goods);
    public FileUploadResult drawDynamicGoodsPoster(String erCodeUrl, String portrait, String inviteCode, String mainPic, GoodsDetailVO goods);
    /**
     * 单个商品快速分享图
     * @param erCodeUrl
     * @param portrait
     * @param inviteCode
     * @param mainPic
     * @param goods
     * @return
     */
    public FileUploadResult drawGoodsQuickhShare(String erCodeUrl, String portrait, String inviteCode, String mainPic,
            GoodsDetailVO goods);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudGoodsService.java
New file
@@ -0,0 +1,63 @@
package com.yeshi.fanli.service.inter.user.cloud;
import java.util.List;
import java.util.Set;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGoods;
import com.yeshi.fanli.exception.user.cloud.UserCloudGoodsException;
public interface UserCloudGoodsService {
    public List<UserCloudGoods> listByUid(long start, int count, Long uid);
    public long countByUid(Long uid);
    /**
     * 根据商品信息查询
     * @param uid
     * @param goodsId
     * @param goodsType
     * @return
     */
    public UserCloudGoods getByUidAndGoods(Long uid, Long goodsId, Integer goodsType);
    /**
     * 添加发单库商品
     * @param uid
     * @param set
     * @param goodsType
     * @throws UserCloudGoodsException
     */
    public void addGoods(Long uid, Set<Long> set, Integer goodsType) throws UserCloudGoodsException;
    /**
     * 用户删除商品
     * @param id
     * @param uid
     */
    public void deleteByPrimaryKeyAndUid(Long id, Long uid);
    /**
     * 查询未分享的商品
     * @param uid
     * @return
     */
    public List<UserCloudGoods> listByNotShare(Long uid);
    /**
     * 查询
     * @param id
     */
    public UserCloudGoods selectByPrimaryKey(Long id);
    /**
     * 更新信息
     * @param record
     */
    public void updateByPrimaryKeySelective(UserCloudGoods record);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudGroupService.java
New file
@@ -0,0 +1,62 @@
package com.yeshi.fanli.service.inter.user.cloud;
import java.util.List;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
import com.yeshi.fanli.exception.user.cloud.UserCloudGroupException;
public interface UserCloudGroupService {
    /**
     * 根据uid查询
     * @param uid
     * @return
     */
    public List<UserCloudGroup> listByUid(Long uid);
    /**
     * 首次添加朋友圈状态
     * @param uid
     */
    public void addCircle(Long uid);
    /**
     * 创建群信息
     * @param uid
     * @throws UserCloudGroupException
     */
    public void addGroup(Long uid, String groupId, String groupName, int maxNum);
    /**
     * 根据uid删除
     * @param uid
     */
    public void deleteGroupByUid(Long uid);
    /**
     * 切换群状态
     * @param uid
     * @param id
     * @param state
     */
    public void switchGroupState(long uid, long id, boolean state) throws UserCloudGroupException;
    /**
     * 切换朋友圈状态
     * @param uid
     * @param state
     * @throws UserCloudGroupException
     */
    public void switchCircleState(long uid, boolean state) throws UserCloudGroupException;
    /**
     * 获取群列表
     * @param uid
     * @return
     */
    public List<UserCloudGroup> listGroupByUid(Long uid);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudManageService.java
New file
@@ -0,0 +1,22 @@
package com.yeshi.fanli.service.inter.user.cloud;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudManage;
public interface UserCloudManageService {
    /**
     * 保存信息
     * @param uid
     * @param official
     * @param custom
     */
    public void save(Long uid, Boolean official, Boolean custom);
    /**
     * 根据id查询
     * @param uid
     * @return
     */
    public UserCloudManage selectByPrimaryKey(Long uid);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudOrderService.java
New file
@@ -0,0 +1,73 @@
package com.yeshi.fanli.service.inter.user.cloud;
import java.util.List;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
import com.yeshi.fanli.exception.user.cloud.UserCloudOrderException;
public interface UserCloudOrderService {
    /**
     * 创建未付款订单
     * @param uid
     * @param type
     * @throws UserCloudOrderException
     */
    public UserCloudOrder addCloudOrder(Long uid, String type) throws UserCloudOrderException;
    /**
     * 查询后一条订单 -未支付的
     * @param uid
     * @param type
     * @return
     */
    public UserCloudOrder getLastOrderByUnpaid(Long uid, String type);
    /**
     * 查询后一条订单 -支付完成的
     * @param uid
     * @param type
     * @return
     */
    public UserCloudOrder getLastOrderByPayEnd(Long uid, String type);
    /**
     * 查询订单记录
     * @param page
     * @param count
     * @param uid
     * @param state 1-成功 -未支付
     * @return
     */
    public List<UserCloudOrder> getOrderRecord(int page, int count, Long uid, Integer state);
    /**
     * 统计状态
     * @param uid
     * @param state
     * @return
     */
    public long countOrderRecord(Long uid, Integer state);
    public UserCloudOrder selectByPrimaryKey(Long id);
    /**
     * 更新
     * @param cloudOrder
     */
    public void updateByPrimaryKeySelective(UserCloudOrder cloudOrder);
    /**
     * 支付成功更新订单状态
     * @param orderId
     * @throws UserCloudOrderException
     */
    public void cloudPayCloudSuccess(Long orderId) throws UserCloudOrderException;
    /**
     * 查询最近更新但未付款的
     * @return
     */
    public List<UserCloudOrder> getLasthourByUnpaid();
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudSendContentService.java
New file
@@ -0,0 +1,15 @@
package com.yeshi.fanli.service.inter.user.cloud;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendContent;
public interface UserCloudSendContentService {
    /**
     * 保存
     * @param record
     * @return
     */
    public UserCloudSendContent save(UserCloudSendContent record);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudSendRecordService.java
New file
@@ -0,0 +1,25 @@
package com.yeshi.fanli.service.inter.user.cloud;
import java.util.List;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudSendRecord;
public interface UserCloudSendRecordService {
    /**
     * 查询已发送记录
     * @param uid
     * @param sendId
     * @param sendOrigin
     * @return
     */
    public List<UserCloudSendRecord> listByUidAndSendId(Long uid, String sendId, String sendOrigin);
    /**
     * 保存
     * @param record
     * @return
     */
    public UserCloudSendRecord save(UserCloudSendRecord record);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/cloud/UserCloudService.java
New file
@@ -0,0 +1,87 @@
package com.yeshi.fanli.service.inter.user.cloud;
import com.yeshi.fanli.entity.bus.user.cloud.CloudOrderMenuEnum;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloud;
import com.yeshi.fanli.exception.user.cloud.UserCloudException;
public interface UserCloudService {
    /**
     *  查询有效
     * @return
     */
    public UserCloud getValidByUid(Long uid);
    /**
     * 统计所有
     * @param uid
     * @return
     */
    public long countByUid(Long uid);
    /**
     * 最后一条
     * @param uid
     * @return
     */
    public UserCloud getLastByUid(Long uid);
    /**
     * 更新登录微信信息
     * @param uid
     * @param wxId
     * @param wxName
     * @param wxPortrait
     */
    public void updateWXInfo(Long uid, String wxId, String wxName, String wxPortrait) throws UserCloudException;
    /**
     * 支付完成开通云发单信息
     * @param uid
     * @param orderId
     * @param menuEnum
     * @throws UserCloudException
     */
    public void openCloud(Long uid, Long orderId, CloudOrderMenuEnum menuEnum) throws UserCloudException;
    /**
     * 刷新群
     * @param uid
     * @throws UserCloudException
     */
    public void searchGroup(Long uid) throws UserCloudException;
    /**
     * 发送自定义商品
     * @param uid
     * @param id
     */
    public void autoSendCustomGoods(Long uid, Long id);
    /**
     * 自动发送动态
     * @param uid
     * @param id
     */
    public void autoSendByDynamic(Long uid, String id);
    /**
     * 手动云发单 - 动态
     * @param uid
     * @param id
     * @throws UserCloudException
     */
    public void sendByDynamic(Long uid, String id) throws UserCloudException;
    /**
     * 手动云发单 - 商品
     * @param uid
     * @param goodsId
     * @param goodsType
     * @throws UserCloudException
     */
    public void sendCustomGoods(Long uid, Long goodsId, Integer goodsType) throws UserCloudException;
}
fanli/src/main/java/com/yeshi/fanli/service/manger/alipay/UserCloudAlipayManager.java
New file
@@ -0,0 +1,103 @@
package com.yeshi.fanli.service.manger.alipay;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.yeshi.fanli.entity.bus.user.cloud.CloudOrderMenuEnum;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudOrder;
import com.yeshi.fanli.exception.user.cloud.UserCloudException;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudGroupService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudManageService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudOrderService;
import com.yeshi.fanli.service.inter.user.cloud.UserCloudService;
import com.yeshi.fanli.util.alipay.AlipayApi;
import com.yeshi.fanli.util.alipay.AlipayWapConfig;
/**
 *  云发单支付管理
 * @author Administrator
 *
 */
@Component
public class UserCloudAlipayManager {
    @Resource
    private UserCloudService userCloudService;
    @Resource
    private UserCloudOrderService userCloudOrderService;
    @Resource
    private UserCloudGroupService userCloudGroupService;
    @Resource
    private UserCloudManageService userCloudManageService;
    public static final String  TRADE_INDEX = "yufadan-";
    /**
     * 创建支付订单
     * @param uid
     * @param type
     * @return
     * @throws Exception
     * @throws UserCloudException
     */
    @Transactional(rollbackFor = Exception.class)
    public String getAlipayForm(Long uid, String type) throws Exception, UserCloudException{
        CloudOrderMenuEnum menuEnum = CloudOrderMenuEnum.getMenuEnum(type);
        if (menuEnum == null)
            throw new UserCloudException(1, "套餐类型不匹配");
        // 订单信息
        UserCloudOrder cloudOrder = userCloudOrderService.getLastOrderByUnpaid(uid, type);
        if (cloudOrder == null)
            cloudOrder = userCloudOrderService.addCloudOrder(uid, type);
        if (cloudOrder == null || cloudOrder.getId() == null)
            throw new UserCloudException(1, "创建订单信息失败");
        // 待请求参数数组
        Map<String, String> map = new HashMap<String, String>();
        map.put("seller_id", AlipayWapConfig.SELLER_ID);// 收款方账号
        // 订单号
        map.put("out_trade_no", TRADE_INDEX + cloudOrder.getId());
        // 订单金额:0.01元,精准到分
        map.put("total_amount", menuEnum.getMoney() + "");
        // 订单标题
        map.put("subject", "云发单充值");
        // 销售产品码,商家和支付宝签约的产品码
        map.put("product_code", type);
        // 该笔订单允许的最晚付款时间,逾期将关闭交易  15分钟
        map.put("timeout_express", "15m");
        // 支付成功后返回哪个前端页面
        String returnUrl = "http://apph5.banliapp.com";
        // 支付成功后回调地址
        String notifyUrl = "http://192.168.1.253:8080/fanli/api/v2/user/cloud/payEnd?id=" +cloudOrder.getId();
        // 获取支付form
        return AlipayApi.tradeWapPayRequest(map, returnUrl, notifyUrl);
    }
    /**
     * 查询订单交易是否支付成功
     * @param orderId
     * @throws Exception
     */
    public void tradeQueryByOrderId(Long orderId) throws Exception {
        boolean result = AlipayApi.tradeQuery(TRADE_INDEX + orderId, null, null, null);
        // 支付成功
        if (result) {
            userCloudOrderService.cloudPayCloudSuccess(orderId);
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/util/ImageToBase64.java
New file
@@ -0,0 +1,79 @@
package com.yeshi.fanli.util;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import Decoder.BASE64Encoder;
public class ImageToBase64 {
    public static void main(String[] args) {
        // 第一个:把网络图片装换成Base64
        String netImagePath = "http://ec-1255749512.file.myqcloud.com/swiperPic/c7847b574a79400298bc63706fd89faf.jpeg";
        // 下面是网络图片转换Base64的方法
        String netImageToBase64 = NetImageToBase64(netImagePath);
        System.out.println(netImageToBase64);
        // 下面是本地图片转换Base64的方法
         String imagePath = "本地图片路径";
         ImageToBase64(imagePath);
    }
    /**
     * 网络图片转换Base64的方法
     *
     * @param netImagePath     
     */
    public static String NetImageToBase64(String netImagePath) {
        try {
            // 创建URL
            URL url = new URL(netImagePath);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            ByteArrayOutputStream data = new ByteArrayOutputStream();
            // 将内容读取内存中
            int len = -1;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 关闭流
            is.close();
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 本地图片转换Base64的方法
     *
     * @param imgPath     
     */
    public static String ImageToBase64(String imgPath) {
        try {
            InputStream in = new FileInputStream(imgPath);
            byte[] data = new byte[in.available()];
            in.read(data);
            in.close();
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/ImageUtil.java
@@ -43,6 +43,243 @@
public class ImageUtil {
    /**
     * 分析海报图
     * @param qrcode
     * @param portraitStream
     * @param goods
     * @return
     */
    public static InputStream drawGoodsQuickhShare(InputStream qrcode, InputStream portraitStream, String inviteCode,
            String mainPic, GoodsDetailVO goods) {
        try {
            String fontPath = "/usr/share/fonts/PingFang_Medium.ttf";
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("win")) {
                fontPath = "D:/PingFang_Medium.ttf";
            }
            String fontBoldPath = "/usr/share/fonts/PingFang_Heavy_0.ttf";
            if (os.toLowerCase().startsWith("win")) {
                fontBoldPath = "D:/PingFang_Heavy_0.ttf";
            }
            Font font24 = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(24.0f);
            Font font26 = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(26.0f);
            Font boldFont36 = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(36.0f);
            int px = 640; // 图片宽度
            // int py = 1154; // 图片高度 显示邀请码
            int py = 1060; // 图片高度
            final BufferedImage targetImg = new BufferedImage(px, py, 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 = (Graphics2D) targetImg.getGraphics();
            g2d.setRenderingHints(mapH);
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, px, py);
            int x = 640;
            int y = 640;
            int spacing = 20; // 右边距
            // 1、画商品主图
            InputStream picStream = HttpUtil.getAsInputStream(mainPic);
            // InputStream picStream =
            // ImageUtil.class.getClassLoader().getResourceAsStream("image/share/test_pic1.jpg");
            g2d.drawImage(ImageIO.read(picStream), 0, 0, x, y, null);
            // 2、画来源图标
            int length = 10;
            int row1 = 450;
            int iconWidth = 72;
            String source = "";
            InputStream icon = null;
            int goodsType = goods.getGoodsType();
            if (goodsType == Constant.SOURCE_TYPE_TAOBAO) {
                source = "淘宝";
                if (goods.getShopType() == 10) {
                    icon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_tb.png");
                } else {
                    icon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_tm.png");
                }
            } else if (goodsType == Constant.SOURCE_TYPE_JD) {
                source = "京东";
                icon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_jd.png");
            } else if (goodsType == Constant.SOURCE_TYPE_PDD) {
                source = "拼多多";
                length = 9;
                row1 = row1 - 26;
                iconWidth = iconWidth + 28;
                icon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_pdd.png");
            } else {
                return null;
            }
            g2d.drawImage(ImageIO.read(icon), spacing, y + 20, iconWidth, 34, null);
            // 3、商品标题内容
            int row = 0;
            String title = goods.getTitle();
            length = ImageUtil.getTextLengthByWidth(g2d, font26, title, row1, length);
            g2d.setFont(font26);
            g2d.setColor(new Color(0, 0, 0));
            g2d.drawString(title.substring(0, length), spacing + iconWidth + 5, y + 45 + row * 36);
            row++;
            title = title.substring(length);
            int length2 = ImageUtil.getTextLengthByWidth(g2d, font26, title, 600, 11);
            if (length2 > 24) {
                g2d.drawString(title.substring(0, 21) + "...", spacing, y + 45 + row * 36);
            } else {
                g2d.drawString(title.substring(0, length2), spacing, y + 45 + row * 36);
            }
            int baoYouLength = spacing;
            if (!goods.isHasCoupon()) {
                // 无券
                g2d.setColor(new Color(229, 0, 92));
                g2d.drawString("¥ ", spacing, y + 125);
                g2d.setFont(boldFont36);
                g2d.drawString(MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()).toString(), spacing + 21, y + 125);
            } else {
                // 券后价
                g2d.setFont(font26);
                g2d.setColor(new Color(229, 0, 92));
                g2d.drawString("券后价  ¥ ", spacing, y + 125);
                g2d.setFont(boldFont36);
                String couponPrice = MoneyBigDecimalUtil.getWithNoZera(goods.getCouponPrice()).toString();
                g2d.drawString(couponPrice, spacing + 116, y + 125);
                FontMetrics fm2 = g2d.getFontMetrics(boldFont36);
                int textLength1 = 116 + fm2.stringWidth(couponPrice);
                // 渠道原价
                g2d.setColor(new Color(153, 153, 153));
                g2d.setFont(font24);
                g2d.drawString(goods.getPriceName() + " ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()),
                        spacing + textLength1 + 10, y + 125);
                // 券字
                InputStream quan = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_quan.png");
                g2d.drawImage(ImageIO.read(quan), spacing, y + 140, 47, 40, null);
                // 券面额
                String quanAmount = "¥ " + goods.getCouponInfo().getAmount();
                FontMetrics fm = g2d.getFontMetrics(font26);
                int textLength = fm.stringWidth(quanAmount);
                g2d.setFont(font26);
                g2d.setColor(new Color(229, 0, 92));
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.drawRoundRect(spacing + 42, y + 140, textLength + 20, 39, 10, 10);
                g2d.drawString(quanAmount, spacing + 55, y + 170);
                baoYouLength = spacing + 42 + textLength + 20 + 20;
            }
            // 自营 、包邮
            InputStream ziying = null;
            if (goods.getShopType() == 21) {
                ziying = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_ziying.png");
                g2d.drawImage(ImageIO.read(ziying), baoYouLength, y + 150, 60, 30, null);
            } else if (goods.isBaoyou()) {
                ziying = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_baoyou.png");
                g2d.drawImage(ImageIO.read(ziying), baoYouLength, y + 150, 60, 30, null);
            }
            // 销量
            String sale = null;
            int salesType = goods.getSalesType();
            if (salesType == 1) {
                sale = "月销";
            } else if (salesType == 2) {
                sale = "2小时销量";
            } else if (salesType == 3) {
                sale = "今日销量";
            } else if (salesType == 4) {
                sale = "总销量";
            } else {
                sale = "月销";
            }
            sale = sale + " " + goods.getSalesCount();
            FontMetrics fm = g2d.getFontMetrics(font24);
            int textLength = fm.stringWidth(sale);
            g2d.setFont(font24);
            g2d.setColor(new Color(153, 153, 153));
            g2d.drawString(sale, spacing + 605 - textLength, y + 125);
            // 下单提示
            InputStream downTip = null;
            if (goodsType == Constant.SOURCE_TYPE_TAOBAO) {
                downTip = ImageUtil.class.getClassLoader().getResourceAsStream("image/share/down_tip_tb.png");
            } else {
                downTip = ImageUtil.class.getClassLoader().getResourceAsStream("image/share/down_tip_jd_pdd.png");
            }
            g2d.drawImage(ImageIO.read(downTip), spacing, y + 200, 382, 203, null);
            // 二维码图框
            InputStream codeFrame = ImageUtil.class.getClassLoader()
                    .getResourceAsStream("image/share/qr_code_frame01.png");
            g2d.drawImage(ImageIO.read(codeFrame), spacing + 405, y + 200, 200, 203, null);
            // 画二维码
            int codeSize = 170;
            int pX = spacing + 422;
            int pY = y + 217;
            g2d.drawImage(ImageIO.read(qrcode), pX, pY, codeSize, codeSize, null);
            int portraitSize = 200 * 5 / 23;
            int pPX = pX + codeSize / 2 - portraitSize / 2;
            int pPY = pY + codeSize / 2 - portraitSize / 2;
            // 头像白色边框
            g2d.setColor(Color.WHITE);
            g2d.fillRoundRect(pPX - 4, pPY - 4, portraitSize + 8, portraitSize + 8, 5, 5);
            g2d.setRenderingHints(mapH);
            // 画头像
            BufferedImage portraitImg = ImageIO.read(portraitStream);
            portraitImg = ImageUtil.zoomInImage(portraitImg, portraitSize, portraitSize);
            portraitImg = ImageUtil.roundImage(portraitImg, 10);
            g2d.drawImage(portraitImg, pPX, pPY, portraitSize, portraitSize, null);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(new Color(255, 231, 224));
            g2d.fillRoundRect(spacing, y + 420, 607, 79, 10, 10);
            InputStream banliStream = ImageUtil.class.getClassLoader().getResourceAsStream("image/banlikuaisheng.png");
            g2d.drawImage(ImageIO.read(banliStream), spacing + 20, y + 440, 170, 38, null);
            inviteCode = "邀请码:" + inviteCode;
            Font font26d28 = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(26.28f);
            FontMetrics fmcode = g2d.getFontMetrics(font26d28);
            int codeLength = fmcode.stringWidth(inviteCode);
            // 邀请码背景
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(new Color(229, 71, 27));
            g2d.fillRoundRect(spacing + (600 - (int) (codeLength * 1.1)), y + 440, 10 + codeLength, 37, 10, 10);
            // 邀请码文字
            g2d.setFont(font26d28);
            g2d.setColor(new Color(255, 255, 255));
            g2d.drawString(inviteCode, spacing + (600 - (int) (codeLength * 1.1) + 5), y + 468);
            g2d.dispose();
            ByteArrayOutputStream aos = new ByteArrayOutputStream();
            ImageIO.write(targetImg, "JPEG", aos);
            return new ByteArrayInputStream(aos.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
            try {
                LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        return null;
    }
    // 画商品分享图
    public static InputStream drawGoodsShareXCX(InputStream qrcode, UserInfo user, GoodsDetailVO goods) {
        try {
fanli/src/main/java/com/yeshi/fanli/util/aitaoker/AitaokerApiUtil.java
New file
@@ -0,0 +1,506 @@
package com.yeshi.fanli.util.aitaoker;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.yeshi.utils.HttpUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yeshi.fanli.dto.aitaoker.QrcodeLoginDTO;
import com.yeshi.fanli.dto.aitaoker.RobotInfoDTO;
import com.yeshi.fanli.dto.aitaoker.WeiXinGroupDTO;
import com.yeshi.fanli.util.StringUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class AitaokerApiUtil {
    public static String APP_KEY = "1077080250";
    public static String SECRET_KEY = "7c6118bd-7aa5-65b8-c6d4-058728e9446f";
    // 请求连接
    private static String SERVER_URL = "http://router.itaoke.org/api";
    private static String baseRequest(String method, Map<String, String> param) {
        Map<String, String> baseMap = new HashMap<>();
        baseMap.put("app_key", APP_KEY);
        baseMap.put("v", "1.0");
        baseMap.put("format", "json");
        baseMap.put("sign_method", "md5");
        baseMap.put("timestamp", System.currentTimeMillis()+ "");
        baseMap.put("method", method);
        baseMap.put("domain", "hi.flqapp.com");
        baseMap.put("client", "113.249.194.232");
        baseMap.put("partner_id", "top-sdk-php-20190618");
        String url = combinedUrl(baseMap);
        if (param != null) {
            Iterator<String> its = param.keySet().iterator();
            while (its.hasNext()) {
                String key = its.next();
                baseMap.put(key, param.get(key));
            }
        }
        url+= "sign=" + getSign(baseMap);
        return HttpUtil.post(url, param);
    }
    /**
     * 拼接所有系统参数包括sign的url
     * @param params
     * @return
     */
    private static String combinedUrl (Map<String, String> params) {
        String url = SERVER_URL + "?";
        Iterator<String> its = params.keySet().iterator();
        while (its.hasNext()) {
            String key = its.next();
            try {
                url += String.format("%s=%s&", key, URLEncoder.encode(params.get(key), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return url;
    }
    /**
     * 获取签名
     * @param params
     * @return
     */
    private static String getSign(Map<String, String> params) {
        List<String> list = new ArrayList<>();
        Iterator<String> its = params.keySet().iterator();
        while (its.hasNext()) {
            String key = its.next();
            list.add(key + params.get(key));
        }
        Collections.sort(list);
        String str = "";
        for (String st : list) {
            str += st;
        }
        return StringUtil.Md5(SECRET_KEY + str + SECRET_KEY).toUpperCase();
    }
    /**
     * 获取登录二维码
     * @param robotId
     * @return
     */
    public static QrcodeLoginDTO getQrcodeMaclogin(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.qrcode.maclogin", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        resultJson = resultJson.optJSONObject("data");
        if (resultJson != null) {
            Type type = new TypeToken<QrcodeLoginDTO>() {}.getType();
            return new Gson().fromJson(resultJson.toString(), type);
        }
        return null;
    }
    /**
     *  检查是否扫码
     * @param robotId
     * @return
     */
    public static Boolean getQrcodeStatus(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.qrcode.status", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        resultJson = resultJson.optJSONObject("data");
        if (resultJson != null && !StringUtil.isNullOrEmpty(resultJson.optString("status"))) {
            int optInt = resultJson.optInt("status");
            if (optInt == 1) {
                return true;
            } else {
                return false;
            }
        }
        return null;
    }
    /**
     *   检查是否登陆(真正的登录接口)
     * @param robotId 机器人id
     * @param wId  获取二维码接口返回的微信实例id
     * @return
     */
    public static QrcodeLoginDTO getQrcodeMacloginCheck(int robotId, String wId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("uuid", wId);
        // 请求结果
        String result = baseRequest("itaoke.robot.check.maclogin", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        resultJson = resultJson.optJSONObject("data");
        if (resultJson != null && !StringUtil.isNullOrEmpty(resultJson.optString("wcId"))) {
            Type type = new TypeToken<QrcodeLoginDTO>() {}.getType();
            return new Gson().fromJson(resultJson.toString(), type);
        }
        return null;
    }
    /**
     *   检查是否在线
     * @param robotId 机器人id
     * @return
     */
    public static boolean onlineCheck(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.check.online", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            return true;
        }
        return false;
    }
    /**
     * 4.强制下线
     * @param robotId 机器人id
     * @return
     */
    public static boolean macloginOffline(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.force.offline", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            return true;
        }
        return false;
    }
    /**
     *  掉线重连
     * @param robotId 机器人id
     * @return
     */
    public static boolean loseReconnet(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.lose.reconnet", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            return true;
        }
        return false;
    }
    /**
     * 创建机器人
     * @param month 月数
     * @param robotType 机器人类型 1 发单机器人 2转发机器人 3 返利机器人 4全能机器人 5小型机器人 6发圈机器人
     * @param wechatrobot  微信号
     * @param agentUid  代理id
     * @return
     */
    public static RobotInfoDTO robotCreate(int month , int robotType, String wechatrobot, String agentUid) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("month", month  +"");
        map.put("robot_type", robotType + "");
        map.put("wechatrobot", wechatrobot);
        if(!StringUtil.isNullOrEmpty(agentUid))
            map.put("agent_uid", agentUid);
        // 请求结果
        String result = baseRequest("itaoke.robot.create.get", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            Type type = new TypeToken<RobotInfoDTO>() {}.getType();
            return new Gson().fromJson(resultJson.toString(), type);
        }
        return null;
    }
    /**
     * 机器人更换微信号
     * @param robotId 机器人id
     * @param wxid 微信号
     * @return
     */
    public static RobotInfoDTO robotChangeWeiXin(int robotId, String wxid) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("wechatrobot", wxid);
        // 请求结果
        String result = baseRequest("itaoke.robot.change.get", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            Type type = new TypeToken<RobotInfoDTO>() {}.getType();
            return new Gson().fromJson(resultJson.toString(), type);
        }
        return null;
    }
    /**
     * 机器人续费
     * @param robotId 机器人id
     * @param wxid 微信号
     * @return
     */
    public static RobotInfoDTO robotRenewals(int robotId, int month) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("month", month +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.change.get", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            Type type = new TypeToken<RobotInfoDTO>() {}.getType();
            return new Gson().fromJson(resultJson.toString(), type);
        }
        return null;
    }
    /**
     * 删除机器人
     * @param robotId
     * @return
     */
    public static boolean robotDelete(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.delete.get", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            return true;
        }
        return false;
    }
    /**
     * 获取好友-群列表
     * @param robotId
     * @return
     */
    public static List<WeiXinGroupDTO> getContract(int robotId) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        // 请求结果
        String result = baseRequest("itaoke.robot.get.contract", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("0000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            // 订阅号
            //JSONArray publicArray = resultJson.optJSONArray("public");
            // 好友列表
            //JSONArray friendArray = resultJson.optJSONArray("friend");
            // 群列表
            JSONArray groupArray = resultJson.optJSONArray("group");
            if (groupArray != null && groupArray.size() > 0) {
                List<WeiXinGroupDTO> listGroup = new ArrayList<>();
                Type type = new TypeToken<RobotInfoDTO>() {}.getType();
                Gson gson = new Gson();
                for (int i = 0 ;i < groupArray.size(); i ++) {
                    listGroup.add(gson.fromJson(groupArray.get(i).toString(), type));
                }
            }
        }
        return null;
    }
    /**
     * 发朋友圈
     * @param robotId
     * @param content
     * @param picUrl 图片url,多个请用;分隔
     * @return
     */
    public static String macsendCircle(int robotId, String content, String picUrl) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("pic_url", picUrl);
        map.put("content", content);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.circle", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("1000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            return resultJson.optString("id");
        }
        return null;
    }
    /**
     * 朋友圈发送视频
     * @param robotId
     * @param videoPath 视频地址
     * @param thumbPath 封面url
     * @return
     */
    public static String macsendCircleVideo(int robotId, String videoPath, String thumbPath) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("video_path", videoPath);
        map.put("thumb_path", thumbPath);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.videocircle", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("1000".equals(resultJson.optString("code"))) {
            resultJson = resultJson.optJSONObject("data");
            return resultJson.optString("id");
        }
        return null;
    }
    /**
     * 朋友圈发送视频
     * @param robotId
     * @param videoPath 视频地址
     * @param thumbPath 封面url
     * @return
     */
    public static boolean macsendCircleComment(int robotId, String wxId, String msgId, String content) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("wx_id", wxId);
        map.put("msg_id", msgId);
        map.put("content", content);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.circlecomment", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if ("1000".equals(resultJson.optString("code"))) {
            return true;
        }
        return false;
    }
    /**
     *  发文本消息
     * @param robotId
     * @param wxId 微信群ID
     * @param content 内容
     * @return
     */
    public static boolean macsendText(int robotId, String toWxId, String content) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("toWxId", toWxId );
        map.put("content", content);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.text", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if (resultJson.optInt("code") == 1000) {
            return true;
        }
        return false;
    }
    /**
     * 发base64图
     * @param robotId
     * @param wxId
     * @param imgBase64
     * @return
     */
    public static boolean macsendImgBase64(int robotId, String toWxId, String imgBase64) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("toWxId", toWxId );
        map.put("base64_data", imgBase64);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.base64", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if (resultJson.optInt("code") == 1000) {
            return true;
        }
        return false;
    }
    /**
     *   发链接消息
     * @param robotId
     * @param wxId 微信群ID
     * @param title 标题
     * @param url 链接
     * @param description 描述
     * @param thumbUrl 图片
     * @return
     */
    public static boolean macsendCard(int robotId, String wxId, String title, String url,
            String description ,String thumbUrl) {
        // 请求参数
        Map<String, String> map = new HashMap<>();
        map.put("robot_id", robotId +"");
        map.put("wx_id", wxId);
        map.put("title", title);
        map.put("url", url);
        map.put("description", description);
        map.put("thumbUrl", thumbUrl);
        // 请求结果
        String result = baseRequest("itaoke.robot.macsend.card", map);
        JSONObject resultJson = JSONObject.fromObject(result);
        if (resultJson.optInt("code") == 1000) {
            return true;
        }
        return false;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/alipay/AliPaySignUtil.java
New file
@@ -0,0 +1,91 @@
package com.yeshi.fanli.util.alipay;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
public class AliPaySignUtil {
    /**
     * 连接Map键值对
     *
     * @param map
     *            Map
     * @param prefix
     *            前缀
     * @param suffix
     *            后缀
     * @param separator
     *            连接符
     * @param ignoreEmptyValue
     *            忽略空值
     * @param ignoreKeys
     *            忽略Key
     * @return 字符串
     */
    public static String joinKeyValue(Map<String, Object> map, String prefix, String suffix, String separator,
                                      boolean ignoreEmptyValue, String... ignoreKeys) {
        List<String> list = new ArrayList<String>();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                String value = String.valueOf(entry.getValue());
                if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key)
                        && (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
                    list.add(key + "=" + (value != null ? value : ""));
                }
            }
        }
        return (prefix != null ? prefix : "") + StringUtils.join(list, separator) + (suffix != null ? suffix : "");
    }
    /**
     * 把request请求参数转换为Map<String,String>
     * @param request 该请求
     * @return Map<String,String>格式的参数
     */
    public static Map<String,String> request2Map(HttpServletRequest request){
        Enumeration<String> names = request.getParameterNames();
        Map<String, String> resData = new HashMap<String, String>();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            resData.put(name, request.getParameter(name));
        }
        return resData;
    }
    /**
     * Bean转map
     * @param bean 要转的bean
     * @return 返回一个TreeMap
     */
    public static TreeMap<String, String> bean2TreeMap(Object bean) {
        TreeMap<String, String> requestMap = new TreeMap<String, String>();
        Class<?> cls = bean.getClass();
        Field[] fields = cls.getDeclaredFields();
        try {
            for (int i = 0; i < fields.length; i++) {
                String key = fields[i].getName();
                fields[i].setAccessible(true);
                Object value = fields[i].get(bean);
                if ("sign".equals(key) || value == null || StringUtils.isEmpty(value.toString())) {
                    continue;
                }
                requestMap.put(key, value.toString());
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return requestMap;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/alipay/AlipayApi.java
New file
@@ -0,0 +1,86 @@
package com.yeshi.fanli.util.alipay;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.yeshi.fanli.util.StringUtil;
public class AlipayApi {
    /**
     * 创建支付请求
     * @param map
     * @return
     * @throws Exception
     */
    public static String tradeWapPayRequest(Map<String, String> map, String payNotify, String backUrl) throws Exception{
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        // 前台回调地址
        alipayRequest.setReturnUrl(backUrl);
        // 成功付款回调
        alipayRequest.setNotifyUrl(payNotify);
        alipayRequest.setBizContent(URLEncoder.encode(JSON.toJSONString(map), "UTF-8"));
        return AlipayWapConfig.getInstance().pageExecute(alipayRequest).getBody();
    }
    /**
     * 查询是否交易完成
     * @param outTradeNo
     * @param tradeNo
     * @param orgPid
     * @param queryOptions
     * @return
     * @throws Exception
     */
    public static boolean tradeQuery (String outTradeNo, String tradeNo, String orgPid, String queryOptions) throws Exception {
        // 订单支付时传入的商户订单号,和支付宝交易号不能同时为空
        if (StringUtil.isNullOrEmpty(outTradeNo) || StringUtil.isNullOrEmpty(outTradeNo)) {
            return false;
        }
        // 待请求参数数组
        Map<String, String> map = new HashMap<String, String>();
        if (!StringUtil.isNullOrEmpty(outTradeNo))
            map.put("out_trade_no", outTradeNo);
        if (!StringUtil.isNullOrEmpty(tradeNo))
            map.put("trade_no", tradeNo);
        if (!StringUtil.isNullOrEmpty(orgPid))
            map.put("org_pid", orgPid);
        if (!StringUtil.isNullOrEmpty(queryOptions))
            map.put("query_options", queryOptions);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent(URLEncoder.encode(JSON.toJSONString(map), "UTF-8"));
        // 支付宝查询
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayWapConfig.APP_ID,
                AlipayWapConfig.APP_PRIVATE_KEY, AlipayWapConfig.PARAM_TYPE, AlipayWapConfig.CHARSET,
                AlipayWapConfig.ALIPAY_PUBLIC_KEY, AlipayWapConfig.SIGNTYPE);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            // 相应成功
            if ("TRADE_SUCCESS".equals(response.getTradeStatus())) {
                return true; // 交易支付成功
            } else if ("TRADE_FINISHED".equals(response.getTradeStatus())) {
                return true; // (交易结束,不可退款)
            }
        }
        return false;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/alipay/AlipayWapConfig.java
New file
@@ -0,0 +1,99 @@
package com.yeshi.fanli.util.alipay;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
public class AlipayWapConfig {
     // 商户appid
     //public static String APP_ID = "2021001164655513";
    //沙箱环境
     public static String APP_ID = "2016102100734118";
    /**
     * 你的私钥   私钥 pkcs8格式的
     */
    public static String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDtWSMDXc3O7HcWcWiDzbmYyZDAEkVK2arOoPGwPLlxDXXpfPv6s2P9qRmXub6rrpbrKtIRpdbjbAJAwyDfIDBHiQzwWBqAPMk+G+1mrhU/NQEWcu0IT410j0MVODpz3X2zlb4UN7bzmkCkmLS7+/1fhKRQTql+2RXpeDuBvSdYlitVxNoXscPwm+xE7zZ84qS2agOUJHA+HGvb5mpEzA3kNPdGMm6hx0CzcEbNeI9AmbFJyXf6vZuHaQRcAe68MZObECIt/RwJfg+YnKwuDJYW+9+iMEUPbfg9ZjQB8062uPC8mddSPcxslP8//svmTXu+bz1Pl4v2FftErO1w/m5tAgMBAAECggEAXpTawwiqbv8EJcljoMJmZ2BLcn7VZhJ/Yn/4UAaiz05R4o2PzEOYYQj1zeSS+s9EDMqvk6DGlTIBY9VeUAv/sUIICe7SALA4caunWvecN+fjWxLJKjqpX/2G+fnCMVHeOaY+bMgW+9RIVk8UFqVAPsQYxnfSS14uwS7MZ9L8zuukNcYXdfZk030usztQaVkZWAddukUjA0YmquTUArZ63uEcU+LlfOpmWZ7JSiX2H7lIn6Fwilo3N3/J3eqTgTlw5N4V2Dvr962xlIzlJ+d5OuH9tRCEHcNaru2GYa/+trVGzbXwsGuCrtLxeFPQOb5HVmh77IMJbESGMe6V3U/BgQKBgQD6ZYSkrYBIdGGewQkPIFcdHa+ElpT5fCuA1ZamCeeOMKM+08r3dRfhxHWY9RuZDEULzcmHU8X44zA6uxU0qVU6Q07KIGWFUf85G4qcbrL+VV1yHGL3t8vbwRljaAZ6hTeEI/2Vfl8UgsvfV4goc7avvxRM2uYjYb5I5mEakTQIVQKBgQDyqN3b0faP5SIWxkLjXYy4Am5LX97FwtTdNm1DUCi1San/wnBQPb4K3iWp4DZgcjWWxZN8AWWkbabV9oPdwaXxxHRZSPo9AkqPGt2A+iiHxl7xCotM95Mg+OgIe5e9bN5+QBtZ9Sg0xe6bMMDlbBhLvGMIZzcOKzPLtoKkDw/FuQKBgQD367YmuycOFjVl02ld0b6PNIpJdDLyxq/oMxKjOaFMVvn7RgZrd0N7JWLuXJnDsrNWmZ3VYOven0tsiznW12ZsdqI3XVZHZ8WVTKC0fKK7UdhhGJwg+5lb71hs5V2sx+QM8Pmun94SV+L2Mxu8Ob4DSuUVp5NAKxIV6gzxGh3ztQKBgH94e8ssucQPTt/92EdN7kz/YecQfpsOZPmrzKvuoOPSxY3IG23bcUiON+TMFmSFumbwdTBQH4/H1jtRmyXTwxOE6sW4U1PXL0mLiE5nmwDwERG4Q0L0TwKkHmfOXQCx/xL9JCEWar+GNnipnLsoFH88gB168u3rffMGdgwuqU9pAoGATKuOiyHqe8mE5xezVqD3R/yaUo/yjGfV6WedsUEI9Dh1T1MJaehdOyzuxe7h5IVwlsPwy29l0wJ80L0+oO9O9CL9OsxiwNO6QK7nyqI0JfSJc0VhettXxWexVq3eSj0CnFd5ksiDwmmBgCs2r2zEmhyKt/fNmI7yn6djuyVjWT4=";
     /**
     * 编码
     */
    public static String CHARSET = "UTF-8";
    /**
     * 支付宝公钥
     */
     public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzPpFDjI0B1O7S3WDNsUPK1UerFzP+6VGUDVYWDnmU4UcEVYc9/McD8w7+3D2P16achvYF7Xk9gE1TbRTbWkMvIKtwj3MKU+zdevwOTwbvV46UQ3L1DdpFNFx89fYNMf81HTr9oQROIUwSIz2yP0i/CuMW/Tqnb5EWnaz5Ws4m1+ioKKq41oTx6kzF5SxFfvkcRq95KTXgcoNauemUncbjV+Rh2G3ZDBy7sLXKaoY8a5M0jtf1f53MPJJ9LEnJE5oCRj2AHsOMJ4ECjoRTGVJvn2mREoyW8SCDfaT7dPD4bagrspwB/kB2j6P0HnddspB7BfdkuKGSz5YviOhdW3TuwIDAQAB";
    /**
     * 支付宝网关地址
     */
    //private static String GATEWAY = "https://openapi.alipay.com/gateway.do";//正式环境
     // 请求网关地址
     public static String GATEWAY = "https://openapi.alipaydev.com/gateway.do";
    //private static String GATEWAY = "https://openapi.alipay.com/gateway.do";//沙箱环境
    /**
     * 成功付款回调
     */
    public static String PAY_NOTIFY = "http://apph5.banliapp.com";//验签
    /**
     * 支付成功回调
     */
    public static String REFUND_NOTIFY = "";//姑且没用到
    /**
     * 前台通知地址
     */
    public static String RETURN_URL = "http://apph5.banliapp.com";//支付成功后返回哪个前端页面
    /**
     * 参数类型
     */
    public static String PARAM_TYPE = "json";
    /**
     * 成功标识
     */
    public static final String SUCCESS_REQUEST = "TRADE_SUCCESS";
    /**
     * 交易关闭回调(当该笔订单全部退款完毕,则交易关闭)
     */
    public static final String TRADE_CLOSED = "TRADE_CLOSED";
    /**
     * 支付宝开发平台中的支付宝账号(企业)
     */
//    public static final String SELLER_ID = "2088231353656741";
    public static final String SELLER_ID = "2088102180556545"; //沙箱环境
    //签名算法类型(根据生成私钥的算法,RSA2或RSA)
    public static final String SIGNTYPE = "RSA2";
    /**
     * 支付宝请求客户端入口
     */
    private volatile static AlipayClient alipayClient = null;
    /**
     * 不可实例化
     */
    private AlipayWapConfig(){};
    /**
     * 双重锁单例
     * @return 支付宝请求客户端实例
     */
    public static AlipayClient getInstance(){
        if (alipayClient == null){
            synchronized (AlipayWapConfig.class){
                if (alipayClient == null){
                    alipayClient = new DefaultAlipayClient(GATEWAY,APP_ID,APP_PRIVATE_KEY,PARAM_TYPE,CHARSET,ALIPAY_PUBLIC_KEY,SIGNTYPE);
                }
            }
        }
        return alipayClient;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/mybatishandler/CloudOrderMenuEnumHandler.java
New file
@@ -0,0 +1,53 @@
package com.yeshi.fanli.util.mybatishandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.yeshi.fanli.entity.bus.user.cloud.CloudOrderMenuEnum;
public class CloudOrderMenuEnumHandler extends BaseTypeHandler<CloudOrderMenuEnum> {
    @Override
    public CloudOrderMenuEnum getNullableResult(ResultSet arg0, String arg1) throws SQLException {
        String key = arg0.getString(arg1);
        if (arg0.wasNull()) {
            return null;
        } else {
            return CloudOrderMenuEnum.valueOf(key);
        }
    }
    @Override
    public CloudOrderMenuEnum getNullableResult(ResultSet arg0, int arg1) throws SQLException {
        String key = arg0.getString(arg1);
        if (arg0.wasNull()) {
            return null;
        } else {
            // 根据数据库中的key值,定位SexEnum子类
            return CloudOrderMenuEnum.valueOf(key);
        }
    }
    @Override
    public CloudOrderMenuEnum getNullableResult(CallableStatement arg0, int arg1) throws SQLException {
        String key = arg0.getString(arg1);
        if (arg0.wasNull()) {
            return null;
        } else {
            // 根据数据库中的key值,定位SexEnum子类
            return CloudOrderMenuEnum.valueOf(key);
        }
    }
    @Override
    public void setNonNullParameter(PreparedStatement arg0, int arg1, CloudOrderMenuEnum arg2, JdbcType arg3)
            throws SQLException {
        arg0.setString(arg1, arg2.name());
    }
}
fanli/src/main/java/com/yeshi/fanli/vo/user/cloud/UserCloudInfoVO.java
New file
@@ -0,0 +1,99 @@
package com.yeshi.fanli.vo.user.cloud;
import java.util.List;
import com.yeshi.fanli.entity.bus.user.cloud.UserCloudGroup;
public class UserCloudInfoVO {
    private String nickName;// 昵称
    private String portrait;// 头像
    private String wxName;// 微信昵称
    private String openTime;// 开通时间
    private String countdown;// 倒计时间
    private Integer openState;// 开通状态
    private boolean loginState;// 登录状态
    private boolean circle;// 开通状态
    private List<UserCloudGroup> listGroup;// 群信息
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
    public String getPortrait() {
        return portrait;
    }
    public void setPortrait(String portrait) {
        this.portrait = portrait;
    }
    public String getWxName() {
        return wxName;
    }
    public void setWxName(String wxName) {
        this.wxName = wxName;
    }
    public String getOpenTime() {
        return openTime;
    }
    public void setOpenTime(String openTime) {
        this.openTime = openTime;
    }
    public String getCountdown() {
        return countdown;
    }
    public void setCountdown(String countdown) {
        this.countdown = countdown;
    }
    public Integer getOpenState() {
        return openState;
    }
    public void setOpenState(Integer openState) {
        this.openState = openState;
    }
    public boolean isLoginState() {
        return loginState;
    }
    public void setLoginState(boolean loginState) {
        this.loginState = loginState;
    }
    public boolean isCircle() {
        return circle;
    }
    public void setCircle(boolean circle) {
        this.circle = circle;
    }
    public List<UserCloudGroup> getListGroup() {
        return listGroup;
    }
    public void setListGroup(List<UserCloudGroup> listGroup) {
        this.listGroup = listGroup;
    }
}
fanli/src/main/resource/log4j.properties
@@ -259,6 +259,14 @@
log4j.appender.teamLog.layout=org.apache.log4j.PatternLayout
log4j.appender.teamLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n  
log4j.logger.tljLog=info,cloudLog
log4j.appender.tljLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.tljLog.File=logs/request/cloudLog.log
log4j.appender.tljLog.MaxFileSize=20MB
log4j.appender.tljLog.MaxBackupIndex=100
log4j.appender.tljLog.layout=org.apache.log4j.PatternLayout
log4j.appender.tljLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
log4j.appender.mongodb=org.apache.log4j.ConsoleAppender
log4j.appender.mongodb.Target=System.out
pom.xml
@@ -571,6 +571,20 @@
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>
         <!-- 支付宝相关 -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.9.71.ALL</version>
        </dependency>
        <!--StringUtils-->
        <!-- <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency> -->
    </dependencies>
    <build>