/**
   * 卸载活动
   *
   * @param userId
   * @param activityId
   */
  public void unpublishActivity(Long userId, Long activityId) {
    logger.info("start to unpublish activity, userId[{}] activityId[{}]", userId, activityId);

    PosterRecommendActivity activity =
        posterRecommendActivityDAO.selectByUserIdAndActivityId(userId, activityId);
    if (null == activity) {
      return;
    }
    if (!ALL_PUBLISHED_ACTIVITY_STATUS.contains(activity.getStatus())) {
      logger.info(
          "userId[{}] activity[{}] status[{}] is not one of [{}], skip.",
          userId,
          activity,
          activity.getStatus(),
          ALL_PUBLISHED_ACTIVITY_STATUS);
      return;
    }
    // 开始卸载详情页海报
    PosterRecommendActivity newActivity = new PosterRecommendActivity();
    newActivity.setUserId(userId);
    newActivity.setId(activityId);
    newActivity.setStatus(PosterRecommendConstants.ACTIVITY_STATUS_UNPUBLISHING);
    newActivity.setUnpublishTime(appService.getLocalSystemTime().toDate());
    newActivity.setUnpublishOwner(appService.getOwner());
    posterRecommendActivityDAO.updateByUserIdAndActivityIdSelective(newActivity);

    // 卸载单个宝贝
    List<PosterRecommendPublishItem> publishItems =
        posterRecommendPublishItemDAO.selectByUserIdAndActivityId(userId, activityId);
    List<Exception> exceptions = Lists.newArrayList();
    for (PosterRecommendPublishItem publishItem : publishItems) {
      try {
        unpublishItem(userId, activityId, publishItem.getItemNumIid());
      } catch (TaobaoAccessControlException e) {
        exceptions.add(e);
      } catch (TaobaoEnhancedApiException e) {
        exceptions.add(e);
      } catch (TaobaoSessionExpiredException e) {
        exceptions.add(e);
      }
    }

    // 结束投放活动
    if (CollectionUtils.isEmpty(exceptions)) {
      newActivity.setStatus(ACTIVITY_STATUS_UNPUBLISHED);
    } else {
      newActivity.setStatus(ACTIVITY_STATUS_UNPUBLISHED_WITH_ERROR);
    }
    posterRecommendActivityDAO.updateByUserIdAndActivityIdSelective(newActivity);
  }
  @Transactional
  public void publish2Item(Long userId, Long activityId, Long itemNumIid, String publishHtml)
      throws TaobaoAccessControlException, TaobaoEnhancedApiException,
          TaobaoSessionExpiredException {
    PosterRecommendPublishItem publishItem =
        posterRecommendPublishItemDAO.selectByUserIdAndActivityIdAndItemNumIidAndStatus(
            userId,
            activityId,
            itemNumIid,
            ImmutableList.of(
                PUBLISH_ITEM_STATUS_WAITING_PUBLISH,
                PUBLISH_ITEM_STATUS_PUBLISHED_FAILED,
                PUBLISH_ITEM_STATUS_UNPUBLISHED_SUCCESSFULLY,
                PUBLISH_ITEM_STATUS_UNPUBLISHED_FAILED));
    if (null == publishItem) {
      return;
    }

    // 更新详情页
    Item item = taobaoApiCache.getItem(userId, itemNumIid);
    // 1 备份
    String backupDesc = item.getDesc();
    // important
    String updatedDesc =
        PublishUtils.addHtml2DetailPage(
            publishItem.getDetailPagePosition(),
            HTML_TAG_RECOMMEND,
            activityId,
            publishHtml,
            backupDesc);
    // 插入详情页备份
    PosterRecommendPublishItemDetailPage posterRecommendPublishItemDetailPage =
        new PosterRecommendPublishItemDetailPage();
    posterRecommendPublishItemDetailPage.setUserId(userId);
    posterRecommendPublishItemDetailPage.setActivityId(activityId);
    posterRecommendPublishItemDetailPage.setItemNumIid(item.getNumIid());
    posterRecommendPublishItemDetailPage.setItemTitle(item.getTitle());
    posterRecommendPublishItemDetailPage.setItemPrice(new BigDecimal(item.getPrice()));
    posterRecommendPublishItemDetailPage.setItemPicUrl(item.getPicUrl());
    posterRecommendPublishItemDetailPage.setBackupDesc(backupDesc);
    posterRecommendPublishItemDetailPage.setDesc(updatedDesc);
    posterRecommendPublishItemDetailPage.setAddTime(appService.getLocalSystemTime().toDate());
    try {
      if (updatedDesc.equals(backupDesc)) {
        ItemUpdateRequest request = new ItemUpdateRequest();
        request.setNumIid(itemNumIid);
        request.setDesc(updatedDesc);
        taobaoApiItemService.updateItem(userId, request);
        taobaoApiCache.invalidItem(itemNumIid);
      }
      posterRecommendPublishItemDetailPage.setStatus(DETAIL_PAGE_STATUS_NORMAL);
      publishSuccessful(userId, activityId, itemNumIid);
    } catch (BaseTaobaoApiException e) {
      publishFailed(userId, activityId, itemNumIid);
      posterRecommendPublishItemDetailPage.setStatus(DETAIL_PAGE_STATUS_PUBLISH_FAILED);
      throw e;
    } finally {
      posterRecommendPublishItemDetailPageDAO.insertSelective(posterRecommendPublishItemDetailPage);
    }
  }
 /**
  * 获取淘宝的授权 code,并换取访问 token
  *
  * @return
  */
 @RequestMapping(value = "/callback", method = RequestMethod.GET)
 public String callback(
     @RequestParam(required = false) String code,
     @RequestParam(required = false) String error,
     @RequestParam(required = false) String error_description,
     @RequestParam(required = false) String state)
     throws TaobaoOauthException {
   if (null != code) {
     Subject currentSubject = SecurityUtils.getSubject();
     if (!currentSubject.isAuthenticated()) {
       ShiroTaobaoAuthenticationToken token = new ShiroTaobaoAuthenticationToken();
       token.setClientId(taobaoApiService.getAppKey());
       token.setCode(code);
       token.setState(state);
       token.setAppKey(taobaoApiService.getAppKey());
       token.setRedirectUri(appService.getTaobaoCallbackUrl());
       try {
         currentSubject.login(token);
       } catch (UnknownAccountException uae) {
         throw new AuthenticationException("UnknownAccountException occurred.", uae);
       } catch (IncorrectCredentialsException ice) {
         throw new AuthenticationException("IncorrectCredentialsException occurred.", ice);
       } catch (LockedAccountException lae) {
         throw new AuthenticationException("LockedAccountException occurred.", lae);
       }
     }
     return "redirect:/"; // 返回首页
   } else {
     return "redirect:/400"; // 返回首页
   }
 }
  /**
   * 投放活动到详情页
   *
   * @param userId
   * @param activityId
   */
  public void publishActivity(Long userId, Long activityId) {
    PosterRecommendActivity activity =
        posterRecommendActivityDAO.selectByUserIdAndActivityId(userId, activityId);
    if (null == activity) {
      return;
    }
    // 开始投放活动
    PosterRecommendActivity newActivity = new PosterRecommendActivity();
    newActivity.setUserId(userId);
    newActivity.setId(activityId);
    newActivity.setStatus(PosterRecommendConstants.ACTIVITY_STATUS_PUBLISHING);
    newActivity.setPublishTime(appService.getLocalSystemTime().toDate());
    newActivity.setPublishOwner(appService.getOwner());
    posterRecommendActivityDAO.updateByUserIdAndActivityIdSelective(newActivity);

    // 投放单个宝贝
    List<PosterRecommendPublishItem> publishItems =
        posterRecommendPublishItemDAO.selectByUserIdAndActivityId(userId, activityId);
    List<Exception> exceptions = Lists.newArrayList();
    for (PosterRecommendPublishItem publishItem : publishItems) {
      try {
        publish2Item(userId, activityId, publishItem.getItemNumIid(), activity.getPublishHtml());
      } catch (TaobaoAccessControlException e) {
        exceptions.add(e);
      } catch (TaobaoEnhancedApiException e) {
        exceptions.add(e);
      } catch (TaobaoSessionExpiredException e) {
        exceptions.add(e);
      }
    }

    // 结束投放活动
    if (CollectionUtils.isEmpty(exceptions)) {
      newActivity.setStatus(PosterRecommendConstants.ACTIVITY_STATUS_PUBLISHED);
    } else {
      newActivity.setStatus(PosterRecommendConstants.ACTIVITY_STATUS_PUBLISHED_WITH_ERROR);
    }
    posterRecommendActivityDAO.updateByUserIdAndActivityIdSelective(newActivity);
  }
 /**
  * 移除指定用户的详情页海报信息
  *
  * @param userId
  */
 public void unpublishActivityByUserId(Long userId) {
   List<PosterRecommendActivity> activities =
       posterRecommendActivityDAO.paginateActivityByUserId(
           userId,
           ImmutableList.of(ACTIVITY_STATUS_PUBLISHED, ACTIVITY_STATUS_PUBLISHED_WITH_ERROR),
           appService.getLocalSystemTime().toDate(),
           null,
           1,
           1000);
   for (PosterRecommendActivity activity : activities) {
     unpublishActivity(userId, activity.getId());
   }
 }
 public void afterPublish(Long userId, Long activityId, Long itemNumIid, boolean successful) {
   PosterRecommendPublishItem newPublishItem = new PosterRecommendPublishItem();
   newPublishItem.setUserId(userId);
   newPublishItem.setActivityId(activityId);
   newPublishItem.setItemNumIid(itemNumIid);
   newPublishItem.setPublishTime(appService.getLocalSystemTime().toDate());
   if (successful) {
     newPublishItem.setStatus(PosterRecommendConstants.PUBLISH_ITEM_STATUS_PUBLISHED_SUCCESSFULLY);
   } else {
     newPublishItem.setStatus(PosterRecommendConstants.PUBLISH_ITEM_STATUS_PUBLISHED_FAILED);
   }
   posterRecommendPublishItemDAO.updateByUserIdAndActivityIdAndItemNumIid(newPublishItem);
 }