签到功能实现

1. 需求分析

签到可以获得积分,礼券,小样,正品等

连续签到,需要显示给用户,已经连续签到多少天

若中断签到,从中断后的第一天签到时间,开始计算签到时间

有没有补签功能

展示签到的历史,显示该会员已经连续签到多少天

签到对于时间的精确度要求比较高,当天签到的,那么记录的签到时间是当天,如果还有后续的一系列操作,比如计算积分,那后续操作的时间必须和签到的时间一致

对于凌晨,跨天之类的场景,特别需要注意

2.表结构设计

会员表,积分表,是以前就有的,本次新增签到功能,需要新增一下的表:

首先要有记录用户签到,暂且定义为HSignIn

 

3. 后台代码实现

Controller

@RestController
@RequestMapping(value = "signIn")
public class SignController extends BaseController {

    @Autowired
    SignInService signInService;

    @Autowired
    SocialProviderService socialProviderService;

    @ApiOperation(value = "签到历史记录查询", notes = "签到历史记录查询")
    @GetMapping(value = "history", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    private ResponseBean signHis(@RequestParam("userId") String userId,
                                      @RequestParam("social") String social) {

        ResponseBean responseBean = new ResponseBean();
        SignInHisResponse signInHisResponse = signInService.getSignInRecord(userId, social);
        responseBean.setData(signInHisResponse);
        return responseBean;
    }
    
    
    @ApiOperation(value = "天猫签到", notes = "天猫签到")
    @GetMapping(value = "signInTmallByJasmine", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    private ResponseBean signInTmallByJasmine(@RequestParam("userId") String userId,
                                              @RequestParam("time") Long time,
                                     @RequestParam("social") String social) {
        ResponseBean responseBean = new ResponseBean();
        SignInHisResponse signInHisResponse = signInService.tmallSignInWithTime(userId, social,time);
        responseBean.setData(signInHisResponse);
        return responseBean;
    }
    
}

具体实现:

连续签到,今日是否已经签到 ===方法判断

private static int getContinuousSignInDay(
			List<HTmallSignInRecord> signInList) {
		// continuousDay 连续签到数
		int continuousDay = 1;
		boolean todaySignIn = false;
		Date today = new Date();
		for (int i = 0; i < signInList.size(); i++) {
			HTmallSignInRecord signIn = signInList.get(i);
			int intervalDay = distanceDay(today, signIn.getSignDT());
			// 当天签到
			if (intervalDay == 0 && i == 0) {
				todaySignIn = true;
			} else if (intervalDay == continuousDay) {
				continuousDay++;
			} else {
				// 不连续,终止判断
				break;
			}
		}
		if (!todaySignIn) {
			continuousDay--;
		}
		return continuousDay;
	}

	/**
	 * 两个日期对比间隔天数
	 *
	 * @param smallDay
	 * @return boolean
	 * @Param largeDay
	 **/
	private static int distanceDay(Date largeDay, Date smallDay) {
		int day = (int) ((largeDay.getTime() - smallDay.getTime()) / (1000 * 60 * 60 * 24));
		return day;
	}

  

签到相关的接口

public interface SignInService {

	SignInHisResponse getSignInRecord(String userId, String social);

	SignInHisResponse tmallSignIn(String userId, String social);

	SignInHisResponse tmallSignInWithTime(String userId, String social,Long time);
	
}

 

和具体的实现

@Service
public class SignInServiceImpl implements SignInService {

	@Autowired
	HTmallSignMapper hTmallSignMapper;

	@Autowired
	SocialService socialService;

	@Autowired
	SocialProviderService socialProviderService;

	@Autowired
	BCustomerService bCustomerService;

	@Autowired
	PEService peService;

	@Autowired
	CustomerService customerService;

	@Autowired
	SendMemberInfoToEcrmMqTask sendMemberInfoToEcrmMqTask;

	@Value("${sys.name}")
	private String sysName;

	@Value("${pe.event.signIn.tmall}")
	String tmallSignInPeEventCode;

	@Override
	public SignInHisResponse getSignInRecord(String userId, String social) {
		int cstId = socialService.findCstIdBySocialAndSocialId(userId, social);
		SignInHisResponse signInHisResponse = new SignInHisResponse();
		List<HTmallSignInRecord> tlist = hTmallSignMapper.getTmallSignRecords(cstId);
		signInHisResponse.setAlreadySignInTodayFlag((hTmallSignMapper.getSignInToday(cstId) > 0) ? true : false);
		if (null != tlist && tlist.size() > 0) {
			signInHisResponse.setTmallSignInRecords(tlist);
			signInHisResponse
					.setContinuousSignInDay(getContinuousSignInDay(tlist));
		}
		return signInHisResponse;
	}

	

	@Override
	public SignInHisResponse tmallSignInWithTime(String userId, String social, Long time) {
		Date date = new Date(time);
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String tt =sd.format(date);
		int cstId = socialService.findCstIdBySocialAndSocialId(userId, social);
		SignInHisResponse signInHisResponse = new SignInHisResponse();
		// 今天是否已签到
		if (hTmallSignMapper.getSignInThisDay(cstId,tt) > 0){
			System.out.println("今日已经签到");
		List<HTmallSignInRecord> tlist = hTmallSignMapper.getTmallSignRecords(cstId);
		signInHisResponse.setTmallSignInRecords(tlist);
		return signInHisResponse;}
		else {

			// 开始签到
			Boolean result = hTmallSignMapper.insertSignInRecord4ThisDay(cstId, tt);
			if (result) {
				List<HTmallSignInRecord> tlist = hTmallSignMapper.getTmallSignRecords(cstId);
				signInHisResponse.setAlreadySignInTodayFlag((hTmallSignMapper.getSignInToday(cstId) > 0) ? true : false);
				signInHisResponse.setContinuousSignInDay(getContinuousSignInDay(tlist));
				signInHisResponse.setTmallSignInRecords(tlist);
				try {
					peService.sendEventWithTime(cstId, sysName, tmallSignInPeEventCode, time);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				sendMemberInfoToEcrmMqTask.syncMemberInfoToECRM(cstId,tmallSignInPeEventCode);
			}

			return signInHisResponse;
		}
	}
}

  

 

  

原文地址:https://www.cnblogs.com/qianjinyan/p/11423772.html