Authored by DengXinFei

Merge branch 'baidu-tp'

package com.yoho.unions.utils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 七牛云图片上传辅助工具类
* qianjun
*/
public class ImagesHelper {
private static final Logger logger = LoggerFactory.getLogger(ImagesHelper.class);
// 当前域名列表
private static final Map<String, String[]> DOMAIN_LIST;
// 当前bucket列表
private static final Map<String, String> BUCKET_LIST;
static {
DOMAIN_LIST = new HashMap<>();
DOMAIN_LIST.put("01", new String[]{"img10.static.yhbimg.com", "img11.static.yhbimg.com"});
DOMAIN_LIST.put("02", new String[]{"img12.static.yhbimg.com", "img13.static.yhbimg.com"});
DOMAIN_LIST.put("03", new String[]{"flv01.static.yhbimg.com", "flv01.static.yhbimg.com"});
DOMAIN_LIST.put("yhb-head", new String[]{"head.static.yhbimg.com", "head.static.yhbimg.com"});
BUCKET_LIST = new HashMap<>();
BUCKET_LIST.put("goodsimg", "goodsimg");
}
/**
* 场景:前台传的是图片绝对路径,数据库存储需要图片相对路径
* 获取图片相对路径
* @param fileName 图片的绝对地址 http://img01.static.yhbimg.com/goodsimg//2016/03/07/13/01f0024f3dc6f0885f370281a2b41c8bfb.png
* @param bucket bucket, 由ImageConstant中定义
*
*/
public static String getImageRelativeUrl(String fileName, String bucket) {
if(fileName==null){
logger.warn("getImageRelativeUrl fail, fileName is null");
return null;
}
if ( StringUtils.isEmpty(fileName) || !isValidBucket(bucket))
{
logger.warn("getImageRelativeUrl fail, invalid param[file:{}, bucket:{}].", fileName, bucket);
return "";
}
logger.info("getImageRelativeUrl by fileName[{}] bucket[{}].", fileName, bucket);
String subfileName = fileName.substring(fileName.indexOf(bucket));
return subfileName.substring(subfileName.indexOf("/"));
}
/**
* 场景:数据库存储是图片相对路径,前台需要图片绝对路径
* 获取图片绝对路径
* @param fileName 图片的相对地址 /2016/03/07/13/01f0024f3dc6f0885f370281a2b41c8bfb.png
* @param bucket bucket, 由ImageConstant中定义
*
*/
public static String getImageAbsoluteUrl(String fileName, String bucket) {
if ( StringUtils.isEmpty(fileName) || !isValidBucket(bucket))
{
logger.warn("getImageAbsoluteUrl fail, invalid param[file:{}, bucket:{}].", fileName, bucket);
return "";
}
// 兼容旧版本绝对URL地址
if (fileName.trim().toLowerCase().startsWith("http://")) {
// 旧版本url中可能会带参数,直接去掉
if (-1 != fileName.indexOf("?")) {
// 去掉后面的参数后返回
return fileName.substring(0, fileName.indexOf("?"));
}
else {
return fileName;
}
}
logger.info("getImageAbsoluteUrl by fileName[{}] bucket[{}].", fileName, bucket);
String fileMode = fileName.substring(15, 17);
if (DOMAIN_LIST.get(fileMode) == null) {
logger.warn("getImageAbsoluteUrl by fileName[{}] bucket[{}] fail.", fileName, bucket);
return "";
}
//随机从两个域名中获取
String[] domains = DOMAIN_LIST.get(fileMode);
int domainMode = new Random().nextInt(2);
return "http://" + domains[domainMode] + "/" + bucket + fileName;
}
/**
* 检查bucket是否有效
* @param bucket
*/
public static boolean isValidBucket(String bucket) {
return BUCKET_LIST.containsKey(bucket);
}
}
\ No newline at end of file
... ...
... ... @@ -68,6 +68,8 @@
<value>/batch/import</value>
<value>/mktReportForm/getMktReportForm</value>
<value>/UnionRest/queryUnionOrders</value>
<value>/getProdcutDetail</value>
<value>/pushArticle</value>
</list>
</property>
<property name="excludeMethods">
... ...
package com.yoho.unions.dal;
import com.yoho.unions.dal.model.ArticleBlock;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface IArticleBlockDao {
ArticleBlock selectByPrimaryKey(Integer id);
List<ArticleBlock> selectListByArticleId(@Param("articleId") int articleId);
}
... ...
package com.yoho.unions.dal;
import com.yoho.unions.dal.model.Article;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface IArticleDAO {
Article selectByPrimaryKey(Integer id);
}
\ No newline at end of file
... ...
package com.yoho.unions.dal.model;
import org.apache.commons.lang3.StringUtils;
public class Article {
//-1已关闭,0 未发布,1 已发布
public static final Byte ARTICLE_STATUS_CLOSED = -1 ;
public static final Byte ARTICLE_STATUS_NOPUBLISH = 0 ;
public static final Byte ARTICLE_STATUS_PUBLISHED = 1 ;
/**
* 非广告有分享按钮的文章
*/
public static final Byte ARTICLE_TYPE_NO_AD_HAS_SHARE_BUTTON = 1;
private Integer id;
private String articleTitle;
private Integer maxSortId;
private Integer minSortId;
private Integer authorId;
private String coverImage;
private Byte coverImageType;
private String url;
private String pcUrl;
private String adsImgSize;
private Byte articleType;
private String articleSummary;
private String articleGender;
private String brand;
private String tag;
private Integer praise;
private Integer browse;
private Integer appType;
private Integer commentId;
// 晒单的商品详情链接和名称
private String productUrlName;
public String getProductUrlName() {
return productUrlName;
}
public void setProductUrlName(String productUrlName) {
this.productUrlName = productUrlName;
}
public Integer getCommentId() {
return commentId;
}
public void setCommentId(Integer commentId) {
this.commentId = commentId;
}
public Integer getAppType() {
return appType;
}
public void setAppType(Integer appType) {
this.appType = appType;
}
public String getPcUrl() {
return pcUrl;
}
public void setPcUrl(String pcUrl) {
this.pcUrl = pcUrl;
}
//-1已关闭,0 未发布,1 已发布
private Byte status;
private Integer isRecommend;
private Integer createTime;
private Integer publishTime;
private Byte publishState;
private Integer updateTime;
private String isPublish;
private boolean filterUrl;
public Article(){}
public Article(Integer maxSortId, Integer authorId, String articleGender, String tag, String isPublish, Byte status, Byte articleType, boolean filterUrl) {
this.maxSortId = maxSortId;
this.authorId = authorId;
this.articleGender = articleGender;
this.tag = tag;
this.isPublish = isPublish;
this.status = status;
this.articleType = articleType;
this.filterUrl = filterUrl;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getArticleTitle() {
return articleTitle;
}
public void setArticleTitle(String articleTitle) {
this.articleTitle = articleTitle == null ? null : articleTitle.trim();
}
public Integer getMaxSortId() {
return maxSortId;
}
public void setMaxSortId(Integer maxSortId) {
this.maxSortId = maxSortId;
}
public Integer getMinSortId() {
return minSortId;
}
public void setMinSortId(Integer minSortId) {
this.minSortId = minSortId;
}
public Integer getAuthorId() {
return authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
public String getCoverImage() {
if(StringUtils.isNotBlank(coverImage)) {
return coverImage.replace("?imageView/", "?imageView2/");
} else {
return coverImage;
}
// return StringUtils.isBlank(coverImage) ? "" : coverImage.replace("?imageView/", "?imageView2/");
}
public void setCoverImage(String coverImage) {
this.coverImage = coverImage == null ? null : coverImage.trim();
}
public Byte getCoverImageType() {
return coverImageType;
}
public void setCoverImageType(Byte coverImageType) {
this.coverImageType = coverImageType;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url == null ? null : url.trim();
}
public String getAdsImgSize() {
return adsImgSize;
}
public void setAdsImgSize(String adsImgSize) {
this.adsImgSize = adsImgSize == null ? null : adsImgSize.trim();
}
public Byte getArticleType() {
return articleType;
}
public void setArticleType(Byte articleType) {
this.articleType = articleType;
}
public String getArticleSummary() {
return articleSummary;
}
public void setArticleSummary(String articleSummary) {
this.articleSummary = articleSummary == null ? null : articleSummary.trim();
}
public String getArticleGender() {
return articleGender;
}
public void setArticleGender(String articleGender) {
this.articleGender = articleGender == null ? null : articleGender.trim();
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand == null ? null : brand.trim();
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag == null ? null : tag.trim();
}
public Integer getPraise() {
return praise;
}
public void setPraise(Integer praise) {
this.praise = praise;
}
public Integer getBrowse() {
return browse;
}
public void setBrowse(Integer browse) {
this.browse = browse;
}
public Byte getStatus() {
return status;
}
public void setStatus(Byte status) {
this.status = status;
}
public Integer getIsRecommend() {
return isRecommend;
}
public void setIsRecommend(Integer isRecommend) {
this.isRecommend = isRecommend;
}
public Integer getCreateTime() {
return createTime;
}
public void setCreateTime(Integer createTime) {
this.createTime = createTime;
}
public Integer getPublishTime() {
return publishTime;
}
public void setPublishTime(Integer publishTime) {
this.publishTime = publishTime;
}
public Byte getPublishState() {
return publishState;
}
public void setPublishState(Byte publishState) {
this.publishState = publishState;
}
public Integer getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Integer updateTime) {
this.updateTime = updateTime;
}
public String getIsPublish() {
return isPublish;
}
public void setIsPublish(String isPublish) {
this.isPublish = isPublish;
}
public boolean isFilterUrl() {
return filterUrl;
}
public void setFilterUrl(boolean filterUrl) {
this.filterUrl = filterUrl;
}
@Override
public String toString() {
return "Article{" +
"id=" + id +
'}';
}
}
\ No newline at end of file
... ...
package com.yoho.unions.dal.model;
public class ArticleBlock {
private Integer id;
private Integer articleId;
private String templateKey;
private Integer orderBy;
private Integer createTime;
private String contentData;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getArticleId() {
return articleId;
}
public void setArticleId(Integer articleId) {
this.articleId = articleId;
}
public String getTemplateKey() {
return templateKey;
}
public void setTemplateKey(String templateKey) {
this.templateKey = templateKey;
}
public Integer getOrderBy() {
return orderBy;
}
public void setOrderBy(Integer orderBy) {
this.orderBy = orderBy;
}
public Integer getCreateTime() {
return createTime;
}
public void setCreateTime(Integer createTime) {
this.createTime = createTime;
}
public String getContentData() {
return contentData;
}
public void setContentData(String contentData) {
this.contentData = contentData;
}
}
... ...
<?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.yoho.unions.dal.IArticleBlockDao" >
<resultMap id="BaseResultMap" type="com.yoho.unions.dal.model.ArticleBlock" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="article_id" property="articleId" jdbcType="INTEGER" />
<result column="template_key" property="templateKey" jdbcType="VARCHAR" />
<result column="order_by" property="orderBy" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="INTEGER" />
</resultMap>
<resultMap id="ResultMapWithBLOBs" type="com.yoho.unions.dal.model.ArticleBlock" extends="BaseResultMap" >
<result column="content_data" property="contentData" jdbcType="LONGVARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
id, article_id, template_key, order_by, create_time
</sql>
<sql id="Blob_Column_List" >
content_data
</sql>
<select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from article_block
where id = #{id,jdbcType=INTEGER}
and status = 1
</select>
<select id="selectListByArticleId" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from article_block
where article_id = #{articleId,jdbcType=INTEGER}
and status = 1 and template_key in('text','goods','singleImage')
order by order_by ASC, id ASC
</select>
</mapper>
\ No newline at end of file
... ...
<?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.yoho.unions.dal.IArticleDAO">
<resultMap id="BaseResultMap" type="com.yoho.unions.dal.model.Article">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="article_title" property="articleTitle" jdbcType="VARCHAR" />
<result column="max_sort_id" property="maxSortId" jdbcType="INTEGER" />
<result column="min_sort_id" property="minSortId" jdbcType="INTEGER" />
<result column="author_id" property="authorId" jdbcType="INTEGER" />
<result column="cover_image" property="coverImage" jdbcType="VARCHAR" />
<result column="cover_image_type" property="coverImageType" jdbcType="TINYINT" />
<result column="url" property="url" jdbcType="VARCHAR" />
<result column="pc_url" property="pcUrl" jdbcType="VARCHAR" />
<result column="ads_img_size" property="adsImgSize" jdbcType="VARCHAR" />
<result column="article_type" property="articleType" jdbcType="TINYINT" />
<result column="article_summary" property="articleSummary" jdbcType="VARCHAR" />
<result column="article_gender" property="articleGender" jdbcType="CHAR" />
<result column="brand" property="brand" jdbcType="VARCHAR" />
<result column="tag" property="tag" jdbcType="VARCHAR" />
<result column="praise" property="praise" jdbcType="INTEGER" />
<result column="browse" property="browse" jdbcType="INTEGER" />
<result column="status" property="status" jdbcType="TINYINT" />
<result column="is_recommend" property="isRecommend" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="INTEGER" />
<result column="publish_time" property="publishTime" jdbcType="INTEGER" />
<result column="publish_state" property="publishState" jdbcType="TINYINT" />
<result column="update_time" property="updateTime" jdbcType="INTEGER" />
<result column="app_type" property="appType" jdbcType="TINYINT" />
<result column="comment_id" property="commentId" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
id, article_title, max_sort_id, min_sort_id, author_id, cover_image, cover_image_type,
url, ads_img_size, article_type, article_summary, article_gender, brand, tag, praise,
browse, status,
is_recommend, create_time, publish_time, publish_state, update_time, app_type,pc_url,comment_id
</sql>
<sql id="Table_Name">
yh_guang.article
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
select
<include refid="Base_Column_List"/>
from article
where id = #{id,jdbcType=INTEGER}
</select>
</mapper>
\ No newline at end of file
... ...
package com.yoho.unions.server.mqconsumer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.common.utils.MD5;
import com.yoho.unions.dal.IArticleBlockDao;
import com.yoho.unions.dal.IArticleDAO;
import com.yoho.unions.dal.model.Article;
import com.yoho.unions.dal.model.ArticleBlock;
import com.yoho.unions.message.CommonMessageConsumer;
import com.yoho.unions.utils.HttpUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.util.*;
/**
* Created by lenovo on 2017/6/15.
*/
@Component
public class ArticlePushConsumer implements CommonMessageConsumer {
private Logger logger = LoggerFactory.getLogger(ArticlePushConsumer.class);
private final static String ARTICLE_PUSH_TOPIC = "guang.article_push";
private final static String ARTICLE_BASE_URL = "guang.m.yohobuy.com/guang/info/";
//可推送的文章一级分类id
private final static Integer[] PUSH_ARTICLE_SORT_ID = {1,2,3,4,22};
@Value("${baidu.tp.push.url}")
private String baiduTPPushUrl;
@Value("${baidu.app.id}")
private String appId;
@Value("${baidu.app.token}")
private String token;
@Autowired
private IArticleDAO articleDAO;
@Autowired
private IArticleBlockDao articleBlockDao;
@Override
public String getMessageTopic() {
return ARTICLE_PUSH_TOPIC;
}
@Override
public void handleMessage(Object message) {
logger.info("article push message {}", message);
try {
if (null == message) {
return;
}
JSONObject jsonObj = JSON.parseObject((String) message);
Integer articleId = jsonObj.getInteger("articleId");
if(articleId == null || articleId < 1){
return;
}
Article article = articleDAO.selectByPrimaryKey(articleId);
//(1) 检查文章是否满足要求
if(!checkArticle(article)){
return;
}
List<ArticleBlock> articleBlockList = articleBlockDao.selectListByArticleId(articleId);
//(2) 检查文章内容是否满足要求
if(!checkArticleBlock(articleId, articleBlockList)){
return;
}
//(3) 获取文章内容和挂接商品
Pair<StringBuilder,JSONArray> content = getArticleContent(articleBlockList);
//(4) 组装推送参数
Map<String, Object> pushParam = getArticlePushParam(article, content);
//(5) 推送文章到百度TP
String response = HttpUtils.httpPost(baiduTPPushUrl, pushParam).getRight();
JSONObject rspMessage = JSONObject.parseObject(response);
if(0 == rspMessage.getInteger("errno")){
JSONObject data = rspMessage.getJSONObject("data");
logger.info("push article to baidu success, articleId is {}, feed_id is {}", articleId, data.getString("id"));
}else{
logger.warn("push article to baidu failed, articleId is {}, return message is {}", articleId, rspMessage.toJSONString());
}
} catch (Exception e) {
logger.warn("ArticlePushConsumer.handleMessage fail: message is {}, error is {}", message, e);
}
}
private Pair<StringBuilder,JSONArray> getArticleContent(List<ArticleBlock> articleBlockList){
StringBuilder contentBuilder = new StringBuilder("<div class=\"p-text\" style=\"margin: 0px;\">");
JSONArray goodsInfoArr = new JSONArray();
Pair<StringBuilder, JSONArray> res = new ImmutablePair<>(contentBuilder, goodsInfoArr);
if(CollectionUtils.isEmpty(articleBlockList)){
return res;
}
int goodsIndex = 0;
for(ArticleBlock articleBlock : articleBlockList){
String templeteKey = articleBlock.getTemplateKey();
String contentData = articleBlock.getContentData();
JSONObject contentObj = JSONObject.parseObject(contentData);
JSONObject data = contentObj.getJSONObject("data");
if("text".equals(templeteKey)){
String text = data.getString("text");
contentBuilder.append(text);
contentBuilder.append("<br/>");
}else if("singleImage".equals(templeteKey)){
JSONObject imageObj = data.getJSONObject("0");
String imageSrc = imageObj.getString("src");
int index = imageSrc.indexOf("?");
imageSrc = index > 0 ? imageSrc.substring(0, index) : imageSrc;
//百度暂不支持gif图片
if(imageSrc.endsWith(".gif")){
continue;
}
contentBuilder.append("<img src= \"");
contentBuilder.append(imageSrc);
contentBuilder.append("\"/>");
}else if("goods".equals(templeteKey)){
JSONArray dataArray = phpArrayToJSONArray(data);
if(dataArray.size() == 0){
continue;
}
for(int i = 0; i < dataArray.size(); i++){
//图文最多支持5个商品
if(goodsInfoArr.size() > 4){
continue;
}
JSONObject element = dataArray.getJSONObject(i);
if(null == element || null == element.getInteger("id") || "Y".equals(element.getString("is_global"))){
continue;
}
contentBuilder.append("<iframe class=\"spd-faked-goods\" data-pos=\"").append(goodsIndex++).append("\"></iframe>");
JSONObject goodInfo = new JSONObject();
goodInfo.put("sku_id", element.getInteger("id"));
goodInfo.put("tpl_id", "BdrainrwSpdGoodsHasPic");
goodsInfoArr.add(goodInfo);
}
}
}
contentBuilder.append("</div>");
return res;
}
private Map<String, Object> getArticlePushParam(Article article, Pair<StringBuilder,JSONArray> content){
SortedMap<String, Object> paramMap = new TreeMap<>();
JSONArray coverImageArr = new JSONArray();
String articleUrl = ARTICLE_BASE_URL + article.getId() + ".html";
String coverImage = article.getCoverImage();
int index = coverImage.indexOf("?");
coverImage = index > 0 ? coverImage.substring(0, index) : coverImage;
coverImageArr.add(coverImage);
paramMap.put("app_id", appId);
paramMap.put("tp_src", "yoho");
paramMap.put("v", "1.0");
paramMap.put("domain", "12");
paramMap.put("origin_url", articleUrl);
paramMap.put("title", article.getArticleTitle());
paramMap.put("abstract", article.getArticleSummary());
paramMap.put("content", content.getLeft().toString());
paramMap.put("cover_layout", "one");
paramMap.put("cover_images", coverImageArr);
paramMap.put("publish_time", article.getPublishTime() == null ? "0": String.valueOf(article.getPublishTime()));
paramMap.put("publish_type", "immediate");
paramMap.put("source_type", "creation");
paramMap.put("service_type", content.getRight().size() > 0 ? 1 : 0);
paramMap.put("goods_info", content.getRight());
List<String> array = new LinkedList<>();
for(Map.Entry<String, Object> entry : paramMap.entrySet()){
if(entry.getValue() == null){
continue;
}
array.add(String.valueOf(entry.getValue()));
}
String signStr = String.join("", array);
String sign = MD5.md5(signStr + token);
paramMap.put("sign", sign);
return paramMap;
}
/**
* 检查文章是否满足推送要求
* @param article
* @return Boolean
*/
private Boolean checkArticle(Article article){
//(1) 文章标题, 摘要不能为空
if(article == null || StringUtils.isEmpty(article.getArticleTitle()) || StringUtils.isEmpty(article.getArticleSummary())){
return false;
}
int maxSortId = article.getMaxSortId();
String title = article.getArticleTitle();
String coverImage = article.getCoverImage();
int index = coverImage.indexOf("?");
coverImage = index > 0 ? coverImage.substring(0, index) : coverImage;
List<Integer> sortIdList = Arrays.asList(PUSH_ARTICLE_SORT_ID);
//(2) 只推送指定文章分类
if(!sortIdList.contains(maxSortId)){
logger.info("checkArticle: article sort id {} not support", maxSortId);
return false;
}
//(3) 封面图是gif格式的不支持
if(coverImage.endsWith(".gif")){
return false;
}
//(4) 文章标题必须大于16个字节,小于80个字节
try {
int len = title.getBytes("GBK").length;
if(len < 16 || len > 80){
logger.info("checkArticle: article title not support, article id {}, title is {}", article.getId(), title);
return false;
}
} catch (UnsupportedEncodingException e) {
logger.warn("checkArticle: get title bytes failed: article id is {}, error is {}", article.getId(), e);
}
return true;
}
/**
* 检查文章内容是否满足推送要求
* @param articleBlockList
* @return Boolean
*/
private Boolean checkArticleBlock(Integer articleId, List<ArticleBlock> articleBlockList){
if(CollectionUtils.isEmpty(articleBlockList)){
return false;
}
List<String> templeteKeyList = new ArrayList<>();
int contentLen = 0;
for(ArticleBlock articleBlock : articleBlockList){
if(articleBlock == null || articleBlock.getTemplateKey() == null){
continue;
}
String templeteKey = articleBlock.getTemplateKey();
if("text".equals(templeteKey)){
try {
String contentData = articleBlock.getContentData();
JSONObject contentObj = JSONObject.parseObject(contentData);
JSONObject data = contentObj.getJSONObject("data");
String text = data.getString("text");
contentLen += text.getBytes("GBK").length;
} catch (UnsupportedEncodingException e) {
logger.warn("checkArticleBlock: get text bytes failed: articleBlock id is {}, error is {}", articleBlock.getId(), e);
}
}else if("singleImage".equals(templeteKey)){
//一张图片算100字节
contentLen += 100;
}
templeteKeyList.add(articleBlock.getTemplateKey());
}
//推送文章必须包含文字
if(!templeteKeyList.contains("text")){
return false;
}
//文章内容必须大于400个字节,小于40000个字节
if(contentLen < 400 || contentLen > 40000){
logger.info("checkArticleBlock: article block not support, articleId is {}", articleId);
return false;
}
return true;
}
/**
* php数组转成json数组
* @param dataObject
* @return JSONArray
*/
private JSONArray phpArrayToJSONArray(JSONObject dataObject) {
JSONArray dataToArray = new JSONArray();
if (dataObject == null || dataObject.isEmpty()) {
return new JSONArray();
}
for (int i = 0; i < dataObject.size(); i++) {
JSONObject object = dataObject.getJSONObject("" + i);
dataToArray.add(object);
}
return dataToArray;
}
}
... ...
package com.yoho.unions.server.restapi;
import com.alibaba.fastjson.JSONObject;
import com.yoho.service.model.union.response.UnionResponse;
import com.yoho.unions.common.utils.SpringContextUtil;
import com.yoho.unions.message.CommonMessageConsumer;
import com.yoho.unions.server.mqconsumer.OrderPushConsumer;
import com.yoho.unions.server.mqconsumer.ArticlePushConsumer;
import com.yoho.unions.server.service.IOrderPushService;
import com.yoho.unions.server.service.IRedirectService;
import com.yoho.unions.server.service.IUnionOrderService;
import com.yoho.unions.server.task.BigDataOrderInfoTask;
import com.yoho.unions.vo.*;
import org.slf4j.Logger;
... ... @@ -13,6 +14,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
... ... @@ -33,7 +35,10 @@ public class OrderUnionRest {
private BigDataOrderInfoTask bigDataOrderInfoTask;
@Autowired
CommonMessageConsumer commonMessageConsumer;
private IUnionOrderService unionOrderService;
@Autowired
private ArticlePushConsumer articlePushConsumer;
/**
* 订单联盟跳转接口
... ... @@ -117,5 +122,16 @@ public class OrderUnionRest {
return new UnionResponse();
}
/**
* 提供给百度查询商品详情接口
*/
@RequestMapping("/getProdcutDetail")
@ResponseBody
public JSONObject getProductDetail(@RequestParam("sku_id")String productSkn,
@RequestParam(value = "from", required =false)String from){
logger.info("Enter getProdcutDetail: productSkn is {}, from is {}", productSkn, from);
return unionOrderService.getProdcutDetail(productSkn, from);
}
}
... ...
package com.yoho.unions.server.service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.service.model.union.request.UnionLogsReqBO;
import com.yoho.service.model.union.request.UnionOrderReqBO;
import com.yoho.service.model.union.response.PageUnionClickLogsRspBO;
... ... @@ -18,4 +19,6 @@ public interface IUnionOrderService {
// PageUnionOrderRspBO queryUnionOrders(UnionOrderReqBO reqBO);
JSONObject getProdcutDetail(String productSkn, String from);
}
... ...
package com.yoho.unions.server.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.service.model.union.UnionTrans;
import com.yoho.service.model.union.request.UnionLogsReqBO;
import com.yoho.service.model.union.request.UnionOrderReqBO;
import com.yoho.service.model.union.response.PageUnionActivityLogsRspBO;
import com.yoho.service.model.union.response.PageUnionOrderRspBO;
import com.yoho.service.model.union.response.UnionActivityLogsRspBO;
import com.yoho.service.model.union.response.UnionOrderRspBO;
import com.yoho.unions.common.enums.NewUserEnum;
import com.yoho.unions.common.enums.OrderStatusEnum;
import com.yoho.unions.common.enums.PaymentTypeEnum;
import com.yoho.unions.common.redis.RedisHashCache;
import com.yoho.unions.common.redis.RedisListCache;
import com.yoho.unions.common.service.IBusinessExportService;
import com.yoho.unions.common.utils.DateUtil;
import com.yoho.unions.dal.IMktMarketingUrlDAO;
import com.yoho.unions.dal.IOrdersMapper;
import com.yoho.unions.dal.IUserOrdersDAO;
import com.yoho.unions.dal.OrdersCouponsMapper;
import com.yoho.unions.dal.model.*;
import com.yoho.unions.dal.model.UnionActivityTrans;
import com.yoho.unions.dal.model.UnionOrders;
import com.yoho.unions.dal.model.UnionOrdersGoods;
import com.yoho.unions.server.service.IUnionOrderService;
import com.yoho.unions.utils.ImagesHelper;
import com.yoho.unions.vo.OrderInfo;
import com.yoho.unions.vo.OrdersGood;
import com.yoho.unions.vo.TransInfo;
... ... @@ -29,7 +23,9 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.util.ArrayList;
... ... @@ -50,6 +46,18 @@ public class UnionOrderServiceImpl implements IUnionOrderService{
private static final String UNION_NORMAL_TRANS_UNIONTYPE = "YH:BD:UNI:ALL:ORDER:";
private static final String PRODUCT_BASE_URL = "http://m.yohobuy.com/product/";
// 搜索服务器的ip端口
@Value("${ip.port.search.server}")
private String searchServerIpAndPort;
@Value("${baidu.union.type}")
private String unionType;
@Autowired
private RestTemplate restTemplate;
@Autowired
private RedisListCache redisListCache;
... ... @@ -304,5 +312,55 @@ public class UnionOrderServiceImpl implements IUnionOrderService{
// return pageUnionOrderRspBO;
// }
@Override
public JSONObject getProdcutDetail(String productSkn, String from) {
String searchUrl = getSearchProductUrl(productSkn);
JSONObject resObj = new JSONObject();
try {
logger.info("getProdcutDetail. searchUrl is:{}", searchUrl);
String json=restTemplate.getForObject(searchUrl, String.class);
JSONObject jsonObject = JSONObject.parseObject(json);
JSONObject product = new JSONObject();
if (jsonObject.getInteger("code") == 200){
JSONObject data = jsonObject.getJSONObject("data");
JSONArray array = data.getJSONArray("product_list");
if(array != null && array.size() > 0){
JSONObject element = array.getJSONObject(0);
product.put("sku_id", element.getString("product_skn"));
product.put("tp_src", "yoho");
product.put("from", "");
product.put("source", "有货");
product.put("is_on_sale", element.getInteger("status"));
product.put("name", element.getString("product_name"));
product.put("desc", element.getString("phrase"));
product.put("img", ImagesHelper.getImageAbsoluteUrl(element.getString("default_images"), "goodsimg"));
product.put("price", element.getInteger("sales_price") == null ? 0 : element.getInteger("sales_price") * 100);
product.put("mprice", element.getInteger("market_price") == null ? 0 : element.getInteger("market_price") * 100);
product.put("promotion_url", getProductUrl(element.getString("product_skn")));
}
resObj.put("errno", 0);
resObj.put("errmsg", "success");
}else{
resObj.put("errno", 1);
resObj.put("errmsg", "service not available");
}
resObj.put("data", product);
} catch (Exception e) {
resObj.put("errno", 1);
resObj.put("errmsg", "service not available");
resObj.put("data", new JSONArray());
logger.warn("getProdcutDetail fail, searchUrl is {}" , searchUrl);
}
return resObj;
}
private String getSearchProductUrl(String productSkn) {
return "http://" + searchServerIpAndPort + "/yohosearch/productindex/productListWithPhrase.json?product_skn=" + productSkn;
}
private String getProductUrl(String productSkn){
return PRODUCT_BASE_URL + productSkn + ".html" + "?nodownload=1&nogoback=1&union_type=" + unionType;
}
}
... ...
... ... @@ -38,11 +38,11 @@ redis.proxy.database=1
########## common rabbitmq ##########
#aws
rabbit_common_aws=192.168.102.45:5672
rabbit_common_aws=192.168.102.22:5672
rabbit_common_aws_user=yoho
rabbit_common_aws_password=yoho
#qq
rabbit_common_qq=192.168.102.45:5672
rabbit_common_qq=192.168.102.22:5672
rabbit_common_qq_user=yoho
rabbit_common_qq_password=yoho
##########common rabbitmq ##########
... ... @@ -50,7 +50,8 @@ rabbit_common_qq_password=yoho
#-------------七牛云配置-------------------#
qiniu.accesskey=atSf7xxIl8alEnsXbhC1bOD1GWVW3qYffz8SlB4m
qiniu.secretkey=pyoJzPygXIkFWrc1BAsH6tAJ0yweTchpJwGKEwhm
qiniu.domain = test
qiniu.bucket = test
zkAddress=127.0.0.1:2181
# web context
... ... @@ -117,4 +118,13 @@ business.mobile=13621380911,15210647200
unions.kafka.consumer.servers=127.0.0.1:9092
unions.kafka.producer.servers=127.0.0.1:9092
\ No newline at end of file
unions.kafka.producer.servers=127.0.0.1:9092
#search config
ip.port.search.server = 192.168.102.216:8080/
#baidu tp config
baidu.tp.push.url=http://hoteltest.baidu.com/business/article_publish
baidu.app.id=1566454424306679
baidu.app.token=spdtkn_test12
baidu.union.type=100000000005493
\ No newline at end of file
... ...
... ... @@ -89,4 +89,14 @@ datasources:
- com.yoho.unions.dal.IOrdersMapper
- com.yoho.unions.dal.OrdersCouponsMapper
yh_guang:
servers:
- 192.168.102.219:3306
- 192.168.102.219:3306
username: yh_test
password: 9nm0icOwt6bMHjMusIfMLw==
daos:
- com.yoho.unions.dal.IArticleDAO
- com.yoho.unions.dal.IArticleBlockDao
readOnlyInSlave: true
\ No newline at end of file
... ...
... ... @@ -116,6 +116,16 @@ union.host=${union.host}
#
#unions.kafka.producer.servers=${unions.kafka.producer.servers}
#search config
ip.port.search.server=${ip.port.search.server}
#baidu tp config
baidu.tp.push.url=${baidu.tp.push.url}
baidu.app.id=${baidu.app.id}
baidu.app.token=${baidu.app.token}
baidu.union.type=${baidu.union.type}
qiniu.accesskey = ${qiniu.accesskey}
qiniu.secretkey = ${qiniu.secretkey}
qiniu.domain = ${qiniu.domain}
... ...
... ... @@ -97,4 +97,15 @@ datasources:
- com.yoho.unions.dal.IOrdersMapper
- com.yoho.unions.dal.OrdersCouponsMapper
yh_guang:
servers:
- ${jdbc.mysql.yhguang.master}
- ${jdbc.mysql.yhguang.slave}
username: ${jdbc.mysql.yhguang.username}
password: ${jdbc.mysql.yhguang.password}
maxConnections: 80
daos:
- com.yoho.unions.dal.IArticleDAO
- com.yoho.unions.dal.IArticleBlockDao
readOnlyInSlave: true
\ No newline at end of file
... ...