Authored by caoyan

Merge branch 'dev_物权转移' into test6.8.6

# Conflicts:
#	web/src/main/resources/databases.yml
#	web/src/main/webapp/META-INF/autoconf/databases.yml
package com.yohoufo.dal.order;
import org.apache.ibatis.annotations.Param;
import com.yohoufo.dal.order.model.OrderOperateRecord;
/**
... ... @@ -8,4 +10,6 @@ import com.yohoufo.dal.order.model.OrderOperateRecord;
public interface OrderOperateRecordMapper {
int insert(OrderOperateRecord orderOperateRecord);
OrderOperateRecord selectByTypeAndOrderCode(@Param("type") Integer type, @Param("orderCode") Long orderCode);
}
... ...
package com.yohoufo.dal.product;
import com.yohoufo.dal.product.model.Brand;
import com.yohoufo.dal.product.model.IdentifyRecord;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import com.yohoufo.dal.product.model.IdentifyRecord;
public interface IdentifyRecordsMapper {
IdentifyRecord selectByTagAndNfcId(@Param("tagId") String tagId, @Param("nfcUid") String nfcUid);
int updateOwner(@Param("tagId") String tagId, @Param("nfcUid") String nfcUid, @Param("owner") Integer owner);
}
\ No newline at end of file
... ...
package com.yohoufo.dal.product;
import org.apache.ibatis.annotations.Param;
import com.yohoufo.dal.product.model.TransferRecordsHistory;
/**
*/
public interface TransferRecordsHistoryMapper {
int insert(TransferRecordsHistory transferRecordsHistory);
TransferRecordsHistory selectByToUid(@Param("tagId") String tagId, @Param("nfcUid") String nfcUid, @Param("toUid") Integer toUid);
int updateStatus(@Param("tagId") String tagId, @Param("nfcUid") String nfcUid, @Param("status") Integer status);
}
... ...
package com.yohoufo.dal.product;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.yohoufo.dal.product.model.TransferRecords;
/**
*/
public interface TransferRecordsMapper {
List<TransferRecords> selectByTagIdAndNfcUid(@Param("tagId") String tagId, @Param("nfcUid") String nfcUid);
int insert(TransferRecords transferRecords);
}
... ...
package com.yohoufo.dal.product.model;
import com.alibaba.fastjson.JSONObject;
public class TransferRecords {
private Integer id;
private String tagId;
private String nfcUid;
private Integer createTime;
private String fromUid;
private String toUid;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTagId() {
return tagId;
}
public void setTagId(String tagId) {
this.tagId = tagId;
}
public String getNfcUid() {
return nfcUid;
}
public void setNfcUid(String nfcUid) {
this.nfcUid = nfcUid;
}
public Integer getCreateTime() {
return createTime;
}
public void setCreateTime(Integer createTime) {
this.createTime = createTime;
}
public String getFromUid() {
return fromUid;
}
public void setFromUid(String fromUid) {
this.fromUid = fromUid;
}
public String getToUid() {
return toUid;
}
public void setToUid(String toUid) {
this.toUid = toUid;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
\ No newline at end of file
... ...
package com.yohoufo.dal.product.model;
import com.alibaba.fastjson.JSONObject;
public class TransferRecordsHistory {
private Integer id;
private String tagId;
private String nfcUid;
private Integer operateTime;
private String fromUid;
private String toUid;
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTagId() {
return tagId;
}
public void setTagId(String tagId) {
this.tagId = tagId;
}
public String getNfcUid() {
return nfcUid;
}
public void setNfcUid(String nfcUid) {
this.nfcUid = nfcUid;
}
public String getFromUid() {
return fromUid;
}
public void setFromUid(String fromUid) {
this.fromUid = fromUid;
}
public String getToUid() {
return toUid;
}
public void setToUid(String toUid) {
this.toUid = toUid;
}
public Integer getOperateTime() {
return operateTime;
}
public void setOperateTime(Integer operateTime) {
this.operateTime = operateTime;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
\ No newline at end of file
... ...
... ... @@ -20,4 +20,11 @@
values (#{orderCode}, #{uid}, #{type}, #{userName}, #{oldInfo}, #{updateTime})
</insert>
<select id="selectByTypeAndOrderCode" resultMap="BaseResultMap">
select <include refid="Base_Column_List"></include>
from order_operate_record
where type=#{type} and order_code=#{orderCode}
limit 1
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -23,4 +23,12 @@
</if>
limit 1
</select>
<update id="updateOwner">
update identify_records set owner=#{owner}
where tag_id = #{tagId,jdbcType=VARCHAR}
<if test="nfcUid != null" >
and nfc_uid = #{nfcUid,jdbcType=VARCHAR}
</if>
</update>
</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.yohoufo.dal.product.TransferRecordsHistoryMapper">
<resultMap id="BaseResultMap" type="com.yohoufo.dal.product.model.TransferRecordsHistory">
<result column="id" property="id" jdbcType="INTEGER" />
<result column="tag_id" property="tagId" jdbcType="VARCHAR" />
<result column="nfc_uid" property="nfcUid" jdbcType="VARCHAR" />
<result column="from_uid" property="fromUid" jdbcType="VARCHAR" />
<result column="to_uid" property="toUid" jdbcType="VARCHAR" />
<result column="operate_time" property="operateTime" jdbcType="INTEGER" />
<result column="status" property="status" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
id,tag_id,nfc_uid,from_uid,to_uid,operate_time, status
</sql>
<insert id="insert" parameterType="com.yohoufo.dal.product.model.TransferRecordsHistory">
insert into transfer_records_history (tag_id, nfc_uid, from_uid, to_uid, operate_time, status)
values (#{tagId}, #{nfcUid}, #{fromUid}, #{toUid}, #{operateTime}, #{status})
</insert>
<select id="selectByToUid" resultMap="BaseResultMap">
select <include refid="Base_Column_List"></include>
from transfer_records_history
where tag_id=#{tagId}
<if test="nfcUid != null and nfcUid != '' ">
and nfc_uid=#{nfcUid}
</if>
<if test="toUid != null and toUid != 0">
and to_uid=#{toUid}
</if>
order by operate_time desc
limit 1
</select>
<update id="updateStatus">
update transfer_records_history set status=#{status}
where tag_id=#{tagId}
<if test="nfcUid != null and nfcUid != '' ">
and nfc_uid=#{nfcUid}
</if>
</update>
</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.yohoufo.dal.product.TransferRecordsMapper">
<resultMap id="BaseResultMap" type="com.yohoufo.dal.product.model.TransferRecords">
<result column="id" property="id" jdbcType="INTEGER" />
<result column="tag_id" property="tagId" jdbcType="VARCHAR" />
<result column="nfc_uid" property="nfcUid" jdbcType="VARCHAR" />
<result column="from_uid" property="fromUid" jdbcType="VARCHAR" />
<result column="to_uid" property="toUid" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
id,tag_id,nfc_uid,from_uid,to_uid,create_time
</sql>
<select id="selectByTagIdAndNfcUid" resultMap="BaseResultMap">
select <include refid="Base_Column_List"></include>
from transfer_records
where tag_id=#{tagId}
<if test="nfcUid != null" >
and nfc_uid = #{nfcUid,jdbcType=VARCHAR}
</if>
order by create_time asc
</select>
<update id="updateOwner">
update transfer_records set from_uid=#{fromUid}, to_uid=#{toUid}
</update>
<insert id="insert" parameterType="com.yohoufo.dal.product.model.TransferRecords">
insert into
transfer_records(tag_id,nfc_uid,from_uid,to_uid,create_time)
values
(#{tagId,jdbcType=VARCHAR },#{nfcUid,jdbcType=VARCHAR },#{fromUid,jdbcType=VARCHAR},#{toUid,jdbcType=VARCHAR },#{createTime,jdbcType=INTEGER })
</insert>
</mapper>
\ No newline at end of file
... ...
... ... @@ -38,5 +38,9 @@
<groupId>com.yoho.ufo.model</groupId>
<artifactId>product-ufo-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.core</groupId>
<artifactId>yoho-core-rabbitmq</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.yohoufo.product.controller;
import com.alibaba.fastjson.JSONObject;
import com.yoho.error.GatewayError;
import com.yoho.error.exception.ServiceException;
import com.yoho.tools.docs.ApiOperation;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.annotation.IgnoreSession;
import com.yohoufo.common.annotation.IgnoreSignature;
import com.yohoufo.common.cache.Cachable;
import com.yohoufo.common.caller.UfoServiceCaller;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.product.helper.SearchHelpService;
import com.yohoufo.product.request.ProductSearchReq;
import com.yohoufo.product.request.SortIdLevel;
import com.yohoufo.product.response.*;
import com.yohoufo.product.service.ProductIdentifyService;
import com.yohoufo.product.service.ProductSearchService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -23,8 +7,15 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import com.yoho.tools.docs.ApiOperation;
import com.yoho.tools.docs.ApiParam;
import com.yoho.tools.docs.ApiResp;
import com.yoho.tools.docs.ApiRespCode;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.annotation.IgnoreSignature;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.product.response.ProductIdentifyResp;
import com.yohoufo.product.service.ProductIdentifyService;
@RestController
public class ProductIdentifyController {
... ... @@ -70,4 +61,80 @@ public class ProductIdentifyController {
// return new ApiResponse.ApiResponseBuilder().code(401).message("操作失败,请稍后重试").build();
// }
// }
@ApiOperation(name = "ufo.product.queryNewIdentifyInfo", desc="UFO商品物权转移查询接口")
@ApiParam(name="tagId",required = true,desc="NFC标签id",type=Integer.class)
@ApiParam(name="nfcUid",required = false,desc="NFC芯片id",type=Integer.class)
@ApiParam(name="uid",required = true,desc="有货uid",type=Integer.class)
@ApiResp(dataClazz=ProductIdentifyResp.class, desc="UFO商品物权转移信息")
@ApiRespCode(code=200,desc="查询成功")
@ApiRespCode(code=402,desc="查询失败")
@IgnoreSignature
@RequestMapping(params = "method=ufo.product.queryNewIdentifyInfo")
public ApiResponse queryNewIdentifyInfo(@RequestParam(value = "tagId", required = true) String tagId,
@RequestParam(value = "nfcUid",required = false) String nfcUid,
@RequestParam(value = "uid", required = true) Integer uid) throws GatewayException {
try{
ProductIdentifyResp info = identifyService.queryNewIdentifyInfo(tagId, nfcUid, uid);
return new ApiResponse.ApiResponseBuilder().code(200).data(info).build();
}catch (Exception e){
logger.warn("queryNewIdentifyInfo error! tagId={}, nfcUid={}, uid={}, e is {}", tagId, nfcUid, uid, e);
if( e instanceof GatewayException){
throw e;
}
return new ApiResponse.ApiResponseBuilder().code(402).message("查询失败,请稍后重试").build();
}
}
@ApiOperation(name = "ufo.product.applyToBeOwner", desc="申请成为物权所有人")
@ApiParam(name="tagId",required = true,desc="NFC标签id",type=Integer.class)
@ApiParam(name="nfcUid",required = false,desc="NFC芯片id",type=Integer.class)
@ApiParam(name="uid",required = true,desc="有货uid",type=Integer.class)
@ApiResp(dataClazz=ProductIdentifyResp.class, desc="申请成为物权所有人")
@ApiRespCode(code=200,desc="操作成功")
@ApiRespCode(code=402,desc="操作失败")
@IgnoreSignature
@RequestMapping(params = "method=ufo.product.applyToBeOwner")
public ApiResponse applyToBeOwner(@RequestParam(value = "tagId", required = true) String tagId,
@RequestParam(value = "nfcUid",required = false) String nfcUid,
@RequestParam(value = "uid", required = true) Integer uid) throws GatewayException {
try{
int result = identifyService.applyToBeOwner(tagId, nfcUid, uid);
return new ApiResponse.ApiResponseBuilder().code(200).data(result).build();
}catch (Exception e){
logger.warn("applyToBeOwner error! tagId={}, nfcUid={}, uid={}, e is {}", tagId, nfcUid, uid, e);
if( e instanceof GatewayException){
throw e;
}
return new ApiResponse.ApiResponseBuilder().code(402).message("申请失败,请稍后重试").build();
}
}
@ApiOperation(name = "ufo.product.updateOwnerApply", desc="确认物权转移")
@ApiParam(name="tagId",required = true,desc="NFC标签id",type=Integer.class)
@ApiParam(name="nfcUid",required = false,desc="NFC芯片id",type=Integer.class)
@ApiParam(name="from_uid",required = true,desc="当前物权所有人",type=Integer.class)
@ApiParam(name="to_uid",required = true,desc="物权申请人",type=Integer.class)
@ApiParam(name="status",required = true,desc="确认结果1:同意,2:拒绝",type=Integer.class)
@ApiResp(dataClazz=ProductIdentifyResp.class, desc="申请成为物权所有人")
@ApiRespCode(code=200,desc="操作成功")
@ApiRespCode(code=402,desc="操作失败")
@IgnoreSignature
@RequestMapping(params = "method=ufo.product.confirmTransferOwner")
public ApiResponse confirmTransferOwner(@RequestParam(value = "tagId", required = true) String tagId,
@RequestParam(value = "nfcUid",required = false) String nfcUid,
@RequestParam(value = "from_uid", required = true) Integer fromUid,
@RequestParam(value = "to_uid", required = true) Integer toUid,
@RequestParam(value = "status", required = true) Integer status) throws GatewayException {
try{
int result = identifyService.confirmOwner(tagId, nfcUid, fromUid, toUid, status);
return new ApiResponse.ApiResponseBuilder().code(200).data(result).build();
}catch (Exception e){
logger.warn("confirmTransferOwner error! tagId={}, nfcUid={}, fromUid={}, toUid is{}, e is {}", tagId, nfcUid, fromUid, toUid, e);
if(e instanceof GatewayException){
throw e;
}
return new ApiResponse.ApiResponseBuilder().code(402).message("操作失败,请稍后重试").build();
}
}
}
\ No newline at end of file
... ...
package com.yohoufo.product.mq;
public interface TopicConstants {
/**
* 物权转移确认超时
*/
String MQ_TOPIC_CONFIRM_OWNER_DELAY = "productOwner.updateTimeOut";
}
... ...
package com.yohoufo.product.mq.consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.yoho.core.rabbitmq.YhConsumer;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.product.TransferRecordsHistoryMapper;
import com.yohoufo.dal.product.model.TransferRecordsHistory;
import com.yohoufo.product.mq.TopicConstants;
/**
* 物权确认超时
* Created by caoyan.
*/
@Component
public class ProductOwnerConfirmDelayMsgConsumer implements YhConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger("mqConsumerLog");
@Autowired
private TransferRecordsHistoryMapper transferRecordsHistoryMapper;
public static final Integer OPERATE_TYPE_APPLYING = 0;//申请中
public static final Integer OPERATE_TYPE_TIMEOUT = 3;//确认超时
public String getMessageTopic() {
return TopicConstants.MQ_TOPIC_CONFIRM_OWNER_DELAY;
}
@Override
public void handleMessage(Object message) {
LOGGER.info("begin handle productOwnerConfirmTimeout update message, message is {}.", message);
TransferRecordsHistory obj = JSON.parseObject(String.valueOf(message),TransferRecordsHistory.class);
TransferRecordsHistory dbItem = transferRecordsHistoryMapper.selectByToUid(obj.getTagId(), obj.getNfcUid(), Integer.valueOf(obj.getToUid()));
if(null != dbItem && dbItem.getStatus().equals(OPERATE_TYPE_APPLYING)) {
//将记录插入历史表transfer_recors_history
TransferRecordsHistory insertItem = new TransferRecordsHistory();
insertItem.setTagId(obj.getTagId());
insertItem.setNfcUid(obj.getNfcUid());
insertItem.setFromUid(obj.getFromUid());
insertItem.setToUid(obj.getToUid());
insertItem.setOperateTime(DateUtil.getCurrentTimeSecond());
insertItem.setStatus(OPERATE_TYPE_TIMEOUT);
transferRecordsHistoryMapper.insert(insertItem);
LOGGER.info("handle productOwnerConfirmTimeout update message success, message is {}.", message);
return;
}
LOGGER.info("not need to handle productOwnerConfirmTimeout update message, message is {}.", message);
}
}
... ...
... ... @@ -16,5 +16,8 @@ public class ProductIdentifyResp {
private String identifyPlat;
private List<IdentifyTrackResp> trackList;
private String transactionId;//区块链Id
private boolean ifOwner;//当前登录的是否是物权所有人
private String identifyUserName;//鉴定师名字
private Integer applyStatus;//申请物权转移状态
private String currentOwner;//当前物权所有人
}
... ...
... ... @@ -6,12 +6,16 @@ import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.product.response.IdentifyShareInfoResp;
import com.yohoufo.product.response.ProductIdentifyResp;
import java.util.List;
public interface ProductIdentifyService {
ProductIdentifyResp queryIdentifyInfo(String tagId, String nfcUid) throws GatewayException;
IdentifyShareInfoResp getShareIdentifyInfo( String tagId, String nfcUid) throws GatewayException;
ProductIdentifyResp queryNewIdentifyInfo(String tagId, String nfcUid, Integer uid) throws GatewayException;
int applyToBeOwner(String tagId, String nfcUid, Integer uid) throws GatewayException;
int confirmOwner(String tagId, String nfcUid, Integer fromUid, Integer toUid, Integer status) throws GatewayException;
}
... ...
package com.yohoufo.product.service.impl;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.collect.Lists;
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 com.alibaba.fastjson.JSONObject;
import com.qiniu.util.Json;
import com.google.common.collect.Maps;
import com.yoho.core.config.ConfigReader;
import com.yoho.core.rabbitmq.YhProducer;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.core.rest.client.hystrix.AsyncFuture;
... ... @@ -11,37 +33,40 @@ import com.yoho.service.model.social.request.UicUserReqBO;
import com.yoho.service.model.social.response.UserInfoRspBO;
import com.yoho.service.model.uic.UicResponse;
import com.yoho.service.model.uic.request.UserInfoBO;
import com.yohobuy.ufo.model.order.common.OperateTypeEnum;
import com.yohobuy.ufo.model.order.constants.QNliveConstants;
import com.yohoufo.common.cache.CacheClient;
import com.yohoufo.common.exception.GatewayException;
import com.yohoufo.common.helper.ImageUrlAssist;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.common.utils.MobileHelper;
import com.yohoufo.dal.order.*;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.OrderOperateRecordMapper;
import com.yohoufo.dal.order.OrdersPayMapper;
import com.yohoufo.dal.order.QiniuLiveRecordMapper;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderGoods;
import com.yohoufo.dal.order.model.OrderOperateRecord;
import com.yohoufo.dal.order.model.OrdersPay;
import com.yohoufo.dal.order.model.QiniuLiveRecord;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.dal.order.model.OrdersPay;
import com.yohoufo.dal.product.IdentifyRecordsMapper;
import com.yohoufo.dal.product.IdentifyRelationMapper;
import com.yohoufo.dal.product.ProductChainMapper;
import com.yohoufo.dal.product.TransferRecordsHistoryMapper;
import com.yohoufo.dal.product.TransferRecordsMapper;
import com.yohoufo.dal.product.model.IdentifyRecord;
import com.yohoufo.dal.product.model.IdentifyRelation;
import com.yohoufo.dal.product.model.ProductChain;
import com.yohoufo.dal.product.model.TransferRecords;
import com.yohoufo.dal.product.model.TransferRecordsHistory;
import com.yohoufo.product.mq.TopicConstants;
import com.yohoufo.product.response.IdentifyShareInfoResp;
import com.yohoufo.product.response.IdentifyTrackResp;
import com.yohoufo.product.response.ProductIdentifyResp;
import com.yohoufo.product.service.ProductIdentifyService;
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 java.text.SimpleDateFormat;
import java.util.*;
@Service
... ... @@ -81,12 +106,34 @@ public class ProductIdentifyServiceImpl implements ProductIdentifyService{
@Autowired
private ConfigReader configReader;
@Autowired
private TransferRecordsMapper transferRecordsMapper;
@Autowired
private OrderOperateRecordMapper orderOperateRecordMapper;
@Autowired
private TransferRecordsHistoryMapper transferRecordsHistoryMapper;
@Resource(name = "yhProducer")
private YhProducer yhProducer;
@Value("${uic.url:http://uic.yohoops.org/uic}")
private String uicUrl;
public static final String DEFAULT_HEAD_IMG = "http://img11.static.yhbimg.com/yhb-img01/2016/07/05/13/017ec560b82c132ab2fdb22f7cf6f42b83.png?imageView/{mode}/w/{width}/h/{height}";
public static final Integer OPERATE_TYPE_APPLYING = 0;//申请中
public static final Integer OPERATE_TYPE_PASS = 1;//同意
public static final Integer OPERATE_TYPE_REJECT = 2;//拒绝
public static final Integer OPERATE_TYPE_TIMEOUT = 3;//确认超时
public static final Integer OPERATE_TYPE_NO_APPLY = 4; //未申请
/**
* 鉴定结果查询接口
* @param tagId
... ... @@ -219,6 +266,288 @@ public class ProductIdentifyServiceImpl implements ProductIdentifyService{
logger.info("queryIdentifyInfo success!, tagId = {}, nfcUid={}, result ={}", tagId, nfcUid, result );
return result;
}
private boolean queryIsOwner(String tagId, String nfcUid, Integer uid) {
IdentifyRecord record = identifyRecordsMapper.selectByTagAndNfcId(tagId, nfcUid);
if(null != record && record.getOwner() == uid.intValue()) {
return true;
}
return false;
}
@Override
public ProductIdentifyResp queryNewIdentifyInfo(String tagId, String nfcUid, Integer uid) throws GatewayException {
logger.info("enter queryNewIdentifyInfo, tagId = {}, nfcUid={}, uid={}", tagId, nfcUid, uid);
//返回结果可能在缓存中
ProductIdentifyResp result = getIdentifyFromCache(tagId, nfcUid);
if(result != null ){
rebuildResult(result, tagId, nfcUid, uid);
logger.info("queryNewIdentifyInfo get result from cache success! tagId = {}, nfcUid={},uid={}, result={} ", tagId, nfcUid, uid, result );
return result;
}
//1)鉴定 记录--先从缓存去取
IdentifyRecord identifyRecord = queryIdentifyRecord(tagId, nfcUid);
if(identifyRecord == null){
throw new GatewayException(402, "鉴定信息不存在");
}
//根据鉴定记录 获取订单号
Long orderCode = identifyRecord.getOrderCode();
//2)订单号 获取订单详细信息
BuyerOrder buyerOrder = buyerOrderMapper.selectOnlyByOrderCode(orderCode);
if(buyerOrder == null){
throw new GatewayException(403, "订单不存在");
}
//3)商品详细信息
result = getOrderDetail(buyerOrder, identifyRecord, tagId);
//4)物权转移轨迹
List<IdentifyTrackResp> trackList = getTrackList(identifyRecord, result.getIdentifyPlat());
result.setTrackList(trackList);
//5)设置当前物权所有人
result.setCurrentOwner(trackList.get(trackList.size()-1).getContent());
//设置缓存--可能会有延时,不影响的
setIdentifyCache(tagId, nfcUid, result);
//添加申请物权转移人信息
rebuildResult(result, tagId, nfcUid, uid);
logger.info("queryIdentifyInfo success!, tagId = {}, nfcUid={}, result ={}", tagId, nfcUid, result );
return result;
}
@Override
public int applyToBeOwner(String tagId, String nfcUid, Integer uid) throws GatewayException {
IdentifyRecord identifyRecord = queryIdentifyRecord(tagId, nfcUid);
if(identifyRecord == null){
throw new GatewayException(402, "鉴定信息不存在");
}
if(identifyRecord.getOwner() == uid.intValue()) {
throw new GatewayException(402, "已经是物权所有人");
}
TransferRecordsHistory history = transferRecordsHistoryMapper.selectByToUid(tagId, nfcUid, uid);
if(null != history && (history.getStatus().equals(OPERATE_TYPE_APPLYING)
|| history.getStatus().equals(OPERATE_TYPE_PASS) || history.getStatus().equals(OPERATE_TYPE_REJECT))) {
throw new GatewayException(402, "当前不可再申请");
}
//将申请记录插入数据库
TransferRecordsHistory insertItem = new TransferRecordsHistory();
insertItem.setTagId(tagId);
insertItem.setNfcUid(nfcUid);
insertItem.setFromUid(String.valueOf(identifyRecord.getOwner()));
insertItem.setToUid(String.valueOf(uid));
insertItem.setOperateTime(DateUtil.getCurrentTimeSecond());
insertItem.setStatus(OPERATE_TYPE_APPLYING);
int result = transferRecordsHistoryMapper.insert(insertItem);
//向物权所有人发送站内信
//发送定时mq
yhProducer.send(TopicConstants.MQ_TOPIC_CONFIRM_OWNER_DELAY, insertItem, null, 3*24*60);//3天
return result;
}
@Override
public int confirmOwner(String tagId, String nfcUid, Integer fromUid, Integer toUid, Integer status) throws GatewayException {
if(null == status || !(status.equals(OPERATE_TYPE_PASS) || status.equals(OPERATE_TYPE_REJECT))){
throw new GatewayException(402, "参数status错误");
}
IdentifyRecord identifyRecord = queryIdentifyRecord(tagId, nfcUid);
if(identifyRecord == null){
throw new GatewayException(402, "鉴定信息不存在");
}
if(identifyRecord.getOwner() != fromUid.intValue()) {
throw new GatewayException(402, "不是当前物权所有人,无法操作");
}
TransferRecordsHistory history = transferRecordsHistoryMapper.selectByToUid(tagId, nfcUid, toUid);
if(null == history || !history.getStatus().equals(OPERATE_TYPE_APPLYING)) {
throw new GatewayException(402, "不是申请中状态");
}
//将记录插入历史表transfer_recors_history
TransferRecordsHistory histroy = new TransferRecordsHistory();
histroy.setTagId(tagId);
histroy.setNfcUid(nfcUid);
histroy.setFromUid(String.valueOf(identifyRecord.getOwner()));
histroy.setToUid(String.valueOf(toUid));
histroy.setOperateTime(DateUtil.getCurrentTimeSecond());
histroy.setStatus(status);
int result = transferRecordsHistoryMapper.insert(histroy);
if(status.equals(OPERATE_TYPE_REJECT)) {
return result;
}
//增加记录到transfer_records
TransferRecords transferRecords = new TransferRecords();
transferRecords.setTagId(tagId);
transferRecords.setNfcUid(nfcUid);
transferRecords.setFromUid(histroy.getFromUid());
transferRecords.setToUid(history.getToUid());
transferRecords.setCreateTime(DateUtil.getCurrentTimeSecond());
transferRecordsMapper.insert(transferRecords);
//更新identify_record
return identifyRecordsMapper.updateOwner(tagId, nfcUid, toUid);
}
private void rebuildResult(ProductIdentifyResp result, String tagId, String nfcUid, Integer uid) {
boolean isOwner = queryIsOwner(tagId, nfcUid, uid);
result.setIfOwner(isOwner);
if(isOwner) {
return;
}
//申请人申请状态
TransferRecordsHistory history = transferRecordsHistoryMapper.selectByToUid(tagId, nfcUid, uid);
if(null == history) {
result.setApplyStatus(OPERATE_TYPE_NO_APPLY);//未申请
}else {
result.setApplyStatus(history.getStatus());
}
ProfileInfoRsp[] profileInfoArray = getUserProfilesByUids(Lists.newArrayList(String.valueOf(uid)));
if(ArrayUtils.isEmpty(profileInfoArray)) {
return;
}
ProfileInfoRsp profileInfo = profileInfoArray[0];
IdentifyTrackResp track = new IdentifyTrackResp();
track.setUid(uid);
String mobileMask = MobileHelper.coverMobile2(profileInfo.getMobile());//隐位的手机号码--隐藏中间6位
track.setContent(StringUtils.isEmpty(profileInfo.getNickname()) ? mobileMask : profileInfo.getNickname());
String headIcon = profileInfo.getHead_ico();
if(DEFAULT_HEAD_IMG.equals(headIcon) || StringUtils.isBlank(headIcon)){//有货的默认头像
//ufo 用户的默认头像
headIcon = configReader.getString("ufo.product.defaultUserHeadIcon", "http://head.static.yhbimg.com/yhb-head/2018/12/28/14/0160773bb87685aade796ea4f94e0587cf.png?imageView2/{mode}/w/{width}/h/{height}");
}
track.setHeadIcon(headIcon);
result.getTrackList().add(track);
}
//交易轨迹
private List<IdentifyTrackResp> getTrackList(IdentifyRecord identifyRecord, String authGroup) {
List<IdentifyTrackResp> trackRespList = new ArrayList<>();
//1)第一部分:一条记录,商品鉴定结果
IdentifyTrackResp identifyTrack = new IdentifyTrackResp();
int authTime = identifyRecord.getAuthTime();
identifyTrack.setTime(authTime);
identifyTrack.setTimeStr(formatDate(authTime, "yyyy.MM.dd HH:mm:ss"));
identifyTrack.setContent(authGroup + "鉴定结果为\"真\"");
//鉴定中心,默认的展示头像
String authIco = configReader.getString("ufo.product.defaultAuthHeadIcon", "http://head.static.yhbimg.com/yhb-head/2018/12/28/14/01384244a3ca86fa5345df87c59317b81f.png?imageView2/{mode}/w/{width}/h/{height}");
identifyTrack.setHeadIcon(authIco);
trackRespList.add(identifyTrack);
//2)第二部分:历史物权所有人,按时间顺序排列
List<TransferRecords> transferList = transferRecordsMapper.selectByTagIdAndNfcUid(identifyRecord.getTagId(), identifyRecord.getNfcUid());
List<String> ownerUidList = transferList.stream().map(TransferRecords::getToUid).collect(Collectors.toList());
List<String> allUidList = Lists.newArrayList();
allUidList.addAll(ownerUidList);
//查询头像和手机号
Map<Integer, ProfileInfoRsp> profileMap = queryIcoAndMobile(allUidList);
List<IdentifyTrackResp> historyTrackList = buildTransferTrackList(profileMap, transferList);
trackRespList.addAll(historyTrackList);
return trackRespList;
}
private List<IdentifyTrackResp> buildTransferTrackList(Map<Integer, ProfileInfoRsp> profileMap, List<TransferRecords> transferList) {
List<IdentifyTrackResp> trackList = Lists.newArrayList();
Map<String, TransferRecords> transferMap = transferList.stream().collect(Collectors.toMap(TransferRecords::getToUid, t->t));
for(Entry<Integer, ProfileInfoRsp> entry : profileMap.entrySet()) {
IdentifyTrackResp item = new IdentifyTrackResp();
item.setUid(entry.getKey());
String mobileMask = MobileHelper.coverMobile2(entry.getValue().getMobile());//隐位的手机号码--隐藏中间6位
item.setContent(StringUtils.isEmpty(entry.getValue().getNickname()) ? mobileMask : entry.getValue().getNickname());
String headIcon = entry.getValue().getHead_ico();
if(DEFAULT_HEAD_IMG.equals(headIcon) || StringUtils.isBlank(headIcon)){//有货的默认头像
//ufo 用户的默认头像
headIcon = configReader.getString("ufo.product.defaultUserHeadIcon", "http://head.static.yhbimg.com/yhb-head/2018/12/28/14/0160773bb87685aade796ea4f94e0587cf.png?imageView2/{mode}/w/{width}/h/{height}");
}
item.setHeadIcon(headIcon);
if(null != transferMap.get(String.valueOf(entry.getKey()))) {
Integer createTime = transferMap.get(String.valueOf(entry.getKey())).getCreateTime();
item.setTime(createTime);
item.setTimeStr(formatDate(createTime, "yyyy.MM.dd HH:mm:ss"));
}
trackList.add(item);
}
Collections.sort(trackList, new Comparator<IdentifyTrackResp>(){//时间顺序排列
@Override
public int compare(IdentifyTrackResp o1, IdentifyTrackResp o2) {
Integer time1 = o1.getTime();
Integer time2 = o2.getTime();
return time1 -time2;
}
});
return trackList;
}
private Map<Integer,ProfileInfoRsp> queryIcoAndMobile(List<String> uidList) {
Map<Integer,ProfileInfoRsp> profileMap = Maps.newHashMap();
ProfileInfoRsp[] profileInfoArray = getUserProfilesByUids(uidList);
if(ArrayUtils.isEmpty(profileInfoArray)) {
return profileMap;
}
for(int i=0; i< profileInfoArray.length; i++) {
ProfileInfoRsp item = profileInfoArray[i];
profileMap.put(item.getUid(), item);
}
return profileMap;
}
//获取订单详情
private ProductIdentifyResp getOrderDetail(BuyerOrder buyerOrder, IdentifyRecord identifyRecord, String tagId) {
ProductIdentifyResp result = new ProductIdentifyResp();
//3)订单号获取 skup
BuyerOrderGoods buyerOrderGoods = buyerOrderGoodsMapper.selectOnlyByOrderCode(buyerOrder.getOrderCode());
Integer skup = buyerOrderGoods.getSkup();
//3)skup获取 productInfo
SellerOrderGoods sellerOrderGoods = sellerOrderGoodsMapper.selectByPrimaryKey(skup);
result.setProductImageUrl(ImageUrlAssist.getAllProductPicUrl(sellerOrderGoods.getImageUrl(), "goodsimg", "center", "d2hpdGU="));
result.setNfcUid(identifyRecord.getNfcUid());
result.setProductId(sellerOrderGoods.getProductId());
result.setProductName(sellerOrderGoods.getProductName());
result.setProductSize(sellerOrderGoods.getSizeName());
//4)vedioFileUrl视频链接
String vedioFileUrl = getLiveVideoUrlByOrderCode(buyerOrder.getOrderCode());
result.setVedioFileUrl(vedioFileUrl);
//查询区块链id
ProductChain productChain = queryTransactionIdByTagId(tagId);
result.setTransactionId(productChain == null ? null : productChain.getTransactionId());
//组装查询结果
//鉴定者的信息、鉴定中心等
IdentifyRelation authGroupInfo = queryAuthGroupInfo(identifyRecord.getAuthUid());
String authGroup = authGroupInfo == null ? "UFO鉴定中心" : authGroupInfo.getGroupName();
result.setIdentifyPlat(authGroup);
// result.setIdentifyTime(timeStr);
//查询鉴定师名字
OrderOperateRecord orderOperateRecord = orderOperateRecordMapper.selectByTypeAndOrderCode(OperateTypeEnum.OPERATE_TYPE_JUDGE_PASS.getCode(), buyerOrder.getOrderCode());
result.setIdentifyUserName(null == orderOperateRecord ? "" : orderOperateRecord.getUserName());
return result;
}
/**
* 查询区块链Id
... ... @@ -332,6 +661,22 @@ public class ProductIdentifyServiceImpl implements ProductIdentifyService{
ProductIdentifyResp identifyResp = clientCache.get(kb, ProductIdentifyResp.class);
return identifyResp;
}
/**
* 批量查询用户基本信息--头像信息+手机号
* @return
*/
private ProfileInfoRsp[] getUserProfilesByUids(List<String> uidList) {
try{
String uids = String.join(",", uidList);
String url = uicUrl + "/profile/getUserProfilesByUids";
logger.info("getUserProfilesByUids start call uic.getUserProfilesByUids uidList={}, url={} ", uidList, url);
return serviceCaller.post("uic.getUserProfilesByUids", url, uids, ProfileInfoRsp[].class,null).get();
}catch(Exception e){
logger.warn("getUserProfilesByUids call uic.getUserProfilesByUids error! uidList={}, e {}", uidList, e);
return null;
}
}
/**
* 查询用户基本信息--头像信息(不要取此接口的手机号)
... ... @@ -348,7 +693,6 @@ public class ProductIdentifyServiceImpl implements ProductIdentifyService{
logger.warn("getUserBaseInfo call uic.getUserInfoByYohoUid error! uid={}, e {}", uid, e);
return null;
}
}
/**
... ... @@ -367,7 +711,6 @@ public class ProductIdentifyServiceImpl implements ProductIdentifyService{
logger.warn("getUserProfileInfo call uic.getProfileActionPost error! uid={}, e {}", uid, e);
return null;
}
}
private String formatDate(Integer time, String pattern) {
... ...
... ... @@ -36,6 +36,9 @@ datasources:
- com.yohoufo.dal.product.PriceTrendHalfYearMapper
- com.yohoufo.dal.product.PriceTrendDayMapper
- com.yohoufo.dal.product.ProductImportTranItemMapper
- com.yohoufo.dal.product.TransferRecordsMapper
- com.yohoufo.dal.product.TransferRecordsHistoryMapper
ufo_order:
servers:
... ...
... ... @@ -63,6 +63,16 @@ consumer:
- class: com.yohoufo.order.mq.consumer.ExpressInfoUpdateConsumer
topic: ufo.order.updateExpressInfo
- address: 192.168.102.45:5672
username: yoho
password: yoho
consumers:
#物权转移确认超时
- class: com.yohoufo.product.mq.consumer.ProductOwnerConfirmDelayMsgConsumer
topic: productOwner.updateTimeOut
delay:
interval: 4320
# crm
- address: 192.168.102.211:5672
consumers:
... ...
... ... @@ -36,6 +36,8 @@ datasources:
- com.yohoufo.dal.product.PriceTrendHalfYearMapper
- com.yohoufo.dal.product.PriceTrendDayMapper
- com.yohoufo.dal.product.ProductImportTranItemMapper
- com.yohoufo.dal.product.TransferRecordsMapper
- com.yohoufo.dal.product.TransferRecordsHistoryMapper
ufo_order:
servers:
... ...
... ... @@ -79,6 +79,16 @@ consumer:
#更新物流调拨信息
- class: com.yohoufo.order.mq.consumer.ExpressInfoUpdateConsumer
topic: ufo.order.updateExpressInfo
- address: ${rabbit_ufo}
username: ${rabbit_ufo_user}
password: ${rabbit_ufo_password}
consumers:
#物权转移确认超时
- class: com.yohoufo.product.mq.consumer.ProductOwnerConfirmDelayMsgConsumer
topic: productOwner.updateTimeOut
delay:
interval: 4320
# crm
... ...