Authored by 匡佳华

指定uid发券

... ... @@ -8,12 +8,14 @@ import com.yoho.ufo.service.model.ExportParam;
import com.yoho.ufo.util.HttpUtil;
import com.yohobuy.ufo.coupon.req.CouponQueryReq;
import com.yohobuy.ufo.coupon.req.CouponSaveUpdateReq;
import com.yohobuy.ufo.coupon.req.CouponSendReq;
import com.yohobuy.ufo.coupon.req.UserCouponQueryReq;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
... ... @@ -88,4 +90,32 @@ public class CouponController {
return HttpUtil.writeErrorInfo(response, "<p>导出失败</p>");
}
}
@RequestMapping(value = "/couponSend")
public ApiResponse sendCoupon(CouponSendReq req){
LOGGER.info("enter couponSend, param is {}", req);
return couponService.sendCoupon(req);
}
@CrossOrigin(origins = "*")
@RequestMapping(value = "/couponSendByImport", method = RequestMethod.POST)
public ApiResponse sendCouponByImport(@RequestParam("file") MultipartFile file , @RequestParam("couponToken") String couponToken){
LOGGER.info("enter couponSendByImport with file is {}", file);
if (file == null || file.getSize() == 0) {
return new ApiResponse(201, "请选择需要上传的文件!", null);
}
if(StringUtils.isEmpty(couponToken)){
return new ApiResponse(201, "输入参数为空!", null);
}
try {
return couponService.sendCouponByImport(file, couponToken);
} catch (PlatformException px) {
LOGGER.warn("couponSendByImport PlatformException. errorMsg = {}", px.getMessage());
return new ApiResponse(px.getCode(), px.getMessage(), null);
} catch (Exception e) {
LOGGER.error("couponSendByImport error.", e);
return new ApiResponse(201, "系统异常", null);
}
}
}
... ...
... ... @@ -3,7 +3,11 @@ package com.yoho.ufo.coupon.service;
import com.yoho.ufo.service.model.ApiResponse;
import com.yohobuy.ufo.coupon.req.CouponQueryReq;
import com.yohobuy.ufo.coupon.req.CouponSaveUpdateReq;
import com.yohobuy.ufo.coupon.req.CouponSendReq;
import com.yohobuy.ufo.coupon.req.UserCouponQueryReq;
import org.springframework.web.multipart.MultipartFile;
import java.util.Set;
/**
* Created by shengguo.cai on 2018/11/20.
... ... @@ -16,4 +20,8 @@ public interface ICouponService {
ApiResponse getCouponInfo(Integer id);
ApiResponse queryUserCoupons(UserCouponQueryReq req);
ApiResponse sendCoupon(CouponSendReq req);
ApiResponse sendCouponByImport(MultipartFile file, String couponToken) throws Exception;
}
... ...
... ... @@ -5,11 +5,13 @@ import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.yoho.core.common.utils.DateUtil;
import com.yoho.core.rabbitmq.YhProducer;
import com.yoho.error.exception.ServiceException;
import com.yoho.ufo.coupon.service.ICouponService;
import com.yoho.ufo.dal.CouponMapper;
import com.yoho.ufo.dal.CouponProductLimitMapper;
import com.yoho.ufo.dal.UserCouponMapper;
import com.yoho.ufo.dal.model.UidImportTranItem;
import com.yoho.ufo.exception.PlatformException;
import com.yoho.ufo.model.coupon.Coupon;
import com.yoho.ufo.model.coupon.CouponProductLimit;
... ... @@ -17,23 +19,25 @@ import com.yoho.ufo.model.coupon.UserCoupon;
import com.yoho.ufo.model.coupon.resp.CouponQueryResp;
import com.yoho.ufo.model.coupon.resp.UserCouponQueryResp;
import com.yoho.ufo.service.IBusinessExportService;
import com.yoho.ufo.service.impl.BatchService;
import com.yoho.ufo.service.impl.UserHelper;
import com.yoho.ufo.service.model.ApiResponse;
import com.yohobuy.ufo.coupon.req.CouponQueryReq;
import com.yohobuy.ufo.coupon.req.CouponSaveUpdateReq;
import com.yohobuy.ufo.coupon.req.CouponSendReq;
import com.yohobuy.ufo.coupon.req.UserCouponQueryReq;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
/**
... ... @@ -42,15 +46,25 @@ import java.util.stream.Collectors;
@Service("couponServiceImpl")
public class CouponServiceImpl implements ICouponService,IBusinessExportService{
private static final Logger LOGGER = LoggerFactory.getLogger(CouponServiceImpl.class);
@Autowired
private CouponMapper couponMapper;
@Autowired
private CouponProductLimitMapper couponProductLimitMapper;
@Autowired
private UserCouponMapper userCouponMapper;
@Autowired
private HttpServletRequest request;
@Autowired
private BatchService batchService;
@Resource(name = "yhProducer")
private YhProducer yhProducer;
@Override
public Class getDataClass() {
return (Class)request.getAttribute("exportClassType");
... ... @@ -220,6 +234,80 @@ public class CouponServiceImpl implements ICouponService,IBusinessExportService{
return new ApiResponse.ApiResponseBuilder().data(jsonObject).build();
}
@Override
public ApiResponse sendCoupon(CouponSendReq req) {
//(1) 参数非空校验
if(req == null || StringUtils.isEmpty(req.getCouponToken()) || StringUtils.isEmpty(req.getUids())){
LOGGER.info("sendCoupon failed with req is null, req is {}", req);
return new ApiResponse(201, "输入参数为空", null);
}
//(2) uid 校验数量是否超过限制,是否为数字
List<String> uidList = Arrays.asList(req.getUids().split(","));
if(uidList.size() > 50){
LOGGER.info("sendCoupon failed with uid size too large, size is {}", uidList.size());
return new ApiResponse(201, "单次至多输入50个uid", null);
}
Set<Integer> uidSet = new HashSet<>();
for(String uid: uidList){
if(!NumberUtils.isNumber(uid)){
LOGGER.info("sendCoupon failed with uid is not number, uid is {}", uid);
return new ApiResponse(201, "uid必须为数字", null);
}
uidSet.add(Integer.valueOf(uid));
}
//(3) 校验券 并通过mq发券
return sendCouponByMQ(req.getCouponToken(), uidSet);
}
@Override
public ApiResponse sendCouponByImport(MultipartFile file, String couponToken) throws Exception {
//解析excel
List<UidImportTranItem> items = batchService.parseData(file, "batchImportUid", UidImportTranItem.class);
//校验uid 1.是否超过数量限制 2.是否合法
if(items.size() > 50){
LOGGER.info("sendCouponByImport item size too large, size is {}", items.size());
return new ApiResponse(201, "导入uid数量超过50!", null);
}
Set<Integer> uidSet = new HashSet<>();
for(int i = 0 ; i < items.size() ; i ++){
UidImportTranItem item = items.get(i);
Integer uid = item.getUid();
if(uid == null || uid < 1){
return new ApiResponse(201, "excel第"+ ( i + 1 ) + "行数据不合法", null);
}
uidSet.add(uid);
}
return sendCouponByMQ(couponToken, uidSet);
}
private ApiResponse sendCouponByMQ(String couponToken, Set<Integer> uidSet){
// ufo券校验 1.是否有效 2.可用数量是否大于所需发送人数
Coupon coupon = couponMapper.selectValidByToken(couponToken);
if(coupon == null){
LOGGER.info("sendCoupon failed with coupon isn't exist or isn't valid, token is {}", couponToken);
return new ApiResponse(201, "优惠券未在使用中!", null);
}
int availableNum = coupon.getCouponNum() - coupon.getSendNum();
if(uidSet.size() > coupon.getCouponNum()){
LOGGER.info("sendCoupon failed with couponNum isn't enough, uidSize is {}, availableCouponNum is {}", uidSet.size(), availableNum);
return new ApiResponse(201, "uid数量大于当前券可用数量:"+ availableNum + "!" , null);
}
// 发券
for(Integer uid : uidSet){
try {
JSONObject sendCouponParam = new JSONObject();
sendCouponParam.put("uid", uid);
sendCouponParam.put("couponTokens", Collections.singletonList(coupon.getCouponToken()));
sendCouponParam.put("sendType", "1");//sendType 为1时, 若这张券已经领过,则仍然可以领
yhProducer.send("ufo.couponSendWithTradeMqNotify", sendCouponParam, null);
Thread.sleep(5);
}catch (Exception e){
LOGGER.info("sendCoupon by mq fail with uid is {}, token is {}", uid, couponToken);
}
}
return new ApiResponse();
}
private void checkSaveOrUpdateCouponParam(CouponSaveUpdateReq req) {
if(req == null){
LOGGER.info("checkSaveOrUpdateCouponParam failed! req is null");
... ...
... ... @@ -17,6 +17,8 @@ public interface CouponMapper {
Coupon selectById(@Param("id") Integer id);
Coupon selectValidByToken(@Param("token") String token);
void insertOrUpdate(@Param("param") CouponSaveUpdateReq param);
void insertByCouponSaveUpdateReq(@Param("param") CouponSaveUpdateReq param);
... ...
package com.yoho.ufo.dal.model;
import com.yoho.ufo.annotation.BatchImportField;
import lombok.Data;
@Data
public class UidImportTranItem {
@BatchImportField(index = 0)
private Integer uid;
}
... ...
... ... @@ -222,4 +222,8 @@
<select id="selectById" resultType="com.yoho.ufo.model.coupon.Coupon">
select <include refid="Base_Column_List" /> from coupon where id=#{id} limit 1;
</select>
<select id="selectValidByToken" resultType="com.yoho.ufo.model.coupon.Coupon">
select <include refid="Base_Column_List" /> from coupon
where coupon_token =#{token} and status = 1 limit 1;
</select>
</mapper>
\ No newline at end of file
... ...
producer:
- address: 192.168.102.45:5672
producers:
- bean: yhProducer
\ No newline at end of file
... ...
producer:
- address: ${rabbit_ufo}
username: ${rabbit_ufo_user}
password: ${rabbit_ufo_password}
producers:
- bean: yhProducer
\ No newline at end of file
... ...
No preview for this file type