diff --git a/src/lib/tools/requests/requests.js b/src/lib/tools/requests/requests.js new file mode 100644 index 0000000..8796f7e --- /dev/null +++ b/src/lib/tools/requests/requests.js @@ -0,0 +1,47 @@ +import axios from "axios"; +import { serializeError } from "serialize-error"; + + +function defaultResponseProcessor(response, dataProcessor) { + return {error: false, data: dataProcessor(response.data), status: response.status}; +} +function defaultErrorProcessor(error) { + return {error: true, data: serializeError(error), status: (error.code === "ERR_NETWORK" ? 502:serializeError(error).status)}; +} +function defaultDataResponseProcessor(data) { + return data; +} + + + +let BasicURLValue = "https://hostapay.trade/api/v1/"; + + + +async function makePost(url, data, options = undefined, + responseProcessor = defaultResponseProcessor, + dataResponseProcessor = defaultDataResponseProcessor, + errorProcessor = defaultErrorProcessor) +{ + try { + const res = await axios.post(BasicURLValue + url, data, options); + return responseProcessor(res, dataResponseProcessor); + } catch (error) { + return errorProcessor(error); + } +} + +async function makeGet(url, options = undefined, + responseProcessor = defaultResponseProcessor, + dataResponseProcessor = defaultDataResponseProcessor, + errorProcessor = defaultErrorProcessor) +{ + try { + const res = await axios.get(BasicURLValue + url, options); + return responseProcessor(res, dataResponseProcessor); + } catch (error) { + return errorProcessor(error); + } +} + +export {BasicURLValue, makePost, makeGet, defaultResponseProcessor, defaultDataResponseProcessor, defaultErrorProcessor}; \ No newline at end of file diff --git a/src/routes/+layout.js b/src/routes/+layout.js new file mode 100644 index 0000000..d2c0be2 --- /dev/null +++ b/src/routes/+layout.js @@ -0,0 +1,2 @@ +export const prerender = true; +export const ssr = false; \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..dda5a54 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,67 @@ + + +{#if loggedIn} +
+ +
+{/if} + +
+
+ +
+
+ + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..bba4aea --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/routes/disputes/+page.svelte b/src/routes/disputes/+page.svelte new file mode 100644 index 0000000..fd545a3 --- /dev/null +++ b/src/routes/disputes/+page.svelte @@ -0,0 +1,342 @@ + + +
+
+
+

Споры

+
+
+
+ +
+
+ { + currentPageDisputes = n; + getDisputes(); + }} + disableButtons={disablePagesDisputes} + css={"btn-neutral"} + /> +

+ Всего страниц: {numOfPagesDisputes} +

+
+
+ {#if !disablePagesDisputes} + + + + + + + + + + + + + + + + + + {#each disputes as dispute} + + + + + + + + + + + + {/each} + +
IDСтатусСБПКартаТелефонКурсСуммаВремя созданияОпции
{dispute["order_id"]}{disputesStatusMap[dispute["order_status"]]}{dispute["is_sbp"] === "t" ? "да" : "нет"}{dispute["requisite_cardnumber"]}{dispute["requisite_phone"]}{dispute["order_rate"]}{dispute["amount"]}{dispute["order_creationtime"]} { + selectedDispute = dispute; + showFullInfo = true; + }} + class="flex gap-2" + > + +
+ {:else} + + {/if} +
+
+
+ +{#if showFullInfo} +
+
+

ID: {selectedDispute.dispute_uuid}

+

+ {disputesStatusMap[selectedDispute["order_status"]]} +

+

{selectedDispute.order_creationtime}

+
+

{selectedDispute.name}

+

Карта: {selectedDispute.requisite_cardnumber}

+

Телефон: {selectedDispute.requisite_phone}

+
+
+

Курс

+

{selectedDispute.order_rate} {selectedDispute.out_code}

+
+
+

Сумма в споре

+

+ {(Number(selectedDispute.new_amount) / Number(selectedDispute.order_rate)).toFixed(2)} {selectedDispute.out_code} ({Number(selectedDispute.new_amount)} USDT) +

+
+
+

Сумма в заявке

+

+ {Number(selectedDispute.order_rate) * Number(selectedDispute.amount)} {selectedDispute.out_code} ({Number(selectedDispute.amount)} USDT) +

+
+ {#if selectedDispute["order_status"] === "4" || selectedDispute["order_status"] === "8"} + + + {/if} + {#if selectedDispute["order_status"] !== "4"} + + {/if} + +
+
+{/if} diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..3f2cd2a --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,118 @@ + + +
+
+

Вход

+ + + + +
+
diff --git a/src/routes/newuser/+page.svelte b/src/routes/newuser/+page.svelte new file mode 100644 index 0000000..ef33088 --- /dev/null +++ b/src/routes/newuser/+page.svelte @@ -0,0 +1,214 @@ + + +
+
+
+

Создание нового пользователя

+
+
+ + + + + + +
+

Торговля:

+ +
+ + {#if userToken !== ""} +
+

+ Токен пользователя: {userToken} +

+
+ {/if} +
+
diff --git a/src/routes/payouts/+page.svelte b/src/routes/payouts/+page.svelte new file mode 100644 index 0000000..788a6f1 --- /dev/null +++ b/src/routes/payouts/+page.svelte @@ -0,0 +1,522 @@ + + +
+
+
+
+
Открыто выплат
+
{numOfOpened}
+ +
+
+
+
+
Принято выплат
+
{numOfAccepted}
+ +
+
+
+
+
Оплачено сегодня
+
{numOfPayed}
+ +
+
+
+
+
Отказов сегодня
+
{numOfCanceled}
+ +
+
+
+
+
+

Выплаты

+
+
+
+ +
+
+ { + currentPagePayouts = n; + getPayouts(); + }} + disableButtons={disablePagesPayouts} + css={"btn-neutral"} + /> +

+ Всего страниц: {numOfPagesPayouts} +

+
+
+ {#if !disablePagesPayouts} + + + + + + + + + + + + + + + + {#each payouts as payout} + + + + + + + + + + + + {/each} + +
IDСтатусСуммаКартаКурсВремя созданияОпции
{payout["uuid"]}{payoutsStatusMap[payout["status"]]}{payout["amount"]} {payout["code"]}{payout["pan"]}{payout["rate"]} {payout["code"]}{payout["creation_time"]} { + selectedPayout = payout; + newPayoutStatus = payout.status; + showFullInfo = true; + }} + class="flex gap-2" + > + +
+ {:else} + + {/if} +
+
+
+ +{#if showFullInfo} +
+
+

ID: {selectedPayout.uuid}

+

+ Выплата {payoutsStatusMap[selectedPayout["status"]]} +

+

{selectedPayout.creation_time}

+
+ +

IP заказчика: {selectedPayout.customer_ip}

+

Карта: {selectedPayout.pan}

+

ID трейдера: {selectedPayout.traider_uuid === "" ? "---":selectedPayout.traider_uuid}

+
+
+

Сумма

+

+ {selectedPayout.amount} + {selectedPayout.code} ({( + Number(selectedPayout.amount) / + Number(selectedPayout.rate) + ).toFixed(2)} USDT) +

+
+
+

Курс

+

{selectedPayout.rate} {selectedPayout.code}

+
+
+

ID нового трейдера:

+

Оставьте пустым, чтобы оставить прежнего трейдера

+ +
+
+

Изменить статус:

+ +
+ {#if selectedPayout["status"] === "2"} + + {/if} + + + +
+
+{/if} diff --git a/src/routes/user/change/[userToken]/+page.js b/src/routes/user/change/[userToken]/+page.js new file mode 100644 index 0000000..361dcdc --- /dev/null +++ b/src/routes/user/change/[userToken]/+page.js @@ -0,0 +1,35 @@ +import { browser } from "$app/environment"; +import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth"; +import { makePost } from "$lib/tools/requests/requests"; +import { sayError } from "$lib/tools/toaster/Toaster"; +import { redirect } from "$lib/tools/url/URLTools"; + +export async function load({ params }) { + if(!browser) return; + const { userToken } = params; + let userResult = await makePost( + "getUser", + { + token: userToken, + }, + makeAuthHeaderForAxios(getAuthInfo()?.a) + ); + if (userResult.status === 401) { + sayError("Данные авторизации устарели"); + // window.location.href = "/"; + redirect("/admin/"); + return {}; + } + if (userResult.error) { + sayError("Не удалось настроить пользователя"); + return {}; + } + userResult["can_trade"] = userResult["can_trade"] === "t" ? true:false; + userResult["can_trade_global"] = userResult["can_trade_global"] === "t" ? true:false; + userResult["balance"] = Number(userResult["balance"]); + userResult["bid"] = Number(userResult["bid"]); + return { + token: userToken, + userData: userResult.data + }; +} \ No newline at end of file diff --git a/src/routes/user/change/[userToken]/+page.svelte b/src/routes/user/change/[userToken]/+page.svelte new file mode 100644 index 0000000..fde8283 --- /dev/null +++ b/src/routes/user/change/[userToken]/+page.svelte @@ -0,0 +1,153 @@ + + +
+
+
+

Изменение информации о пользователе

+
+
+
+ + + + + +
+

Торговля:

+ +
+ + +
+
+
diff --git a/src/routes/user/edit/req/[userToken]/[reqID]/+page.js b/src/routes/user/edit/req/[userToken]/[reqID]/+page.js new file mode 100644 index 0000000..3cede5d --- /dev/null +++ b/src/routes/user/edit/req/[userToken]/[reqID]/+page.js @@ -0,0 +1,16 @@ +import { browser } from "$app/environment"; +import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth"; +import { makePost } from "$lib/tools/requests/requests"; +import { sayError } from "$lib/tools/toaster/Toaster"; + +export async function load({ params }) { + if(!browser) return; + const { userToken } = params; + const { reqID } = params; + let spt = reqID.split("_"); + return { + token: userToken, + reqID: spt[0], + currency: spt[1] + }; +} \ No newline at end of file diff --git a/src/routes/user/edit/req/[userToken]/[reqID]/+page.svelte b/src/routes/user/edit/req/[userToken]/[reqID]/+page.svelte new file mode 100644 index 0000000..885ae18 --- /dev/null +++ b/src/routes/user/edit/req/[userToken]/[reqID]/+page.svelte @@ -0,0 +1,179 @@ + + +
+
+
+

Изменение реквизита (ID: {reqID})

+
+
+ {#each reqInfo as req} + + + + +
+

Активный:

+ +
+ + + {/each} +
+
diff --git a/src/routes/user/neworder/[userToken]/+page.js b/src/routes/user/neworder/[userToken]/+page.js new file mode 100644 index 0000000..2b81760 --- /dev/null +++ b/src/routes/user/neworder/[userToken]/+page.js @@ -0,0 +1,12 @@ +import { browser } from "$app/environment"; +import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth"; +import { makePost } from "$lib/tools/requests/requests"; +import { sayError } from "$lib/tools/toaster/Toaster"; + +export async function load({ params }) { + if(!browser) return; + const { userToken } = params; + return { + token: userToken, + }; +} \ No newline at end of file diff --git a/src/routes/user/neworder/[userToken]/+page.svelte b/src/routes/user/neworder/[userToken]/+page.svelte new file mode 100644 index 0000000..8d57ed0 --- /dev/null +++ b/src/routes/user/neworder/[userToken]/+page.svelte @@ -0,0 +1,49 @@ + + +
+
+
+

Создание заявок

+
+
+ + {#each { length: numOfOrders } as _, index} +
+

Заявка #{index+1}

+ + +
+ {/each} +
+
diff --git a/src/routes/user/profile/[userToken]/+page.js b/src/routes/user/profile/[userToken]/+page.js new file mode 100644 index 0000000..b5f86c8 --- /dev/null +++ b/src/routes/user/profile/[userToken]/+page.js @@ -0,0 +1,31 @@ +import { browser } from "$app/environment"; +import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth"; +import { makePost } from "$lib/tools/requests/requests"; +import { sayError } from "$lib/tools/toaster/Toaster"; +import { redirect } from "$lib/tools/url/URLTools"; + +export async function load({ params }) { + if(!browser) return; + const { userToken } = params; + const userResult = await makePost( + "getUser", + { + token: userToken, + }, + makeAuthHeaderForAxios(getAuthInfo()?.a) + ); + if (userResult.status === 401) { + sayError("Данные авторизации устарели"); + // window.location.href = "/"; + redirect("/admin/"); + return {}; + } + if (userResult.error) { + sayError("Не удалось настроить пользователя"); + return {}; + } + return { + token: userToken, + userData: userResult.data + }; +} diff --git a/src/routes/user/profile/[userToken]/+page.svelte b/src/routes/user/profile/[userToken]/+page.svelte new file mode 100644 index 0000000..86cdbd7 --- /dev/null +++ b/src/routes/user/profile/[userToken]/+page.svelte @@ -0,0 +1,391 @@ + + +
+
+
+

Информация о пользователе

+
+
+
+

Токен:

+

{token}

+
+
+

Имя и фамилия:

+

{userData.name} {userData.surname}

+
+
+

Валюта:

+

{userData?.code}

+
+
+

Баланс:

+

{userData.balance} USDT

+
+
+

Заморожено:

+

{userData?.insurance} USDT

+
+
+

Ставка:

+

{userData.bid} %

+
+
+

Торговля:

+

+ {userData["can_trade"] === "t" ? "Активна" : "Отключена"} +

+
+
+ + Изменить + +
+
+ +
+
+

Реквизиты пользователя

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + {#each userRequisites as requisite} + + + + + + + + + + + + + + {/each} + +
IDСтатусБанкСБПКартаТелефонИмяДевайсОбъем {userData.code}Лимит {userData.code}Опции
{requisite["id"]}{requisite["status"] === "t" ? "активен" : "отключен"}{requisite["bank_name"]}{requisite["is_sbp"] === "t" ? "да" : "нет"}{requisite["cardnumber"]}{requisite["phone"]}{requisite["name"]}{requisite["device_id"]}{requisite["daily_volume"]}{requisite["daily_volume_limit"]} + Изменить + +
+
+
+ + + +
+
+

Текущие заявки

+ +
+
+
+ { + currentPageUserOrders = n; + getUserOrders(); + }} + disableButtons={disablePagesUserOrders} + css={"btn-neutral"} + /> +

Всего страниц: {numPagesUserOrders}

+
+
+ + + + + + + + + + + + + + + + + + {#each userOrders as order} + + + + + + + + + + + + {/each} + +
IDСтатусСуммаКурсСБПМерчантВремя созданияВремя закрытия
{order["id"]}{order["status"]}{order["summa"]} USDT{order["rate"]} RUB{order["is_sbp"] === "t" ? "да" : "нет"}{order["merchant_id"]}{order["creationtime"]}{order["closetime"]}
+
+
+ +
+
+

Заявки на пополнение

+
+
+
+ { + currentPageUserDeposits = n; + getUserDeposits(); + }} + disableButtons={disablePagesUserDeposits} + css={"btn-neutral"} + /> +

+ Всего страниц: {numOfPagesUserDeposits} +

+
+
+ + + + + + + + + + + + + {#each userDeposits as depo} + + + + + + + {/each} + +
СтатусСуммаВремя создания
{depoStatusMap[depo["pending"]]}{depo["amount"]} USDT{depo["creationtime"]}
+
+
+
diff --git a/src/routes/userslist/+page.svelte b/src/routes/userslist/+page.svelte new file mode 100644 index 0000000..d3d6372 --- /dev/null +++ b/src/routes/userslist/+page.svelte @@ -0,0 +1,73 @@ + + +
+
+
+

Все пользователи

+
+
+
+ {#if usersReady} + + + + + + + + + + + + + {#each users as user} + + + + + + + {/each} + +
ТокенИмяБаланс
{user["token"]}{user["name"]} {user["surname"]}{user["balance"]} USDT + Профиль +
+ {:else} +
+ +
+ {/if} +
+
+