首页/心系八方/正文
京东凹凸实验室开发Taro跨平台早期的猫眼电影尝鲜案例解析

 2025年06月22日  阅读 4

摘要:Taro跨平台开发早期尝试京东凹凸实验室在开始构建Taro跨平台框架的早期阶段,研发团队便开始了对Taro的初步测试工作。在这一过程中,他们开发了一款名为猫眼电影的小程序,作为典型案例。尽管时间已经过去了数月,但当时所采用的实现策略至今仍具有很高的参考价...

Taro跨平台开发早期尝试

京东凹凸实验室在开始构建Taro跨平台框架的早期阶段,研发团队便开始了对Taro的初步测试工作。在这一过程中,他们开发了一款名为猫眼电影的小程序,作为典型案例。尽管时间已经过去了数月,但当时所采用的实现策略至今仍具有很高的参考价值。本案例基于猫眼电影的实际线上接口进行开发,至于座位预订所需的数据,则是通过模拟操作来获取的;这样的做法主要是为了便于学习和研究。

运行效果及目录分析

操作系统:Window 10  
Taro版本:v0.0.69
Node版本:v8.11.1
github地址: https://github.com/Harhao/miniProgram
复制代码

该案例的主要开发目录是src,其中各文件的功能如下:

app.js:入口配置文件,定义了小程序中所有页面的路由。

├─.idea
│  └─libraries
├─.temp
├─config
└─src
    ├─assets
    │  └─images
    ├─components (公用组件)
    │  ├─Brandbar
    │  ├─Selectbar
    │  ├─Specialbar
    │  └─Toptab(电影详情分类)
    └─pages
    |    ├─cinema(影院列表)
    |    ├─cinemaDetail(影院详情页)
    |    ├─content(电影介绍)
    |    ├─detail(电影详情页)
    |    ├─map(影院地图定位页)
    |    ├─movies(电影列表页)
    |    ├─order(电影票订单页)
    |    ├─person(用户登录页)
    |    ├─position(地理位置选择页)
    |    ├─search(电影/影院搜索页)
    |    ├─seat(影院座位页)
    |    └─user(用户中心)
    |__app.js(入口配置文件)
    |__app.scss
    |__index.html
复制代码

列表页微信小程序的主界面中,特别设置了两大板块,分别是“正在热映”与“即将上映”,用户可以通过Tab组件轻松地在这些分类之间进行切换和浏览。

关键实现点

1. 城市定位路由

猫眼电影小程序在尝试抓取定位城市接口时未能如愿,因此转向猫眼H5平台,获取了包含所有城市的资料。最初,我们用模拟数据进行了操作,但到了后续阶段,我们改用微信小程序的云开发功能来生成模拟数据。

import Taro, { Component } from "@tarojs/taro";
import Movies from "./pages/movies/movies";
import "./app.scss";
class App extends Component {
  config = {
    //访问路由文件定义
    pages: [
      "pages/movies/movies",
      "pages/person/person",
      "pages/cinema/cinema",
      "pages/position/position",
      "pages/search/search",
      "pages/detail/detail",
      "pages/content/content",
      "pages/cinemaDetail/cinemaDetail",
      "pages/map/map",
      "pages/seat/seat",
      "pages/user/user",
      "pages/order/order"
    ],
    //小程序顶部设置
    window: {
      backgroundTextStyle: "light",
      navigationBarBackgroundColor: "#e54847",
      navigationBarTitleText: "猫眼电影",
      navigationBarTextStyle: "white",
      enablePullDownRefresh: true
    },
    //底部tab导航栏配置
    tabBar: {
      color: "#333",
      selectedColor: "#f03d37",
      backgroundColor: "#fff",
      borderStyle: "black",
      list: [
        {
          pagePath: "pages/movies/movies",
          text: "电影",
          iconPath: "./assets/images/index.png",
          selectedIconPath: "./assets/images/index_focus.png"
        },
        {
          pagePath: "pages/cinema/cinema",
          text: "影院",
          iconPath: "./assets/images/themeOld.png",
          selectedIconPath: "./assets/images/theme.png"
        },
        {
          pagePath: "pages/person/person",
          text: "我的",
          iconPath: "./assets/images/person.png",
          selectedIconPath: "./assets/images/personSelect.png"
        }
      ]
    }
  };
  render() {
    // Movies小程序入口文件
    return ;
  }
}
Taro.render(, document.getElementById("app"));
复制代码

2. 电影列表Tab组件

微信小程序猫眼电影订座功能实现_Taro跨平台开发猫眼电影实例_taro小程序开发案例

目前上映和即将上映的影片类型,均由Taro官方的Tab组件负责展示。该组件的核心代码主要承担着调节这两类信息显示与隐藏的任务,其目的是确保用户在使用过程中的交互体验能够保持流畅。

3. 电影列表页内容

该页面详尽展示了电影的评分、推荐指数和票价等详细信息。鉴于微信小程序的接口功能与用户的地理位置信息紧密相关,因此在页面加载期间,我们需先获取并核实用户所在城市的特定标识码。

// movies页
export default class Movies extends Component {
  config = {
    navigationBarTitleText: "猫眼电影"
  };
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    this.getCities();
  }
  getCities() {
    Taro.request({
      url:
        "https://www.easy-mock.com/mock/5ba0a7f92e49497b37162e32/example_copy/cities_copy_1541385673090",
      method: "GET",
      header: {
        Accept: "application/json, */*",
        "Content-Type": "application/json"
      }
    }).then(res => {
      if (res.statusCode == 200) {
        let data = res.data.data.data.data;
        Taro.setStorageSync("cities", data);
      }
    });
  }
  render() {
    return (
      "movies">
        
      
    );
  }
}
复制代码

真实线上接口与数据伪造

为了搜集猫眼电影平台上的实际观影信息,研究案例中运用了虚构的请求方式,其目的是为了绕过系统对接口访问的限制。具体而言:

通过运用${Date.now()}这一函数,我们能够实时获取当前时间的戳记,从而确保所发送的请求具有时效性。


 "tabItemContent" hidden={this.state.currentNavtab === 0?false:true}>
 
 
 "tabItemContent" hidden={this.state.currentNavtab === 1?false:true}>
 
 
复制代码

城市代码(ci)与电影院代码是至关重要的变量,这些变量主要用于检索特定电影院座位的详细信息。

座位模拟与选座功能

1. 座位数据初始化

座位信息采用二维数组表示:

getMoviesOnList(){
    let cityId = this.state.id
    Taro.showLoading({
      title:"加载中"
    });
    Taro.request({
      url:"https://m.maoyan.com/ajax/movieOnInfoList?token=",
      method:"GET",
      header:{
        "Cookie":`_lxsdk_cuid=164b6cae2cac8-02b7b032f571b5-39614706-1fa400-164b6cae2cbc8; v=3; iuuid=1A6E888B4A4B29B16FBA1299108DBE9CA19FF6972813B39CA13A8D9705187374; revrev=76338a29; _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; webp=true; __mta=3463951.1532075108184.1533098338076.1533118040602.20; _lxsdk=1A6E888B4A4B29B16FBA1299108DBE9CA19FF6972813B39CA13A8D9705187374; from=canary; selectci=true; __mta=3463951.1532075108184.1533118040602.1533118773295.21; _lxsdk_s=164f4f4c9e9-45e-d1b-46%7C%7C50; ci=${cityId}`
      }
    }).then(res=>{
      if(res.statusCode == 200){
        Taro.hideLoading();
        res.data.movieList.forEach((value)=>{
          let arr = value["img"].split("w.h");
          value["img"] = arr[0]+"128.180"+  arr[1]
        });
        this.setState({
          onList:res.data.movieList,
          startIndex:res.data.movieList.length,
          lastIndex:res.data.total -1,
          movieIds:res.data.movieIds
        });
      }else{
        this.setState({
          onList:null,
          movieIds:null
        })
      }
    })
  }
复制代码

0:表示该位置有座位且未被选中。

E:表示该位置没有座位(空位)。

2. 接口数据处理

从线上获取的座位数据(字段st)需进一步处理:

[
    [0,0,0,0,0,0],
    [E,0,0,E,0,0],
    [0,0,0,0,0,0],
    [E,0,0,E,0,0]
]
复制代码

stN,则标记为0(可选的座位)。

stE,则标记为空位。

3. 选座与推荐功能

选座逻辑座位的位置可以通过行号和列号来精确查找,其中item标记用来指示座位的实际状况,若显示为0,则意味着该座位目前可供挑选;若显示为2,则说明该座位已被他人预约。

 initParams(){
    const params = this.$router.params;
    const self = this;
    Taro.setNavigationBarTitle({
      title:params.cinemaName
    })
    Taro.showLoading({
      title:"加载中..."
    });
    Taro.request({
      url:`https://m.maoyan.com/ajax/seatingPlan?timestamp=${Date.now()}`,
      method:'post',
      header:{
        'Cookie': 'uuid_n_v=v1; iuuid=26F6BA50506A11E9A973FDD3C7EBDF0E29C7297EC72D4F77A53F9445EF0EE9F3; webp=true; ci=20%2C%E5%B9%BF%E5%B7%9E; _lxsdk_cuid=169be42cf28c8-098c7e821e63bd-2d604637-3d10d-169be42cf29c8; _lxsdk=26F6BA50506A11E9A973FDD3C7EBDF0E29C7297EC72D4F77A53F9445EF0EE9F3; from=canary; uid=124265875; token=9P1-5VoykD_qrpBxpTvSoVhMwzQAAAAAJwgAAE2za6eVZdI-oORrTHb8dP4JEMYCiza0zSSNoRkHx4qajm2Nu6ClhU00u5A1avIySg; __mta=250960825.1553675243337.1553675275840.1553675275842.6; user=124265875%2C9P1-5VoykD_qrpBxpTvSoVhMwzQAAAAAJwgAAE2za6eVZdI-oORrTHb8dP4JEMYCiza0zSSNoRkHx4qajm2Nu6ClhU00u5A1avIySg; _lxsdk_s=169be42cf2b-ca7-4ca-570%7C%7C14'
      },
      data:{
        cityId:params.cityId,
        ci:params.ci,
        seqNo:params.seqNo
      }
    }).then(res=>{
      if(res.statusCode ==200){
        Taro.hideLoading();
        const seatData = res.data.seatData;
        const seatArray = [];
        seatData.seat.sections[0].seats.map(item=>{
          let  arr = [];
          item["columns"].map(seat=>{
            if(seat["st"] == "N"){
              arr.push('0');
            }else{
              arr.push('E')
            }
          })
          seatArray.push(arr);
        })
        self.setState({
          seatData:seatData,
          seatArray:seatArray
        });
      }
    })
  }
复制代码

推荐座位本系统可满足单座、双座以及三座和四座的推荐选座需求,不过,鉴于我们尚未成功获取到猫眼电影情侣座的相关接口信息,这项功能目前还未能投入使用。

电影详情页实现

详情页展示电影的简略介绍和预告片,逻辑较为简单:

调用电影详情数据接口,获取电影描述和图片。

由于直接获取的图片路径有可能出现偏差,所以必须对路径进行必要的调整,从而确保图片能够被顺利加载。

selectSeat(row,column,item){
    const self = this;
    const arr = this.state.seatArray;
    // item代表该座位是否可选
    if(item == 0){
      if(self.state.buySeat.length ==4){
        Taro.showToast({
          title: '最多选择4个座位',
          duration: 2000
        })
        return false;
      }else{
        let  buySeat = self.state.buySeat;
        arr[row][column]= '2';
        buySeat.push({
          "row":row,
          "column":column
        });
        self.setState({
          buySeat:buySeat,
          seatArray:arr
        })
      }
    }else{
      arr[row][column]= '0';
      const  buySeat = this.state.buySeat;
      let tmpArr = this.state.buySeat;
      buySeat.map((value,index)=>{
        if(value["row"]== row && value["column"]== column){
          tmpArr.splice(index,1);
          self.setState({
            buySeat:tmpArr,
            seatArray:arr
          })
        }
      })
    }
  }
复制代码

总结

此案例展示了Taro在跨平台开发领域的初步尝试,尽管部分数据尚待模拟处理,但它的整体架构和实现方法为后续开发提供了极有价值的参考。若您认为这个案例对您有所启发,不妨点赞以示鼓励。

  selectAll(seats){
    const self = this;
    seats.map(item=>{
      let row = parseInt(item.rowId.split('0')[0]);
      let column = parseInt(item.columnId.split('0')[0]);
      let itemIndex = self.state.seatArray[row][column];
      self.selectSeat(row,column,itemIndex);
    })
  }
  getRecomment(recomment,num){
    switch(num){
      case 1:this.selectAll(recomment.bestOne.seats);break;
      case 2:this.selectAll(recomment.bestTwo.seats);break;
      case 3:this.selectAll(recomment.bestThree.seats);break;
      case 4:this.selectAll(recomment.bestFour.seats);break;
    }
  }
复制代码

版权声明:本文为 “博览广文网” 原创文章,转载请附上原文出处链接及本声明;

原文链接:http://wen.bjhwtx.com/post/34269.html

标签:

博览广文网

博览广文网为所有文学爱好者、新闻爱好者、关注生活多方面内容的观众朋友提供多方位的内容呈现、提升阅读空间、填充碎片时间,开阔读者的视野、增长见识、了解民生、一个让您不出户尽知天下事的网站平台!
热门标签
关于我们
广文舒阅网—让天下读者有家可归!这里汇聚了各类优质文化信息,无论是全球热点、历史故事,还是实用百科、趣味探索,您都能轻松获取。我们希望用阅读点亮您的世界,让每一次浏览都充满收获和乐趣。
导航栏A标题
广文舒阅网
扫码关注
联系方式
全国服务热线:0755-88186625
Q Q:8705332
Email:admin@lanyu.com
地址:深圳市福田区海雅缤纷国际大厦5层501
Copyright 深圳市蓝宇科技有限公司 版权所有 备案号:京ICP备20013102号-1