当前位置: 首页 > news >正文

免费国外建站学校学不到网站建设

免费国外建站,学校学不到网站建设,宁波小程序开发公司,网站建设提议目录 验证数据 加载城市数据 查询列车站点信息 查询列车余票信息 构建列车返回数据 12306 项目中列车数据检索接口路径 #xfeff; TicketController的pageListTicketQuery#xfeff;。 GetMapping(/api/ticket-service/ticket/query)public ResultT… 目录 验证数据 加载城市数据 查询列车站点信息 查询列车余票信息 构建列车返回数据 12306 项目中列车数据检索接口路径 TicketController的pageListTicketQuery。 GetMapping(/api/ticket-service/ticket/query)public ResultTicketPageQueryRespDTO pageListTicketQuery(TicketPageQueryReqDTO requestParam) {return Results.success(ticketService.pageListTicketQueryV1(requestParam));} 验证数据 查询列车数据 Service 实现层接口第一行代码就是通过责任链模式验证数据是否必填以及城市 数据是否存在等执行逻辑。 ticketPageQueryAbstractChainContext.handler(TicketChainMarkEnum.TRAIN_QUERY_FILTER.name(), requestParam); handler具体代码如下 1. 检查相关数据是否为空或空的字符串这个是最先被执行的 /*** 查询列车车票流程过滤器之验证数据是否为空或空的字符串** */ Component public class TrainTicketQueryParamNotNullChainFilter implements TrainTicketQueryChainFilterTicketPageQueryReqDTO {Overridepublic void handler(TicketPageQueryReqDTO requestParam) {if (StrUtil.isBlank(requestParam.getFromStation())) {throw new ClientException(出发地不能为空);}if (StrUtil.isBlank(requestParam.getToStation())) {throw new ClientException(目的地不能为空);}if (requestParam.getDepartureDate() null) {throw new ClientException(出发日期不能为空);}}Overridepublic int getOrder() {return 0;} } 2. 检查数据是否正确 /*** 查询列车车票流程过滤器之验证数据是否正确** */ Component RequiredArgsConstructor public class TrainTicketQueryParamVerifyChainFilter implements TrainTicketQueryChainFilterTicketPageQueryReqDTO {private final RegionMapper regionMapper;private final StationMapper stationMapper;private final DistributedCache distributedCache;private final RedissonClient redissonClient;/*** 缓存数据为空并且已经加载过标识*/private static boolean CACHE_DATA_ISNULL_AND_LOAD_FLAG false;Overridepublic void handler(TicketPageQueryReqDTO requestParam) {StringRedisTemplate stringRedisTemplate (StringRedisTemplate) distributedCache.getInstance();HashOperationsString, Object, Object hashOperations stringRedisTemplate.opsForHash();ListObject actualExistList hashOperations.multiGet(QUERY_ALL_REGION_LIST,ListUtil.toList(requestParam.getFromStation(), requestParam.getToStation()));long emptyCount actualExistList.stream().filter(Objects::isNull).count();if (emptyCount 0L) {return;}if (emptyCount 1L || (emptyCount 2L CACHE_DATA_ISNULL_AND_LOAD_FLAG distributedCache.hasKey(QUERY_ALL_REGION_LIST))) {throw new ClientException(出发地或目的地不存在);}RLock lock redissonClient.getLock(LOCK_QUERY_ALL_REGION_LIST);lock.lock();try {if (distributedCache.hasKey(QUERY_ALL_REGION_LIST)) {actualExistList hashOperations.multiGet(QUERY_ALL_REGION_LIST,ListUtil.toList(requestParam.getFromStation(), requestParam.getToStation()));emptyCount actualExistList.stream().filter(Objects::nonNull).count();if (emptyCount ! 2L) {throw new ClientException(出发地或目的地不存在);}return;}ListRegionDO regionDOList regionMapper.selectList(Wrappers.emptyWrapper());ListStationDO stationDOList stationMapper.selectList(Wrappers.emptyWrapper());HashMapObject, Object regionValueMap Maps.newHashMap();for (RegionDO each : regionDOList) {regionValueMap.put(each.getCode(), each.getName());}for (StationDO each : stationDOList) {regionValueMap.put(each.getCode(), each.getName());}hashOperations.putAll(QUERY_ALL_REGION_LIST, regionValueMap);CACHE_DATA_ISNULL_AND_LOAD_FLAG true;emptyCount regionValueMap.keySet().stream().filter(each - StrUtil.equalsAny(each.toString(), requestParam.getFromStation(), requestParam.getToStation())).count();if (emptyCount ! 2L) {throw new ClientException(出发地或目的地不存在);}} finally {lock.unlock();}}Overridepublic int getOrder() {return 20;} } 加载城市数据 12306 站点查询实际功能中比如你搜索了北京南到杭州东的搜索条件它会帮你列出北京到杭州所有的列车车次。这个很好实现直接通过站点关联到城市通过城市查询列车即可。我们在缓存中有一个 Hash 结构数据专门负责保存列车站点 Code 值与城市之间的关联关系。 // 列车查询逻辑较为复杂详细解析文章查看 https://nageoffer.com/12306/question// v1 版本存在严重的性能深渊问题v2 版本完美的解决了该问题。通过 Jmeter 压测聚合报告得知性能提升在 300% - 500%ListObject stationDetails stringRedisTemplate.opsForHash().multiGet(REGION_TRAIN_STATION_MAPPING, Lists.newArrayList(requestParam.getFromStation(), requestParam.getToStation()));long count stationDetails.stream().filter(Objects::isNull).count();if (count 0) {RLock lock redissonClient.getLock(LOCK_REGION_TRAIN_STATION_MAPPING);lock.lock();try {stationDetails stringRedisTemplate.opsForHash().multiGet(REGION_TRAIN_STATION_MAPPING, Lists.newArrayList(requestParam.getFromStation(), requestParam.getToStation()));count stationDetails.stream().filter(Objects::isNull).count();if (count 0) {ListStationDO stationDOList stationMapper.selectList(Wrappers.emptyWrapper());MapString, String regionTrainStationMap new HashMap();stationDOList.forEach(each - regionTrainStationMap.put(each.getCode(), each.getRegionName()));stringRedisTemplate.opsForHash().putAll(REGION_TRAIN_STATION_MAPPING, regionTrainStationMap);stationDetails new ArrayList();stationDetails.add(regionTrainStationMap.get(requestParam.getFromStation()));stationDetails.add(regionTrainStationMap.get(requestParam.getToStation()));}} finally {lock.unlock();}} 查询列车站点信息 采用Redis而不是Elasticsearch因为搜索只允许选择一天的出发日期。 同时在12306网站上尝试虽然页面上有很多查询条件但大多数条件都是由前端进行筛选实际上并没有触发后端的请求发现只有在点击“查询”按钮时才会真正触发后端的请求而点击页面上的其他筛选条件并不会向后端发出请求。 列车站点数据存入 Redis 中结构如下 具体查询代码 ListTicketListDTO seatResults new ArrayList();String buildRegionTrainStationHashKey String.format(REGION_TRAIN_STATION, stationDetails.get(0), stationDetails.get(1));MapObject, Object regionTrainStationAllMap stringRedisTemplate.opsForHash().entries(buildRegionTrainStationHashKey);if (MapUtil.isEmpty(regionTrainStationAllMap)) {RLock lock redissonClient.getLock(LOCK_REGION_TRAIN_STATION);lock.lock();try {regionTrainStationAllMap stringRedisTemplate.opsForHash().entries(buildRegionTrainStationHashKey);if (MapUtil.isEmpty(regionTrainStationAllMap)) {LambdaQueryWrapperTrainStationRelationDO queryWrapper Wrappers.lambdaQuery(TrainStationRelationDO.class).eq(TrainStationRelationDO::getStartRegion, stationDetails.get(0)).eq(TrainStationRelationDO::getEndRegion, stationDetails.get(1));ListTrainStationRelationDO trainStationRelationList trainStationRelationMapper.selectList(queryWrapper);for (TrainStationRelationDO each : trainStationRelationList) {TrainDO trainDO distributedCache.safeGet(TRAIN_INFO each.getTrainId(),TrainDO.class,() - trainMapper.selectById(each.getTrainId()),ADVANCE_TICKET_DAY,TimeUnit.DAYS);TicketListDTO result new TicketListDTO();result.setTrainId(String.valueOf(trainDO.getId()));result.setTrainNumber(trainDO.getTrainNumber());result.setDepartureTime(convertDateToLocalTime(each.getDepartureTime(), HH:mm));result.setArrivalTime(convertDateToLocalTime(each.getArrivalTime(), HH:mm));result.setDuration(DateUtil.calculateHourDifference(each.getDepartureTime(), each.getArrivalTime()));result.setDeparture(each.getDeparture());result.setArrival(each.getArrival());result.setDepartureFlag(each.getDepartureFlag());result.setArrivalFlag(each.getArrivalFlag());result.setTrainType(trainDO.getTrainType());result.setTrainBrand(trainDO.getTrainBrand());if (StrUtil.isNotBlank(trainDO.getTrainTag())) {result.setTrainTags(StrUtil.split(trainDO.getTrainTag(), ,));}long betweenDay cn.hutool.core.date.DateUtil.betweenDay(each.getDepartureTime(), each.getArrivalTime(), false);result.setDaysArrived((int) betweenDay);result.setSaleStatus(new Date().after(trainDO.getSaleTime()) ? 0 : 1);result.setSaleTime(convertDateToLocalTime(trainDO.getSaleTime(), MM-dd HH:mm));seatResults.add(result);regionTrainStationAllMap.put(CacheUtil.buildKey(String.valueOf(each.getTrainId()), each.getDeparture(), each.getArrival()), JSON.toJSONString(result));}stringRedisTemplate.opsForHash().putAll(buildRegionTrainStationHashKey, regionTrainStationAllMap);}} finally {lock.unlock();}} 查询出来列车基本信息后开始对列车按照出发时间进行排序。 seatResults CollUtil.isEmpty(seatResults)? regionTrainStationAllMap.values().stream().map(each - JSON.parseObject(each.toString(), TicketListDTO.class)).toList(): seatResults; seatResults seatResults.stream().sorted(new TimeStringComparator()).toList(); 查询列车余票信息 列车基本信息已经全部填充完毕了接下来就是查询列车余票信息并填充到基本信息中。 列车余票数据是实时变更的如果在存储到基本信息中就没办法变更了所以单独存储。 for (TicketListDTO each : seatResults) {String trainStationPriceStr distributedCache.safeGet(String.format(TRAIN_STATION_PRICE, each.getTrainId(), each.getDeparture(), each.getArrival()),String.class,() - {LambdaQueryWrapperTrainStationPriceDO trainStationPriceQueryWrapper Wrappers.lambdaQuery(TrainStationPriceDO.class).eq(TrainStationPriceDO::getDeparture, each.getDeparture()).eq(TrainStationPriceDO::getArrival, each.getArrival()).eq(TrainStationPriceDO::getTrainId, each.getTrainId());return JSON.toJSONString(trainStationPriceMapper.selectList(trainStationPriceQueryWrapper));},ADVANCE_TICKET_DAY,TimeUnit.DAYS);ListTrainStationPriceDO trainStationPriceDOList JSON.parseArray(trainStationPriceStr, TrainStationPriceDO.class);ListSeatClassDTO seatClassList new ArrayList();trainStationPriceDOList.forEach(item - {String seatType String.valueOf(item.getSeatType());String keySuffix StrUtil.join(_, each.getTrainId(), item.getDeparture(), item.getArrival());Object quantityObj stringRedisTemplate.opsForHash().get(TRAIN_STATION_REMAINING_TICKET keySuffix, seatType);int quantity Optional.ofNullable(quantityObj).map(Object::toString).map(Integer::parseInt).orElseGet(() - {MapString, String seatMarginMap seatMarginCacheLoader.load(String.valueOf(each.getTrainId()), seatType, item.getDeparture(), item.getArrival());return Optional.ofNullable(seatMarginMap.get(String.valueOf(item.getSeatType()))).map(Integer::parseInt).orElse(0);});seatClassList.add(new SeatClassDTO(item.getSeatType(), quantity, new BigDecimal(item.getPrice()).divide(new BigDecimal(100), 1, RoundingMode.HALF_UP), false));});each.setSeatClassList(seatClassList);} 构建列车返回数据 查看 12306 列车查询页可知会存在不同的查询条件这些查询条件都是通过本次查询所有列车数据构建出来的。不同地区的不同查询列车数据车次类型、出发车站、到达车站以及车次席别都不同。 接下来就是通过构建者模式构建列车查询返回数据。 return TicketPageQueryRespDTO.builder().trainList(seatResults).departureStationList(buildDepartureStationList(seatResults)).arrivalStationList(buildArrivalStationList(seatResults)).trainBrandList(buildTrainBrandList(seatResults)).seatClassTypeList(buildSeatClassList(seatResults)).build();
http://www.hkea.cn/news/14417277/

相关文章:

  • 织梦怎么做单页网站做网站原型现成的框架
  • 商标设计网站免费保定seo网络推广
  • 怎么购买网站空间和域名品牌推广策划方案怎么写
  • 郴州做网站ku0735网站系统分析的步骤有哪些
  • ipv6网站建设东营网站建设收益高
  • 设计公司网站案例网站建设的技能有哪些方面
  • 数据集网站1个亿用户的服务器多少钱
  • 网上商城网站建设方案书三门峡市建设项目备案网站
  • 私人做的不错的网站个人网站建设规划书
  • 黄页网站推广公司做网站的把网站写成一行
  • 中国没公司怎么做网站企业邮箱账号
  • 网站备案背景南京网站建设的公司
  • 理财网站开发迅睿cms模板
  • 做网站在哪儿买空间win2008sr怎么用iis做网站
  • 网站多条件筛选 html在网上那里能接单做网站
  • 宜昌网站建设哪家好五八同城最新招聘信息
  • 网页制作什么主题好深圳seo专家
  • 手机网站页面模板wordpress文章页幻灯片
  • 安徽中机诚建建设有限公司网站天津市招标投标公共服务平台
  • 茂名网站建设公司哪个好新图闻的合作伙伴
  • 个人视频网站制作网站建设方案书例子
  • wordpress环境部署东莞网站优化费用
  • 东莞想做网站太原新站优化
  • 山西网站建设方案从化专业做网站
  • 定制级高端网站建设网站推广软文选天天软文
  • 网站可以做软件检测吗seo公司名字
  • 北京燕郊网站建设帝国cms企业门户网站仿站视频教程 网盘
  • 长兴建设局网站转播网站如何做
  • 推广网站出现中性产品网站优化目的
  • 网站建设与维护制度企业网站营销案例