0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

予約サイトの設計

Last updated at Posted at 2021-06-30

#施設、建物

export interface Prop {
  //----------const
  id: number;
  na: string;
  roomTyps: number[];//洋室、和室、キャンプ、バンガロー等const ROOMTYPのid
  path: string;//ドメインnegura.gq
  lat: number;//googleMap
  lng: number;//googleMap
  zoom: number;//googleMap
  marker: number;//googleMap
  icon: string;
  users: string[];//編集権限のあるuserId
  txts: string[];//トップページのスライダーに表示
  //-----------MySQL
  price: number;//入場料
  charges: Charge[];//駐車料等他の料金
  close: boolean;//休止
  idx: number;//並び順
}

ドメイン名に一致するpathを持つpropがシステム単位になる。

###部屋タイプ

export const ROOMTYP = {
  1: { na: '洋室' },
  2: { na: '和室' },
  3: { na: 'ドミトリー' },
  4: { na: 'バンガロー' },
  5: { na: 'キャンプ' }
}

変更することはほとんどないので定数としてconfigファイルにベタ書き
#部屋、区画

export interface Room {
  id: number;
  prop: number;//建物、施設id
  typ: number;//ROOMTYP 和室、洋室、キャンプ、バンガローなど
  na: string;
  txt: string;//説明文
  img: string;
  simg: string;
  limg: string;
  price: number;//基本価格
  charges:Charge[];//追加人、車等への課金
  qty: number;//在庫、部屋数
  size: number;//フリーサイト面積上限
  created: Date;
  chat: boolean;//true=チャット口コミ書込み可
  close: boolean;//true=休止中
  idx: number;//並び順
  beds24: boolean;//true=OTA連携
  beds24id: number;//beds24のroomId
  max_people?: number;//↓beds24 params
  max_adult?: number;
  max_child?: number;
  min_stay?: number;
  max_stay?: number;
  min_price?: number;
}

基本となる貸出単位
###雑費

export interface Charge {
  id: number;
  prop: number;
  room: number;
  key: string;
  typ: string;//people,vehicle,tent...etc
  min: number;
  max: number;
  price: number;
  idx: number;//並び順
}

人数追加料、こども料金、駐車料、テント代など
#予約料金算出クラス

export class Unit {
  adult: number;
  child: number;
  vehicles: Vehicle[];
  constructor(adult?: number, child?: number, vehicles?: Vehicle[]) {
    this.adult = adult ? adult : 2;
    this.child = child ? child : 0;
    this.vehicles = vehicles ? vehicles : [{ id: 1, size: VEHICLETYP[1].size }];
  }
  protected toObj(array: any[]) {//[{id:x,...}]arrayからidでグループ化したcountを値に持つObject({x:count})を返す
    let data: any = {};
    for (let v of array) {
      if (data[v.id]) {
        data[v.id]++;
      } else {
        data[v.id] = 1;
      }
    }
    return data;
  }
  size(): number {
    let size = this.adult * 10 + this.child * 5;
    for (let vehicle of this.vehicles) {
      size += vehicle.size;
    }
    return size;
  }
  toString(): { people: string, vehicle: string } {
    let people = this.adult ? `大人:${this.adult}人 ` : "";
    people += this.child ? `こども:${this.child}人 ` : "";
    let vehicle = "";
    const obj = this.toObj(this.vehicles);
    Object.keys(obj).forEach(id => {
      vehicle += `${VEHICLETYP[id].na}:${obj[id]}台 `;
    })
    return { people: people, vehicle: vehicle };
  }
  price(room): number {
    let price = this.adult * room.price_adult + this.child * room.price_child;
    for (let vehicle of this.vehicles) {
      price += room[`price_${VEHICLETYP[vehicle.id].key}`];
    }
    return price;
  }
  queryParams(): Object {//ページ遷移時のクエリストリング生成用
    let params: any = {};
    if (this.adult) params.adult = this.adult;
    if (this.child) params.child = this.child;
    const obj = this.toObj(this.vehicles);
    Object.keys(obj).forEach(id => {
      params[VEHICLETYP[id].key] = obj[id];
    })
    return params;
  }
}

予約料金はroomオブジェクトをpriceメソッドに入れて算出する。
現在のpriceメソッドはChargeに対応していない。

昨日いただいたレビュー
「今後の拡張性を考慮すると、可変部分(課金対象は人?車?テント?、上限面積は?、等)は別クラスに分割しておいた方が、例えば別のキャンプ場に売る時などに、テストの範囲を限定できるかと思いました。」
を実現すべくChargeクラスを新設した。
######元のroomオブジェクト

export interface Room {
  id: number;
  prop: number;//建物、施設id
  typ: number;//ROOMTYP 和室、洋室、キャンプ、バンガローなど
  na: string;
  txt: string;//説明文
  img: string;
  simg: string;
  limg: string;
  price: number;//標準価格
  qty: number;//在庫
  size: number;//フリーサイト面積上限
  created: Date;
  chat: boolean;//true=チャット口コミ書込み可
  close: boolean;//true=休止中
  idx: number;//並び順
  beds24: boolean;//true=OTA連携
  beds24id: number;//beds24のroomId
  max_people?: number;
  max_adult?: number;
  max_child?: number;
  min_stay?: number;
  max_stay?: number;
  min_price?: number;
  price_adult?: number;
  price_child?: number;
  price_car?: number;
  price_motorcycle?: number;
  price_bycycle?: number;
}

雑費をroomに直接並べていくのは拡張性を考えると避けるべきか?
###乗り物(雑費Charge.typのひとつ)

export const VEHICLETYP = {
  0: { na: "", key: "", icon: "", size: 0 },
  1: { na: '', key: "car", icon: "http://maps.google.co.jp/mapfiles/ms/icons/cabs.png", size: 10 },
  2: { na: 'バイク', key: "motorcycle", icon: "http://maps.google.co.jp/mapfiles/ms/icons/motorcycling.png", size: 5 },
  3: { na: '自転車', key: "bicycle", icon: "http://maps.google.co.jp/mapfiles/ms/icons/cycling.png", size: 3 },
  4: { na: 'トレーラー', key: "trailer", icon: "http://maps.google.co.jp/mapfiles/ms/icons/truck.png", size: 15 }
}

あまり変更することがないと思い定数にしたが、sizeは頻繁な変更が必要かも?
Vehicleを配列にした理由は、UIにsegment
https://ionicframework.com/jp/docs/api/segment
を使用したかったため。
利用者のほとんどは車1台、乗り物複数台は稀なので、乗り物の種類ごとに数を入力させるのではなく、乗り物の種類を選んでもらうというアプローチ。
unitform.jpg
車2台は上のように表現され少々不自然だが、さらに最下部の+ボタンでいくつでも追加できる。ほとんどの人にとっては今後乗り物の種類が増えてもUXが低下しない。
おかげでtoObj([])という余計なprotectedメソッドが必要になるが。

というわけで、これからUnitクラスのprice()メソッドをChargeオブジェクトに対応するよう改修していきます...

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?