Skip to content

Store

Innerhalb dieser Vue Anwendung wird ein Store-System verwendet. Hierzu wird Pinia genutzt.

Type

Der Type des State sieht so aus. Hier können je nach Kundenanforderung noch Dinge hinzu kommen.

ts
export interface PiniaRootState {
  apiUrlV10: string;
  apiUrlV11: string;
  apiUrlV20: string;
  publisherId: number;
  userId: number;
  authorId: number;
  isAuthenticated: boolean;
  auth: AxiosBasicCredentials;
  seasons: any;
  tournaments: any;
  leagues: any;
  squad: any;
  userRestrictions: any;
  sportTypes: any;
  teamTypes: any;
  regions: any;
  league_hierarchies: any;
  paper_settings: any;
};
export interface PiniaRootState {
  apiUrlV10: string;
  apiUrlV11: string;
  apiUrlV20: string;
  publisherId: number;
  userId: number;
  authorId: number;
  isAuthenticated: boolean;
  auth: AxiosBasicCredentials;
  seasons: any;
  tournaments: any;
  leagues: any;
  squad: any;
  userRestrictions: any;
  sportTypes: any;
  teamTypes: any;
  regions: any;
  league_hierarchies: any;
  paper_settings: any;
};

Definition / Verwendung

In dem PiniaRootState werden alle grundlegenden Daten des Kunden gespeichert. Für die Anfragen an die API-Instanz wird das benötigt: auth { username: "", password: ""}

ts
export const store = defineStore("index", {
  state: (): PiniaRootState => {
    return {
      apiUrlV10: "https://api.deinsportplatz.de/api/v1.0/",
      apiUrlV11: "https://api.deinsportplatz.de/api/v1.1/",
      apiUrlV20: "https://api.deinsportplatz.de/api/v2.0/",
      publisherId: 0,
      userId: 0,
      authorId: 0,
      isAuthenticated: false,
      auth: { username: "dspportal", password: "vryScrP7" },
      seasons: [],
      leagues: [],
      squad: [],
      tournaments: [],
      userRestrictions: [],
      sportTypes: [],
      teamTypes: [],
      regions: [],
      league_hierarchies: [],
      paper_settings: [],
    };
  }
})
export const store = defineStore("index", {
  state: (): PiniaRootState => {
    return {
      apiUrlV10: "https://api.deinsportplatz.de/api/v1.0/",
      apiUrlV11: "https://api.deinsportplatz.de/api/v1.1/",
      apiUrlV20: "https://api.deinsportplatz.de/api/v2.0/",
      publisherId: 0,
      userId: 0,
      authorId: 0,
      isAuthenticated: false,
      auth: { username: "dspportal", password: "vryScrP7" },
      seasons: [],
      leagues: [],
      squad: [],
      tournaments: [],
      userRestrictions: [],
      sportTypes: [],
      teamTypes: [],
      regions: [],
      league_hierarchies: [],
      paper_settings: [],
    };
  }
})

Getter

In dem Store sind die entsprechenden Getter definiert, um die Daten später in anderen Components zuverwenden.

ts
getPublisherId: (state: PiniaRootState) => {
    return state.publisherId;
},
getPublisherId: (state: PiniaRootState) => {
    return state.publisherId;
},

Mutation

In dem State verändern sich durchgehend Daten und Felder. Aus diesem Grund benötigen wir die Mutation des PiniaRootState Eine Mutation verändert immer nur einen Wert des PiniaRootState

ts
// mutations
setPublisherId(id: number) {
    this.publisherId = id;
},
// mutations
setPublisherId(id: number) {
    this.publisherId = id;
},

Action

Die Actions gehören zu den wichtigsten Teil des PiniaRootState. Eine Action kann verschiedene Werte im PiniaRootState verändern. Folgend ist ein Action dargestellt.

ts
userLogin(email: string, password: string, publisherId: number) {
    const config: Object = {
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    auth: this.auth,
    };
    const params = new URLSearchParams();
    params.append("email", email);
    params.append("password", password);
    params.append("publisherId", publisherId.toString());
    const loginUrl = `${this.apiUrlV10}${this.publisherId}/checkUser`;
    axios
    .post(loginUrl, params, config)
    .then((res) => {
        if (res.data.userId) {
        this.isAuthenticated = true;
        this.userId = res.data.userId;
        this.authorId = res.data.authorId;
        this.userRestrictions = res.data.restrictions;
        if (res.data.authorId) {
            router.push("/widget");
        } else {
            router.push("/ticker");
        }
        } else {
        alert("Fehler beim Login!");
        }
    })
    .catch((err) => {
        console.log(err.message);
        this.isAuthenticated = false;
        this.userId = 0;

        this.authorId = 0;
        alert("Fehler beim Login!");
    });
},
userLogin(email: string, password: string, publisherId: number) {
    const config: Object = {
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    auth: this.auth,
    };
    const params = new URLSearchParams();
    params.append("email", email);
    params.append("password", password);
    params.append("publisherId", publisherId.toString());
    const loginUrl = `${this.apiUrlV10}${this.publisherId}/checkUser`;
    axios
    .post(loginUrl, params, config)
    .then((res) => {
        if (res.data.userId) {
        this.isAuthenticated = true;
        this.userId = res.data.userId;
        this.authorId = res.data.authorId;
        this.userRestrictions = res.data.restrictions;
        if (res.data.authorId) {
            router.push("/widget");
        } else {
            router.push("/ticker");
        }
        } else {
        alert("Fehler beim Login!");
        }
    })
    .catch((err) => {
        console.log(err.message);
        this.isAuthenticated = false;
        this.userId = 0;

        this.authorId = 0;
        alert("Fehler beim Login!");
    });
},

Export

Am Ende der Datei wird der Store exportiert, um ihn erreichbar zu machen.

ts
export default store;
export default store;

In den Views und den Components wird der Store wie folgend importiert. (HomeView.vue)

ts
import { store as useStore } from "@/stores";
const store = useStore();
import { store as useStore } from "@/stores";
const store = useStore();

Sonderfunktionen

Verschiedene Abschnitte im neuen Backend erfordern spezifische Anfragen an die API, da sie nicht mit den allgemeinen SQL-Alchemy-Filtern abgedeckt werden können. Für diesen Zweck wurden auf sowohl auf der API-Seite als auch auf der Frontend-Seite, insbesondere im Pinia Store, Methoden implementiert, um die relevanten Daten korrekt darstellen zu können. Hier ist ein Beispiel aus dem Spielkalender.

Die Abfrage beinhaltet eine Array in dem Dict´s mit Liga und den Spielen nach Spieltagen sortiert sind. Der Pfad lautet

ts
const path = `/matches/backend/calendar/${this.publisherId}/${date}`
const path = `/matches/backend/calendar/${this.publisherId}/${date}`

Die Methode im Pinia Store ist folgenden -> retrieveBackendMatchCalendar. Sie ist nur eine von vielen Methoden, welche benötigt wird im Backend. In der deinsportplatz-api finden sich alle Endpunkte welche neu für das Backend angelegt worden unter backend_widget.py. Es gibt sicherlich auch noch andere Endpunkte welche verwendet werden, dies sind nur die Neuen.