Authored by wujiexiang

新增:兑换券功能

/**
*
*
*/
package com.yoho.activity.common.redis;
... ... @@ -47,7 +47,11 @@ public enum CacheKeyEnum {
QUERY_EBOOK_LINK_BY_UID_EID("yh:activity:ebook:link:by:uid:eid:", 300, "通过UID获取电子刊链接或者校验用户是否兑换阅读码"),
QUERY_READCODE_BY_UID_EID("yh:activity:ebook:by:uid:eid:codeStatus:","page:{}:limit:{}", 300, "通过电子刊ID获取电子刊"),
//口令
COMMON_SHARE_COMMAND("yh:activity:command:key:", 300, "口令");
COMMON_SHARE_COMMAND("yh:activity:command:key:", 300, "口令"),
//券兑换活动
COUPON_EXCHANGE_ACTIVITY("yh:activity:couponExchangeActivity:", 1800, "券兑换活动"),
USER_EXCHANGE_COUPON_LOCK("yh:activity:userExchangeCouponLock:", 5, "防止重复提交");
// 缓存的key
private String cacheKey;
... ... @@ -79,7 +83,7 @@ public enum CacheKeyEnum {
/**
* 获取该枚举的信息
*
*
* @param key
* @return
*/
... ...
package com.yoho.activity.common.redis;
import javax.annotation.Resource;
import com.yoho.core.redis.cluster.annotation.Redis;
import com.yoho.core.redis.cluster.operations.nosync.*;
import org.springframework.stereotype.Service;
... ...
package com.yoho.activity.common.redis;
import com.yoho.core.redis.cluster.lock.SimpleDistributedLockFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by wujiexiang on 20/6/1.
*/
@Configuration
public class LockFactoryConfiguration {
@Autowired
private GracefulRedisTemplate redisTemplate;
@Bean
public SimpleDistributedLockFactory simpleDistributedLockFactory() {
SimpleDistributedLockFactory simpleDistributedLockFactory = new SimpleDistributedLockFactory();
simpleDistributedLockFactory.setRedisTemplate(redisTemplate.getRedisTemplate());
simpleDistributedLockFactory.setValueOperations(redisTemplate.getValueOperations());
return simpleDistributedLockFactory;
}
}
... ...
package com.yoho.activity.common.redis;
import com.google.common.collect.Lists;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Created by wujiexiang on 20/5/29.
*/
@Component
public class RedisValueCacheLoader {
@Autowired
private RedisValueCache redisValueCache;
/**
* @param callBack
* @param cacheKey
* @param keys
* @param clazz
* @param <R>
* @return 返回的map, key为keys参数的值
*/
public <K, R> Map<K, R> load(CacheKeyEnum cacheKey, List<K> keys, Class<R> clazz, OriginCallBack<K, R> callBack) {
//最终结果
Map<K, R> resultMap = new HashMap<>();
if (CollectionUtils.isEmpty(keys)) {
return resultMap;
}
List<RedisKeyBuilder> cacheKeys = keys.stream().map(key -> newRedisKeyBuilder(cacheKey, key)).collect(Collectors.toList());
Map<String /* redis key*/, R> cacheMap = redisValueCache.mget(cacheKeys, clazz);
List<K> missKeys = Lists.newLinkedList();
if (null == cacheMap) {
missKeys.addAll(keys);
} else {
for (K key : keys) {
R r = cacheMap.get(newRedisKeyBuilder(cacheKey, key).getKey());
if (r == null) {
missKeys.add(key);
} else {
resultMap.put(key, r);
}
}
}
//all hit cache
if (CollectionUtils.isEmpty(missKeys)) {
return resultMap;
}
Map<K, R> missMap = callBack.call(missKeys);
if (MapUtils.isNotEmpty(missMap)) {
Map<RedisKeyBuilder, R> toCacheMap = new HashMap<>();
for (Map.Entry<K, R> entry : missMap.entrySet()) {
toCacheMap.put(newRedisKeyBuilder(cacheKey, entry.getKey()), entry.getValue());
}
redisValueCache.mset(toCacheMap, cacheKey.getExpire());
resultMap.putAll(missMap);
}
return resultMap;
}
private <K> RedisKeyBuilder newRedisKeyBuilder(CacheKeyEnum cacheKey, K key) {
return RedisKeyBuilder.newInstance().appendFixed(cacheKey.getCacheKey()).appendVar(key);
}
public interface OriginCallBack<K, R> {
Map<K, R> call(List<K> missKeys);
}
}
... ...
package com.yoho.activity.controller;
import com.yoho.activity.service.impl.CouponExchangeService;
import com.yoho.error.exception.ServiceException;
import com.yoho.service.model.activity.BatchActivityRequest;
import com.yoho.service.model.activity.CouponExchangeActivityVO;
import com.yoho.service.model.activity.CouponExchangeRequest;
import com.yoho.service.model.activity.CouponExchangeResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* Created by wujiexiang on 20/5/29.
*/
@Controller
@RequestMapping("/couponExchangeController")
public class CouponExchangeController {
private static Logger logger = LoggerFactory.getLogger(CouponExchangeController.class);
@Autowired
private CouponExchangeService couponExchangeService;
@RequestMapping("/queryActivityList")
@ResponseBody
public List<CouponExchangeActivityVO> queryCouponExchangeActivityList(@RequestBody BatchActivityRequest request) throws ServiceException {
logger.info("in queryCouponExchangeActivityList,request:{}", request);
return couponExchangeService.queryValidActivityList(request.getUid(), request.getParams());
}
@RequestMapping("/exchangeCoupon")
@ResponseBody
public CouponExchangeResponse exchangeCoupon(@RequestBody CouponExchangeRequest request) throws ServiceException {
logger.info("in exchangeCoupon,request:{}", request);
String couponCode = couponExchangeService.exchange(request.getUid(), request.getToken());
return CouponExchangeResponse.builder().couponCode(couponCode).build();
}
}
... ...
package com.yoho.activity.dal;
import com.yoho.activity.dal.model.CouponExchangeActivity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Created by wujiexiang on 20/5/29.
*/
public interface CouponExchangeActivityMapper {
/**
* 只查询有效的活动
*
* @param tokens
* @return
*/
List<CouponExchangeActivity> selectByTokens(@Param("tokens") List<String> tokens);
}
... ...
package com.yoho.activity.dal;
import com.yoho.activity.dal.model.CouponExchangeDetail;
import org.apache.ibatis.annotations.Param;
/**
* Created by wujiexiang on 20/5/29.
*/
public interface CouponExchangeDetailMapper {
int insert(CouponExchangeDetail detail);
CouponExchangeDetail select(@Param("uid") int uid, @Param("token") String token);
}
... ...
package com.yoho.activity.dal.model;
import lombok.Data;
/**
* Created by wujiexiang on 20/5/29.
*/
@Data
public class CouponExchangeActivity {
private Integer id;
private String token;
private String name;
private String subName;
private String sendCouponId;
private Integer exchangeYohoCoinNum;
}
... ...
package com.yoho.activity.dal.model;
import lombok.Data;
/**
* Created by wujiexiang on 20/5/29.
*/
@Data
public class CouponExchangeDetail {
private Long id;
private Integer uid;
private String token;
private String sendCouponId;
private Integer exchangeYohoCoinNum;
private String couponCode;
private Integer createTime;
}
... ...
<?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.activity.dal.CouponExchangeActivityMapper">
<resultMap id="BaseResultMap" type="com.yoho.activity.dal.model.CouponExchangeActivity">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="token" property="token" jdbcType="VARCHAR" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="sub_name" property="subName" jdbcType="VARCHAR" />
<result column="send_coupon_id" property="sendCouponId" jdbcType="VARCHAR" />
<result column="exchange_yoho_coin_num" property="exchangeYohoCoinNum" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, token, name, sub_name, send_coupon_id, exchange_yoho_coin_num
</sql>
<select id="selectByTokens" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from coupon_exchange_activity
where status = 1
and token IN
<foreach item="item" index="index" collection="tokens" open="(" separator="," close=")">#{item}</foreach>
</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.activity.dal.CouponExchangeDetailMapper">
<resultMap id="BaseResultMap" type="com.yoho.activity.dal.model.CouponExchangeDetail">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="uid" property="uid" jdbcType="INTEGER"/>
<result column="token" property="token" jdbcType="VARCHAR"/>
<result column="send_coupon_id" property="sendCouponId" jdbcType="VARCHAR"/>
<result column="exchange_yoho_coin_num" property="exchangeYohoCoinNum" jdbcType="INTEGER"/>
<result column="coupon_code" property="couponCode" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="INTEGER"/>
</resultMap>
<sql id="Base_Column_List">
id, uid, token, send_coupon_id, exchange_yoho_coin_num, coupon_code, create_time
</sql>
<insert id="insert" parameterType="com.yoho.activity.dal.model.CouponExchangeDetail">
insert into coupon_exchange_detail (id, uid, token, send_coupon_id, exchange_yoho_coin_num, coupon_code, create_time)
values (#{id,jdbcType=BIGINT}, #{uid,jdbcType=INTEGER}, #{token,jdbcType=VARCHAR},
#{sendCouponId,jdbcType=VARCHAR}, #{exchangeYohoCoinNum,jdbcType=INTEGER}, #{couponCode,jdbcType=VARCHAR}, #{createTime,jdbcType=INTEGER}
)
</insert>
<select id="select" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from coupon_exchange_detail
where uid = #{uid,jdbcType=INTEGER}
and token = #{token,jdbcType=VARCHAR}
limit 1
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -4,7 +4,7 @@
<parent>
<groupId>com.yoho</groupId>
<artifactId>parent</artifactId>
<version>1.7.1-SNAPSHOT</version>
<version>1.7.7-SNAPSHOT</version>
</parent>
<groupId>com.yoho.dsf</groupId>
... ... @@ -61,6 +61,11 @@
<artifactId>yohobuy-activity-activity</artifactId>
<version>${project-version}</version>
</dependency>
<dependency>
<groupId>com.yoho.dsf.yhusers</groupId>
<artifactId>yoho-users-client</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
... ...
... ... @@ -17,10 +17,6 @@
<groupId>com.yoho.dsf.yhactivity</groupId>
<artifactId>yohobuy-activity-common</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.dsf.yhactivity</groupId>
<artifactId>yohobuy-activity-common</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.service.model</groupId>
... ... @@ -40,20 +36,16 @@
<artifactId>order-service-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.service.model</groupId>
<artifactId>activity-service-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.service.model</groupId>
<artifactId>activity-service-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.core</groupId>
<artifactId>yoho-core-redis-cluster</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.dsf.yhusers</groupId>
<artifactId>yoho-users-client</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.core</groupId>
<artifactId>yoho-core-redis-cluster</artifactId>
<artifactId>yoho-core-transaction</artifactId>
</dependency>
</dependencies>
... ...
package com.yoho.activity.service.impl;
import com.google.common.collect.Lists;
import com.yoho.activity.common.redis.CacheKeyEnum;
import com.yoho.activity.common.redis.RedisValueCacheLoader;
import com.yoho.activity.common.utils.DateUtils;
import com.yoho.activity.dal.CouponExchangeActivityMapper;
import com.yoho.activity.dal.CouponExchangeDetailMapper;
import com.yoho.activity.dal.model.CouponExchangeActivity;
import com.yoho.activity.dal.model.CouponExchangeDetail;
import com.yoho.activity.service.transaction.CompensableCouponExchangeService;
import com.yoho.core.redis.cluster.lock.SimpleDistributedLock;
import com.yoho.core.redis.cluster.lock.SimpleDistributedLockFactory;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yoho.service.model.activity.CouponExchangeActivityVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Created by wujiexiang on 20/5/29.
*/
@Service
public class CouponExchangeService {
static Logger logger = LoggerFactory.getLogger(CouponExchangeService.class);
@Autowired
private CouponExchangeActivityMapper couponExchangeActivityMapper;
@Autowired
private CouponExchangeDetailMapper couponExchangeDetailMapper;
@Autowired
private RedisValueCacheLoader redisValueCacheLoader;
@Autowired
private CompensableCouponExchangeService compensableCouponExchangeService;
@Autowired
private SimpleDistributedLockFactory simpleDistributedLockFactory;
@Autowired
private YohoCoinService yohoCoinService;
/**
* 查询
*
* @param tokens
* @return
*/
public List<CouponExchangeActivityVO> queryValidActivityList(int uid, List<String> tokens) {
if (CollectionUtils.isEmpty(tokens)) {
return Lists.newArrayList();
}
Map<String, CouponExchangeActivity> cacheMap = loadCouponExchangeActivityMap(tokens);
if (MapUtils.isEmpty(cacheMap)) {
logger.warn("not find any activity by {}", tokens);
return Lists.newArrayList();
}
//查询用户有货币数量
int userYohoCoinNum = yohoCoinService.getUserYohoCoinNum(uid);
return cacheMap.values().stream().map(activity -> {
//有货币数量是否足够
boolean supportExchange = activity.getExchangeYohoCoinNum() >= userYohoCoinNum;
return CouponExchangeActivityVO.builder().name(activity.getName())
.subName(activity.getSubName()).token(activity.getToken()).exchangeYohoCoinNum(activity.getExchangeYohoCoinNum())
.isSupportExchange(supportExchange ? "Y" : "N")
.description(supportExchange ? null : "有货币不足")
.build();
}).collect(Collectors.toList());
}
/**
* 兑换
*
* @param uid
* @param token
* @return
*/
public String exchange(int uid, String token) {
logger.info("[{} - {}] in exchange", uid, token);
CouponExchangeActivity activity = loadCouponExchangeActivity(token);
if (Objects.isNull(activity)) {
logger.warn("not find activity by {}", token);
throw new ServiceException(500, "兑换活动不存在");
}
if (shouldExchangeAgain(uid, token)) {
logger.warn("[{} - {}] can't exchange again", uid, token);
throw new ServiceException(500, "您已兑换过该券");
}
CacheKeyEnum cacheKey = CacheKeyEnum.USER_EXCHANGE_COUPON_LOCK;
SimpleDistributedLock simpleLock = createLock(uid, token, cacheKey);
// 加防并发领取锁
simpleLock.lockOrElseThrow(cacheKey.getExpire(), TimeUnit.SECONDS,
() -> new ServiceException(ServiceError.ACTIVITY_REQUEST_TOO_FREQUENT));
String couponCode;
try {
//补偿兑换
couponCode = compensableCouponExchangeService.exchange(uid, activity);
recordCouponExchangeDetail(uid, couponCode, activity);
} finally {
simpleLock.releaseLock();
}
return couponCode;
}
private Map<String, CouponExchangeActivity> loadCouponExchangeActivityMap(List<String> tokens) {
Map<String, CouponExchangeActivity> cacheMap = redisValueCacheLoader.load(CacheKeyEnum.COUPON_EXCHANGE_ACTIVITY, tokens, CouponExchangeActivity.class, createOriginCallBack());
return cacheMap;
}
private CouponExchangeActivity loadCouponExchangeActivity(String token) {
return loadCouponExchangeActivityMap(Lists.newArrayList(token)).get(token);
}
private RedisValueCacheLoader.OriginCallBack createOriginCallBack() {
return (keys) -> {
//只关注有效的活动
List<CouponExchangeActivity> couponExchangeActivities = couponExchangeActivityMapper.selectByTokens(keys);
return couponExchangeActivities.stream().collect(Collectors.toMap(activity -> activity.getToken(), activity -> activity));
};
}
/**
* 能否再次兑换å
*
* @param uid
* @param token
* @return
*/
private boolean shouldExchangeAgain(int uid, String token) {
return couponExchangeDetailMapper.select(uid, token) != null;
}
/**
* 创建锁ß
*
* @return
*/
private SimpleDistributedLock createLock(int uid, String token, CacheKeyEnum cacheKey) {
RedisKeyBuilder lockKey = RedisKeyBuilder.newInstance().appendFixed(cacheKey.getCacheKey()).appendVarWithMH(uid, token);
SimpleDistributedLock simpleLock = simpleDistributedLockFactory.create(lockKey);
return simpleLock;
}
private void recordCouponExchangeDetail(int uid, String couponCode, CouponExchangeActivity activity) {
//记录兑换明细
try {
CouponExchangeDetail detail = new CouponExchangeDetail();
detail.setUid(uid);
detail.setToken(activity.getToken());
detail.setSendCouponId(activity.getSendCouponId());
detail.setExchangeYohoCoinNum(activity.getExchangeYohoCoinNum());
detail.setCouponCode(couponCode);
detail.setCreateTime(DateUtils.getCurrentTimeSecond());
couponExchangeDetailMapper.insert(detail);
} catch (Exception ex) {
logger.warn("[{} - {}] exception happened when record exchange detail for couponCode:{}", uid, activity.getToken(), couponCode);
}
}
}
... ...
package com.yoho.activity.service.impl;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.service.model.promotion.CouponForm;
import com.yoho.service.model.promotion.CouponsLogBo;
import com.yoho.service.model.promotion.request.CouponsLogReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* Created by wujiexiang on 20/6/1.
*/
@Service
public class CouponService {
private final static Logger logger = LoggerFactory.getLogger(CouponService.class);
@Autowired
private ServiceCaller serviceCaller;
public String sendCoupon(int uid, String token, String couponId) {
logger.info("[{} - {}] start sendCoupon {}", uid, token, couponId);
CouponForm form = new CouponForm();
form.setCouponId(couponId);
form.setUid(String.valueOf(uid));
form.setFlag("1");//多发
form.setRemark(token);
String couponCode = serviceCaller.call("promotion.sendCoupon", form, String.class);
logger.info("[{} - {}] end sendCoupon,couponCode:{}", uid, token, couponCode);
return couponCode;
}
public boolean hasSendCoupon(int uid, String token, String couponId) {
CouponsLogReq request = new CouponsLogReq();
request.setUid(uid);
request.setCouponId(Integer.valueOf(couponId));
request.setRemark(token);
CouponsLogBo[] bos = serviceCaller.call("promotion.queryUserCouponList", request, CouponsLogBo[].class);
if (Objects.isNull(bos) || bos.length == 0) {
return true;
}
if (bos.length > 1) {
logger.warn("[{} - {}] send many coupons,coupons:{}", uid, token, bos);
}
return false;
}
}
... ...
package com.yoho.activity.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.transaction.Compensator;
import com.yoho.core.transaction.annoation.TxCompensatable;
import com.yoho.core.transaction.annoation.TxCompensateArgs;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yoho.service.model.order.constants.BusinessLineType;
import com.yoho.service.model.response.CommonRspBO;
import com.yoho.service.model.response.YohoCoin;
import com.yoho.yhusers.client.YohoCoinHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by wujiexiang on 20/6/1.
*/
@Service
public class YohoCoinService implements Compensator {
private final static Logger logger = LoggerFactory.getLogger(YohoCoinService.class);
@Autowired
private YohoCoinHandler yohoCoinHandler;
@Autowired
private CouponService couponService;
@TxCompensatable(value = YohoCoinService.class)
public void useYohoCoin(@TxCompensateArgs("uid") int uid,
@TxCompensateArgs("token") String token,
@TxCompensateArgs("sendCouponId") String sendCouponId,
@TxCompensateArgs("useYohoCoinNum") int useYohoCoinNum) {
logger.info("[{} - {}] exchange coupon {},will use yoho coin num:{}", uid, token, sendCouponId, useYohoCoinNum);
if (useYohoCoinNum > 0) {
JSONObject params = new JSONObject();
params.put("token", token);
CommonRspBO commonRspBO = yohoCoinHandler.subtractYohoCoin(0, 9, uid, useYohoCoinNum * -1, params.toJSONString(), BusinessLineType.YOHOBUY.getName());
if (commonRspBO != null && commonRspBO.getCode() == 200) {
logger.info("[{} - {}] use yoho coin success", uid, token);
} else {
logger.info("[{} - {}] use yoho coin fail", uid, token);
throw new ServiceException(ServiceError.YOHOCOIN_CALLER_ERROR);
}
}
}
/**
* 有货币补偿方式,由core调用
*
* @param message
*/
@Override
public void compensate(String message) {
logger.info("YohoCoinService begin to compensate,message is {}", message);
JSONObject json = JSON.parseObject(message);
int uid = json.getIntValue("uid");
String token = json.getString("token");
if (shouldCompensate(uid, token, json.getString("sendCouponId"))) {
doCompensate(uid, token, json.getIntValue("useYohoCoinNum"));
} else {
logger.info("[{}-{}] should not compensate", uid, token);
}
logger.info("YohoCoinService compensate end,uid is {}", uid);
}
private boolean shouldCompensate(int uid, String token, String sendCouponId) {
return couponService.hasSendCoupon(uid, token, sendCouponId);
}
private void doCompensate(int uid, String token, int useYohoCoinNum) {
logger.info("[{} - {}] compensate yoho coin,useYohoCoinNum is {}", uid, token, useYohoCoinNum);
if (uid > 0 && useYohoCoinNum > 0) {
CommonRspBO reponse = yohoCoinHandler.refundYohoCoin(0, 2, uid, useYohoCoinNum, BusinessLineType.YOHOBUY.getName());
if (reponse != null) {
logger.info("compensate yoho coin success,compensate response is {}", reponse);
} else {
logger.info("compensate yoho coin fail!!");
}
}
}
/**
* 查询有货币数量
* 有货币的计量单位为分
*
* @param uid
* @return
*/
public int getUserYohoCoinNum(int uid) {
YohoCoin yohoCoin = yohoCoinHandler.getYohoCoinNum(uid);
if ("yuan".equalsIgnoreCase(yohoCoin.getCoinUnit())) {
return yohoCoin.getCoinNum() * 100;
} else if ("jiao".equalsIgnoreCase(yohoCoin.getCoinUnit())) {
return yohoCoin.getCoinNum() * 10;
} else {
return yohoCoin.getCoinNum();
}
}
}
... ...
package com.yoho.activity.service.transaction;
import com.yoho.activity.dal.model.CouponExchangeActivity;
import com.yoho.activity.service.impl.CouponService;
import com.yoho.activity.service.impl.YohoCoinService;
import com.yoho.core.transaction.YHTxCoordinator;
import com.yoho.core.transaction.annoation.YHTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by wujiexiang on 20/5/29.
*/
@Service
public class CompensableCouponExchangeService {
private final static Logger logger = LoggerFactory.getLogger(CompensableCouponExchangeService.class);
@Autowired
private YohoCoinService yohoCoinService;
@Autowired
private CouponService couponService;
@Autowired
YHTxCoordinator tx;
@YHTransaction
public String exchange(int uid, CouponExchangeActivity activity) {
String couponCode;
try {
yohoCoinService.useYohoCoin(uid, activity.getToken(), activity.getSendCouponId(), activity.getExchangeYohoCoinNum());
couponCode = couponService.sendCoupon(uid, activity.getToken(), activity.getSendCouponId());
} catch (Exception ex) {
logger.warn("[{}] exchange coupon fail,activity:{}", uid, activity);
tx.rollback();
throw ex;
}
logger.info("[{}] exchange coupon by token {} success,couponCode is {}", uid, activity.getToken(), couponCode);
return couponCode;
}
}
... ...
... ... @@ -81,6 +81,7 @@
<value>/queryEBookByUserId</value>
<value>/queryLinkByEIdAndUserId</value>
<value>/queryEBookSubscriberInfo</value>
<value>.*/couponExchangeController/.+</value>
</list>
</property>
<property name="excludeMethods">
... ...
... ... @@ -26,10 +26,10 @@ redis.proxy.auth=
execute.timetask.host=192.168.90.9
#zkAddress
zkAddress=192.168.102.45:2181
zkAddress=192.168.102.211:2181
#zkAddress=127.0.0.1:2181
# web context
web.context=activity
web.context=activity2
# ******************** drawline lucky draw task interval(TimeUnit.MINUTES) ********************
drawline.luckydraw.interval=1440
... ... @@ -84,4 +84,10 @@ ufo.fore.domain = http://java-yohoufo-fore.test3.ingress.dev.yohocorp.com/ufo-ga
activity.randomSaleNumLimit = 3888
activity.randomSaleNumHalfLimit = 2000
\ No newline at end of file
activity.randomSaleNumHalfLimit = 2000
#rabbit address for YHTransaction
rabbit_host=192.168.102.211:5672
rabbit_user=yoho
rabbit_password=yoho
\ No newline at end of file
... ...
... ... @@ -174,7 +174,7 @@
</logger>
<!-- root级别 DEBUG -->
<root level="DEBUG">
<root level="INFO">
<!-- 控制台输出 -->
<appender-ref ref="STDOUT" />
<!-- 文件输出 -->
... ...
... ... @@ -66,4 +66,10 @@ ufo.fore.domain = ${ufo.fore.domain}
activity.randomSaleNumLimit = ${activity.randomSaleNumLimit}
activity.randomSaleNumHalfLimit = ${activity.randomSaleNumHalfLimit}
\ No newline at end of file
activity.randomSaleNumHalfLimit = ${activity.randomSaleNumHalfLimit}
#rabbit address for YHTransaction
rabbit_host=${rabbit_common}
rabbit_user=${rabbit_common_user}
rabbit_password=${rabbit_common_password}
\ No newline at end of file
... ...