SOURCE

// 出发地
const START = '上海'
// 到达地
const ARRIVES = ['丽江']
// // 返程
const revert = true
// 日期
const dates = [
    // '2021-01-02',
    '2021-01-03',
]

// 出发城市信息
const startCity = CITIES.find(c => c.cityName === START.trim())

// 到达城市信息
const arriveCitys = ARRIVES.map(ARRIVE => CITIES.find(c => c.cityName === ARRIVE.trim()))

const headers = new Headers();
headers.append("Cache-Control", "no-cache");
headers.append("versionCode", "17000");
headers.append("platformInfo", "MWEB");
headers.append("Content-Type", "application/json;charset=UTF-8");
headers.append("channelCode", "MWEB");
headers.append("clientVersion", "1.7.0");
headers.append("Sec-Fetch-Site", "same-origin");
headers.append("Sec-Fetch-Mode", "cors");
headers.append("Sec-Fetch-Dest", "empty");


const fetchData = (date, startCity, arriveCity) =>
    fetch("https://m.juneyaoair.com/server/v2/flight/AvFare", {
        method: 'POST',
        headers,
        body: JSON.stringify({
            "sendCity": startCity.cityName,
            "sendCode": startCity.cityCode,
            "arrCity": arriveCity.cityName,
            "arrCode": arriveCity.cityCode,
            "directType": "D",
            "flightType": "OW",
            "tripType": "D",
            "queryType": "",
            "blackBox": "eyJ2IjoiNGhYNnhwMGNMOXc5KzVnRnkwNDErMDVYTTNQblgrOEZHMDhXTzZ2UXJEcVQrTUJxUHhaMUFWSXF5UFgyVlQzNCIsIm9zIjoicGFkIiwiaXQiOjU4OCwidCI6InZRM3IvQ2FQcW12T0N6N0dKWlczQmxZTXc5a2tKT1dsS0dDMDZtU1V0SHpIWE5XWFBUWHB5SmJZOTVNUm1GWTdPRnJzVmF5b0dOaklmZjgwN3RyNGNRPT0ifQ==",
            "channelCode": "MWEB",
            "clientVersion": "1.7.0",
            "versionCode": "17000",
            departureDate: date,
            returnDate: date
        }),
        redirect: 'follow'
    })
    .then(response => response.text())
    .then(result => JSON.parse(result))
    .catch(error => null)

const init = async () => {

    // const arr = [arriveCity].slice(0, 109).map(arriveCity => fetchData(dates[0], startCity, arriveCity))
    
    const arr = arriveCitys.reduce(
        (r, arriveCity) => r.concat(
            dates.map(
                date => fetchData(date, !revert ? startCity : arriveCity, !revert ? arriveCity : startCity)
                )
            ), [])

    const originList = await Promise.all(arr).then(list => list.reduce((r, a) => {
            return r.concat((a || {}).flightInfoList || [])
        }, []))

    const d = []

    originList.forEach(o => {
        const a = (o.cabinFareList || []).find(ca => ca.cabinType === 'ADT_UNLIMITED_FLY' && ca.cabinNumber !== '0')
        // const a = (o.cabinFareList || []).find(ca => ca.cabinType === 'ADT_UNLIMITED_FLY')
        const {
            depDateTime,
            depAirportName,
            depCityName,
            arrAirportName,
            arrDateTime,
            arrCityName
        } = o
        a && d.push({
            '出发': '周' +  ['日','一','二','三','四','五','六'][new Date(depDateTime).getDay()] + '|' +depDateTime  + '|' + depCityName + '/' +depAirportName,
            '到达': arrCityName + '/' + arrAirportName + '|' + arrDateTime,
            '余票': a.cabinNumber,
            depDateTime
        })
    })
    if (d.length) {
        new Notification('有票了!  有票了!')
        d.sort((i, j) => +new Date(i.depDateTime) - +new Date(j.depDateTime)).map(x => { delete x.depDateTime ; return x })
        console.log('========= 有过票 =========')
        console.table(d)
        // if (d.find(x => x.depDateTime == "2020-11-29 17:40")) {
            // return
        // }
    }
    // } else console.error('真没有!')

}

// window.JXInterval = setInterval(init, 25000)
init()
console 命令行工具 X clear

                    
>
console