上源代码
package com.czcb.park.controller; import com.czcb.park.bean.ChargeEventRequest; import com.czcb.park.bean.ChargeEventResponse; import com.czcb.park.bean.ComeRecord; import com.czcb.park.repo.ComeRecordRepository; import io.micrometer.core.instrument.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.*; import java.nio.charset.Charset; import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; //import org.springframework.util.DigestUtils; @RestController @RequestMapping(path = "/") public class TestController { public static final String SIGNKEY = "app.sign-key"; public static final String SPARE_TIME = "app.spare-time"; private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private final static Logger logger = LoggerFactory.getLogger(TestController.class); Environment environment; ComeRecordRepository comeRecordRepository; @Autowired public void setComeRecordRepository(ComeRecordRepository comeRecordRepository) { this.comeRecordRepository = comeRecordRepository; } @Autowired public void setEnvironment(Environment environment) { this.environment = environment; } /** * 获取车辆入场信息 * * @param cph 车处于号 * @return */ @RequestMapping(path = "/get") public @ResponseBody Iterable<ComeRecord> get(@RequestParam String cph) { return comeRecordRepository.findByCph(cph); } /** * 车辆入场 * * @param cph 车牌号 * @return */ @RequestMapping(path = "/in") public @ResponseBody ComeRecord in(@RequestParam String cph) { ComeRecord comeRecord = new ComeRecord(); comeRecord.setCph(cph); comeRecord.setCardNo("123123"); comeRecord.setInTime(new Timestamp(System.currentTimeMillis())); comeRecordRepository.save(comeRecord); return comeRecord; } /** * 车辆出场 * * @param cph 车牌号 * @return */ @RequestMapping(path = "/out") public @ResponseBody ComeRecord out(@RequestParam String cph) { List<ComeRecord> comeRecords = comeRecordRepository.findByCph(cph); if (comeRecords.size() > 0) { comeRecordRepository.delete(comeRecords.get(0)); return comeRecords.get(0); } else { return null; } } /** * 充电减免优惠 * * @param chargeEventRequest * @return */ @RequestMapping( path = "/chargeEvent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody ChargeEventResponse chargeEvent(@RequestBody ChargeEventRequest chargeEventRequest) { ChargeEventResponse response = new ChargeEventResponse(); try { logger.info(String.format("收到充电优惠事件,merchId=【%s】,plateNo=【%s】,duration=【%s分钟】", chargeEventRequest.getMerchId(), chargeEventRequest.getPlateNo(), chargeEventRequest.getDuration())); String sign = genSign(chargeEventRequest); if (!Objects.equals(chargeEventRequest.getSign(), sign)) { logger.info(String.format("签名校验失败,%s but %s expected", chargeEventRequest.getSign(), sign)); response.setCode("20001"); response.setData(new HashMap()); response.setMsg("签名校验失败"); return ChargeEventResponse.buildResponse(ChargeEventResponse.RespType.ERROR_SIGN_DISMATCH); } else { logger.info("签名校验通过"); String cph = chargeEventRequest.getPlateNo(); // 车牌号 List<ComeRecord> comeRecords = comeRecordRepository.findByCph(cph); if (comeRecords.size() == 0) { logger.error(String.format("未找到车辆【%s】的入场记录", cph)); return ChargeEventResponse.buildResponse(ChargeEventResponse.RespType.ERROR_CAR_NOT_FOUND); } else if (comeRecords.size() > 1) { return ChargeEventResponse.buildResponse(ChargeEventResponse.RespType.ERROR_CAR_REENTRANCE); } else { ComeRecord comeRecord = comeRecords.get(0); logger.info(String.format( "找到车辆【%s】的入场记录,入场时间【%s】,减免时长【%d分钟】", cph, comeRecord.getInTime().toLocalDateTime(), chargeEventRequest.getDuration() )); // 可提供的出场时间, 从配置项读取,默认为0 int spareTime = 0; try { spareTime = Integer.parseInt(environment.getProperty(SPARE_TIME)); } catch (Exception e) { } // 多次减免以最后一次计,需要把原始入场时间或前一次减免时间记录下来,以重新计算 String originInTime = comeRecord.getOriginInTime(); // 先备份原始入场时间字段,只备份一次 if (Objects.isNull(originInTime) || originInTime == "") { originInTime = comeRecord.getInTime().toLocalDateTime().format(formatter); logger.info(String.format("备份车辆【%s】原始入场时间:%s", cph, originInTime)); comeRecord.setOriginInTime(originInTime); } int duration = chargeEventRequest.getDuration(); Timestamp inTime = Timestamp.valueOf( LocalDateTime.parse(comeRecord.getOriginInTime(), formatter)); // 减免时长,当前时间加上额外出场时间,最多2小时 //inTime.setTime( // Math.min(inTime.getTime() + duration * 60 * 1000L, // System.currentTimeMillis() + spareTime * 60 * 1000L)); // 2019年5月30日修改:无论何种情况,入场时间增加2小时+spare_time inTime.setTime(inTime.getTime() + duration * 60 * 1000L + spareTime * 60 * 1000L); logger.info(String.format("修改车辆【%s】的入场时间为【%s】", cph, inTime.toLocalDateTime())); comeRecord.setInTime(inTime); comeRecord.setSfGate("滴滴收费减免"); comeRecordRepository.save(comeRecord); logger.info(String.format("更新车辆【%s】的入场记录成功", cph)); return ChargeEventResponse.buildResponse(ChargeEventResponse.RespType.SUCCESS); } } } catch (Exception e) { logger.error("服务器异常", e); return ChargeEventResponse.buildResponse(ChargeEventResponse.RespType.ERROR_INTERNAL_EXCEPTION, e.getMessage()); } } /** * 充电减免优惠-生成签名测试 * * @param chargeEventRequest * @return */ @RequestMapping( path = "/chargeEventKey", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody ChargeEventRequest chargeEventKey(@RequestBody ChargeEventRequest chargeEventRequest) { ChargeEventRequest request = chargeEventRequest; request.setSign(genSign(chargeEventRequest)); return request; } /** * 生成签名 * * @param chargeEventRequest * @return */ public String genSign(ChargeEventRequest chargeEventRequest) { Map<String, String> paramMap = new HashMap<>(); paramMap.put("merchId", chargeEventRequest.getMerchId()); paramMap.put("plateNo", chargeEventRequest.getPlateNo()); paramMap.put("duration", chargeEventRequest.getDuration() + ""); String signKey = environment.getProperty(SIGNKEY); String[] keyArray = new String[paramMap.keySet().size()]; paramMap.keySet().toArray(keyArray); Arrays.sort(keyArray); StringBuffer sb = new StringBuffer(); for (String key : keyArray) { if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(paramMap.get(key))) { sb.append(key).append("=").append(paramMap.get(key)).append("&"); } } sb.append("key=").append(DigestUtils.md5DigestAsHex(signKey.getBytes(Charset.forName("utf-8")))); String sign = DigestUtils.md5DigestAsHex(sb.toString().getBytes(Charset.forName("utf-8"))).toUpperCase(); // logger.info("param : {}", sb.toString()); // logger.info("param: {} sign: {}", sb.toString(), sign); return sign; } }