---
# System prepended metadata

title: 運動中心 api

---

# 運動中心 api 

邏輯: 某一頁可以找到場地的 Object : providers

利用 Template7 先將 BODY 建立一個 屬於外掛的 DOM，給予 ID，由於頁面本身有 Jqeury 所以直接引用。接著綁定按鈕事件， reload 跟 原始網頁的 method 預約

再跑一次 providers 迴圈，將變數塞入物件，建立實例，因為後段一次只吃一個場地的參數，所以依次將 ID 塞到 job 陣列裡面。

建立完畢之後 doJob，每次將 job 的陣列吐出一個 value， 塞入 run 中，run 建立一個 Promise，代表這個場地資料取得完畢，並且 render dom。結束之後繼續把 job 變數重複傳遞，直到 job 變成空陣列為止

class 物件：主要包裝了兩個 load、send

#### load
根據 actionInit 去針對後端寫入場地參數
接著 actionGetDateList 去要每日的時段列表
讀取資料 render 到 dom 中

#### send
根據 actionInit 去針對後端寫入場地參數
呼叫原生網頁的 API 送 日期 (date) 時間(time) => 跳轉


## Fetch 版本 
```javascript  
// ==UserScript==
// @name         sport_auto_api
// @namespace    http://mesak.tw
// @version      1.0
// @description  Help order sport place
// @author       Mesak
// @match        https://pzsc.17fit.com/service-flow-sp
// @icon         https://www.google.com/s2/favicons?sz=64&domain=17fit.com
// @require      https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.3/moment.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/template7/1.4.1/template7.min.js
// ==/UserScript==
const dataFormat = "YYYY/MM/DD";
const allowDates = [moment(), moment().add(1, "days"), moment().add(2, "days"), moment().add(3, "days")];
const bodyTemplate = `<section class="container" id="plugin_order_place">
<div class="row">
{{#each this}}
  <div class="col-md-6">
	<div id="place_{{member_id}}" data-key="{{@key}}" class="panel panel-primary">
	  <div class="panel-heading"><span>{{member_name}}</span>
	    <button type="button" class="refresh close" data-id="{{member_id}}">
	    	<span class="glyphicon glyphicon-refresh" aria-hidden="true"></span>
	    </button>
	  </div>
	  <div class="panel-body text-center"></div>
	</div>
  </div>
{{/each}}
</div>
</section>`;
const dateTemplate = `
<div class="row">
    {{#each list}}
	<div class="col-md-3">
        <h4>{{title}}</h4>
    {{#each times}}
        <div style="margin-bottom:6px">
           <a class="btn btn-warning btn-block" rel="pick_up_time" data-id="{{@root.id}}" data-time="{{time}}" data-date="{{date}}">{{time}}</a>
        </div>
    {{else}}
	    <div style="text-align: center; ">
	        本日已額滿，請選擇其它日期
	    </div>
    {{/each}}
    </div>
    {{/each}}
</div>
`;
const loadTemplate = `
<div class="loader triangle">
    <svg viewBox="0 0 86 80">
        <path d="M40 65L5.35899 4.99999L74.641 5L40 65Z"/>
    </svg>
</div>
`
class place {
    constructor(name, member_id, role_relationships_id) {
        this.member_id = member_id;
        this.role_relationships_id = role_relationships_id;
        this.level_price = 0;
        this.member_name = name;
        this.dates = new Map();
        this.$node = $(`#place_${member_id}`);
    }
    actionInit() {
        return new Promise((resolve, _reject) => {
        	fetch('https://pzsc.17fit.com/service-flow-dt',{
        		method : 'POST',
			    headers:{
			      'Content-Type': 'application/x-www-form-urlencoded'
			    },
			    body: new URLSearchParams({
                   member_id: this.member_id, //場點 ID
                    role_relationships_id: this.role_relationships_id, //場地 ID
                    member_name: this.member_name, //場地名稱
                    level_price: this.level_price,
			    })
        	})
			.then(function(response) {
				resolve();
			})
        });
    }
    actionGetDateList() {
        const datePromise = [];
        allowDates.forEach((moment, index) => {
            let date = moment.format(dataFormat);
            datePromise.push(
                fetch('https://pzsc.17fit.com/getServiceProviderDateTimeApi',{
                    method : 'POST',
                    headers:{
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: new URLSearchParams({
                        date: moment.format(dataFormat),
                    })
                }).then( (response) => response.json() ).then( (data) => {
                    this.setDate(date, data);
                })
            );
        });
        return new Promise((resolve, _reject) => {
            Promise.all(datePromise).then((result) => {
                resolve(result);
            });
        });
    }
    setDate(date, data) {
        this.dates.set(date, data);
    }
    load(){
    	return new Promise((resolve, _reject) => {
        this.$node.find('.panel-body').html(Template7.compile(loadTemplate));
		    this.actionInit().then(() => {
		        this.actionGetDateList().then((data) => {
		            this.render();
		            resolve(data)
		        });
		    });
       });
    }
    send(date,time) {
        this.actionInit().then(() => {
            $17.formPost({
                url: "https://pzsc.17fit.com/service-flow-confirm",
                params: {
                    is_cash: 0,
                    selected_day: date,
                    selected_time: time
                },
            });
        });
    }
    render() {
        let data = {
            id: this.member_id,
            list: [],
        };
        allowDates.forEach((moment, index) => {
            let date = moment.format(dataFormat);
            let dateTimes = this.dates.get(date);
            let dateData = {
                title: date,
                times: Array.from(dateTimes.values()),
            };
            dateData.hasTimes = dateData.times.length > 0;
            data.list.push(dateData);
        });
        this.$node.find('.panel-body').html(Template7.compile(dateTemplate)(data));
    }
}
(function () {
    "use strict";
    //$('body').append('<div id="plugin_order_place"></div>')
    providers = providers.filter( item => item.member_id != 0);
    $("body").append(Template7.compile(bodyTemplate)(providers));
    const service = new Map();
    const jobs = [];
    let test_id ;
    providers.forEach((item, index) => {
        service.set( `member_${item.member_id}`, new place(item.member_name, item.member_id, item.role_relationships_id));
        jobs.push( `member_${item.member_id}` );
        test_id = `member_${item.member_id}`
    });
	$('#plugin_order_place').on('click','a[rel="pick_up_time"]' , (e) => {
        $17.swal({
          title: `預約時間 ${e.currentTarget.dataset.date} ${e.currentTarget.dataset.time}`,
          text: '是否要預約？',
          type: 'success',
          }, () => {
	    	const member_id = e.currentTarget.dataset.id
	        const activeService = service.get(`member_${member_id}`);
		    activeService.send(e.currentTarget.dataset.date,e.currentTarget.dataset.time)
        });
    }).on('click','.refresh' , (e) => {
    	const member_id = e.currentTarget.dataset.id
        run( `member_${member_id}` )
    })
	function run( id ) {
		const activeService = service.get(id);
		return activeService.load();
    }
	function doJob(jobs){
		if( jobs.length ){
			run( jobs.shift() ).then(()=>{
				doJob(jobs)
			})
		}
	}
    doJob( jobs )
    //run( test_id )
})();
```