Skip to content

业务讲解-详解用户选择节目座位的流程

前置知识讲解

  • 建议小伙伴先跳转到相应文档学习什么是缓存击穿?

技术精华-如何解决缓存击穿?

  • 学习如何利用双重检测锁思想优化查询节目详情?

如何应对突发性热点数据暴增导致系统压力过大问题?

流程讲解

在查询节目详情后,就开始了订票的流程,这时要分为两个分支,节目分为可选择座位和不可选择座位,根据节目表中的字段permit_choose_seat来判断

如果节目可以选择座位的话,在节目详情页面会有可选座的说明

1723690303276-99fd8e44-d367-45f4-9663-d78610fa23e9.jpeg

可以点击选座购买,接着会跳转到选择座位的页面

1723690330801-1c896ebd-82da-43cb-9408-770402e85c27.jpeg

控制层

com.damai.controller.SeatController#relateInfo

java
@ApiOperation(value = "查询座位相关信息")
@PostMapping(value = "/relate/info")
public ApiResponse<SeatRelateInfoVo> relateInfo(@Valid @RequestBody SeatListDto seatListDto) {
    return ApiResponse.ok(seatService.relateInfo(seatListDto));
}

service层

com.damai.service.SeatService#relateInfo

java
public SeatRelateInfoVo relateInfo(SeatListDto seatListDto) {
    SeatRelateInfoVo seatRelateInfoVo = new SeatRelateInfoVo();
    //从redis中查询节目
    ProgramVo programVo = 
            redisCache.get(RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM,seatListDto.getProgramId()),ProgramVo.class);
    //如果查询不到,则去数据库中查询,再放入redis中
    if (Objects.isNull(programVo)){
        ProgramGetDto programGetDto = new ProgramGetDto();
        programGetDto.setId(seatListDto.getProgramId());
        programVo = programService.detail(programGetDto);
    }
    //查询演出时间
    ProgramShowTime programShowTime = programShowTimeService.selectProgramShowTimeByProgramId(seatListDto.getProgramId());
    //查询该节目下的票档集合
    List<TicketCategoryVo> ticketCategoryVoList = ticketCategoryService
            .selectTicketCategoryListByProgramIdMultipleCache(programVo.getId(),programShowTime.getShowTime());
    
    List<SeatVo> seatVos = new ArrayList<>();
    //遍历票档集合
    for (TicketCategoryVo ticketCategoryVo : ticketCategoryVoList) {
        //根据节目id和票档id来查询出座位集合,汇总到seatVos中
        seatVos.addAll(selectSeatResolution(seatListDto.getProgramId(),ticketCategoryVo.getId(),
                DateUtils.countBetweenSecond(DateUtils.now(), programShowTime.getShowTime()), TimeUnit.SECONDS));
    }
    //如果节目不允许选择座位,直接抛出异常
    if (programVo.getPermitChooseSeat().equals(BusinessStatus.NO.getCode())) {
        throw new DaMaiFrameException(BaseCode.PROGRAM_NOT_ALLOW_CHOOSE_SEAT);
    }

    Map<String, List<SeatVo>> seatVoMap =
            seatVos.stream().collect(Collectors.groupingBy(seatVo -> seatVo.getPrice().toString()));
    //节目id
    seatRelateInfoVo.setProgramId(programVo.getId());
    //节目地点
    seatRelateInfoVo.setPlace(programVo.getPlace());
    //节目演出时间
    seatRelateInfoVo.setShowTime(programShowTime.getShowTime());
    //节目演出时间对应的星期
    seatRelateInfoVo.setShowWeekTime(programShowTime.getShowWeekTime());
    //节目的价格列表
    seatRelateInfoVo.setPriceList(seatVoMap.keySet().stream().sorted().collect(Collectors.toList()));
    //节目的座位列表
    seatRelateInfoVo.setSeatVoMap(seatVoMap);
    return seatRelateInfoVo;
}

下面开始逐步的进行讲解

查询节目信息

java
//从redis中查询节目
ProgramVo programVo = 
        redisCache.get(RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM,seatListDto.getProgramId()),ProgramVo.class);
//如果查询不到,则去数据库中查询,在放入redis中
if (Objects.isNull(programVo)){
    ProgramGetDto programGetDto = new ProgramGetDto();
    programGetDto.setId(seatListDto.getProgramId());
    //查询节目详情
    programVo = programService.detail(programGetDto);
}

先从redis查询节目信息,查询不到的话,调用节目详情方法

其实查询座位信息这步之前是要查询节目详情的,在查询节目详情中已经节目信息放到redis了中,这里再查询一遍也是为了保险,说白了,还是怕有意外将请求直接落到数据库上,造成数据库的压力过大

关于节目详情的具体流程,在查询节目详情的文档中有细致的讲解,本文就不再赘述

接下来的流程就不是很复杂了,查询座位信息、查询演出时间,然后将信息进行组装后返回给前端

查询演出时间

java
 ProgramShowTime programShowTime = programShowTimeService.selectProgramShowTimeByProgramId(seatListDto.getProgramId());

查询演出时间的详细逻辑在如何应对突发性热点数据暴增导致系统压力过大问题?章节中已经详细讲解过,这里就不再赘述

查询座位

java
//遍历票档集合
for (TicketCategoryVo ticketCategoryVo : ticketCategoryVoList) {
    //根据节目id和票档id来查询出座位集合,汇总到seatVos中
    seatVos.addAll(selectSeatResolution(seatListDto.getProgramId(),ticketCategoryVo.getId(),
            DateUtils.countBetweenSecond(DateUtils.now(), programShowTime.getShowTime()), TimeUnit.SECONDS));
}
java
@ServiceLock(lockType= LockType.Read,name = SEAT_LOCK,keys = {"#programId","#ticketCategoryId"})
public List<SeatVo> selectSeatResolution(Long programId,Long ticketCategoryId,Long expireTime,TimeUnit timeUnit) {
    //从缓存中查询所有状态的座位
    List<SeatVo> seatVoList = getSeatVoListByCacheResolution(programId,ticketCategoryId);
    if (CollectionUtil.isNotEmpty(seatVoList)) {
        return seatVoList;
    }
    //如果redis中三种状态的座位都没有,说明根本就没有往redis中存放过
    //加锁
    RLock lock = serviceLockTool.getLock(LockType.Reentrant, GET_SEAT_LOCK, new String[]{String.valueOf(programId),
            String.valueOf(ticketCategoryId)});
    lock.lock();
    try {
        //再从缓存中查询座位数据
        seatVoList = getSeatVoListByCacheResolution(programId,ticketCategoryId);
        if (CollectionUtil.isNotEmpty(seatVoList)) {
            return seatVoList;
        }
        //如果缓存中还是没有,则从数据库中查询
        LambdaQueryWrapper<Seat> seatLambdaQueryWrapper =
                Wrappers.lambdaQuery(Seat.class).eq(Seat::getProgramId, programId)
                        .eq(Seat::getTicketCategoryId,ticketCategoryId);
        List<Seat> seats = seatMapper.selectList(seatLambdaQueryWrapper);
        for (Seat seat : seats) {
            SeatVo seatVo = new SeatVo();
            BeanUtil.copyProperties(seat, seatVo);
            seatVo.setSeatTypeName(SeatType.getMsg(seat.getSeatType()));
            seatVoList.add(seatVo);
        }
        //将座位按照状态进行分类
        Map<Integer, List<SeatVo>> seatMap = seatVoList.stream().collect(Collectors.groupingBy(SeatVo::getSellStatus));
        //没有售卖的座位
        List<SeatVo> noSoldSeatVoList = seatMap.get(SellStatus.NO_SOLD.getCode());
        //正在锁定的座位
        List<SeatVo> lockSeatVoList = seatMap.get(SellStatus.LOCK.getCode());
        //已经售卖的座位
        List<SeatVo> soldSeatVoList = seatMap.get(SellStatus.SOLD.getCode());
        if (CollectionUtil.isNotEmpty(noSoldSeatVoList)) {
            //将没有售卖的座位放入redis中
            redisCache.putHash(RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM_SEAT_NO_SOLD_RESOLUTION_HASH, 
                            programId,ticketCategoryId),noSoldSeatVoList.stream()
                            .collect(Collectors.toMap(s -> String.valueOf(s.getId()),s -> s,(v1,v2) -> v2))
                    ,expireTime, timeUnit);
        }
        if (CollectionUtil.isNotEmpty(lockSeatVoList)) {
            //将正在锁定的座位放入redis中
            redisCache.putHash(RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM_SEAT_LOCK_RESOLUTION_HASH, 
                            programId,ticketCategoryId),lockSeatVoList.stream()
                            .collect(Collectors.toMap(s -> String.valueOf(s.getId()),s -> s,(v1,v2) -> v2))
                    ,expireTime, timeUnit);
        }
        if (CollectionUtil.isNotEmpty(soldSeatVoList)) {
            //将已经售卖的座位放入redis中
            redisCache.putHash(RedisKeyBuild.createRedisKey(RedisKeyManage.PROGRAM_SEAT_SOLD_RESOLUTION_HASH, 
                            programId,ticketCategoryId)
                    ,soldSeatVoList.stream()
                            .collect(Collectors.toMap(s -> String.valueOf(s.getId()),s -> s,(v1,v2) -> v2))
                    ,expireTime, timeUnit);
        }
        //将座位集合,先按座位行号排序,再接着按座位列号排序
        seatVoList = seatVoList.stream().sorted(Comparator.comparingInt(SeatVo::getRowCode)
                .thenComparingInt(SeatVo::getColCode)).collect(Collectors.toList());
        return seatVoList;
    }finally {
        lock.unlock();
    }
}

分别从redis中查询没有售卖、锁定中、已售卖所有状态的座位列表,如果都没有查到,说明redis中没有存放过,则去数据库中查询座位,再把这些座位按照售卖状态分组后,再放入redis中

获得了座位集合后,将这些所有的座位先按座位行号排序,再接着按座位列号排序后,将列表返回

验证节目是否选座

java
if (programVo.getPermitChooseSeat().equals(BusinessStatus.NO.getCode())) {
    throw new DaMaiFrameException(BaseCode.PROGRAM_NOT_ALLOW_CHOOSE_SEAT);
}

如果节目的规定是不允许进行手动选择座位的,则要抛出异常,不再往下执行

这里可能有小伙伴会想为什么不在查询座位之前来验证节目是否选座?而是要在查询座位后再验证?

因为不论节目是否允许选座,等到用户下单后,都是要选择相应的座位进行锁定的,把座位加载出来放到缓存中,这样别的用户查询这个节目的座位时,就可以直接从缓存中查询了。

将座位列表分组

java
Map<String, List<SeatVo>> seatVoMap = 
                seatVos.stream().collect(Collectors.groupingBy(seatVo -> seatVo.getPrice().toString()));

这里是将座位集合,按照座位的价格进行分组成Map结构。key:座位价格  value:座位集合

组装数据

到这步需要展示的数据就已经全部查询出来了,接着就是组装数据

java
//节目id
seatRelateInfoVo.setProgramId(programVo.getId());
//节目地点
seatRelateInfoVo.setPlace(programVo.getPlace());
//节目演出时间
seatRelateInfoVo.setShowTime(programShowTime.getShowTime());
//节目演出时间对应的星期
seatRelateInfoVo.setShowWeekTime(programShowTime.getShowWeekTime());
//节目的价格列表
seatRelateInfoVo.setPriceList(seatVoMap.keySet().stream().sorted().collect(Collectors.toList()));
//节目的座位列表
seatRelateInfoVo.setSeatVoMap(seatVoMap);
return seatRelateInfoVo;

**seatVoMap.keySet().stream().sorted().collect(Collectors.toList())**就是价格列表

用户在选择价格时,需要将该价格对应的座位列表进行高亮显示,前端可根据返回的seatVoMap也就是Map结构来实现此功能

返回前端的实体Vo对象

com.damai.vo.SeatRelateInfoVo

java
@Data
@ApiModel(value="SeatRelateInfoVo", description ="座位相关信息")
public class SeatRelateInfoVo implements Serializable {

    private static final long serialVersionUID = 1L;
    
    
    @ApiModelProperty(name ="programId", dataType ="Long", value ="节目表id")
    private Long programId;
    
    @ApiModelProperty(name ="place", dataType ="String", value ="地点")
    private String place;
    
    @ApiModelProperty(name ="showTime", dataType ="Date", value ="演出时间")
    private Date showTime;
    
    @ApiModelProperty(name ="showWeekTime", dataType ="String", value ="演出时间所在的星期")
    private String showWeekTime;
    
    @ApiModelProperty(name ="priceList", dataType ="List<String>", value ="价格集合")
    private List<String> priceList;
    
    @ApiModelProperty(name ="seatVoMap", dataType ="Map<String,List<SeatVo>>", value ="座位集合")
    private Map<String,List<SeatVo>> seatVoMap;
   
}

返回给前端的示例数据结构

json
{
    "code": "0",
    "message": "",
    "data": {
        "programId": "1",
        "place": "本土王牌LIVE",
        "showTime": "2024-03-21 20:00:00",
        "showDayTime": "",
        "showWeekTime": "周四",
        "priceList": [
            "180"
        ],
        "seatVoMap": {
            "180": [
                {
                    "id": "1",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "2",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "3",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "4",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "5",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "6",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "7",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "8",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "9",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "10",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "1",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "11",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "12",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "13",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "14",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "15",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "16",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "17",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "18",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "19",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "20",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "2",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "21",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "22",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "23",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "24",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "25",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "26",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "27",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "28",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "29",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "30",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "3",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "31",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "32",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "33",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "34",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "35",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "36",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "37",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "38",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "39",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "40",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "4",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "41",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "42",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "43",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "44",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "45",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "46",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "47",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "48",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "49",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "50",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "5",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "51",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "1",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "52",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "2",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "53",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "3",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "54",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "4",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "55",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "5",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "56",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "6",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "57",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "7",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "58",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "8",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "59",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "9",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                },
                {
                    "id": "60",
                    "programId": "1",
                    "ticketCategoryId": "2",
                    "rowCode": "6",
                    "colCode": "10",
                    "seatType": "1",
                    "seatTypeName": "通用座位",
                    "price": "180",
                    "sellStatus": "1"
                }
            ]
        }
    }
}

更新: 2025-11-21 10:28:18
原文: https://www.yuque.com/u22210564/ykdrdh/gln3ytflw2keiuvw

Java 后端面试知识库