2024-11-06 15:27:33 +03:00

475 lines
16 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script>
import { browser } from "$app/environment";
import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth.js";
import { makePost } from "$lib/tools/requests/requests.js";
import { sayError } from "$lib/tools/toaster/Toaster.js";
import { redirect } from "$lib/tools/url/URLTools.js";
import Pagination from "$lib/ui-components/pagination.svelte";
export let data;
let { userData } = data;
let { token } = data;
let userInfoReloading = false;
const orderStatusMap = {
"1": "Ожидает исполнения",
"2": "Время заявки истекло",
"3": "Исполнена",
};
async function deleteUser() {
const result = await makePost(
"deleteUser",
{
token: token,
},
makeAuthHeaderForAxios(getAuthInfo()?.a)
);
if (result.status === 401) {
sayError("Данные авторизации устарели");
// window.location.href = "/";
redirect("/admin/");
return;
}
if (result.error) {
sayError("Не удалось удалить пользователя");
return;
}
redirect("/admin/userslist");
}
async function reloadUserInfo() {
userInfoReloading = true;
const userResult = await makePost(
"getUser",
{
token: token,
},
makeAuthHeaderForAxios(getAuthInfo()?.a)
);
if (userResult.status === 401) {
userInfoReloading = false;
sayError("Данные авторизации устарели");
redirect("/admin/");
return;
}
if (userResult.error) {
userInfoReloading = false;
sayError("Не удалось настроить пользователя");
return;
}
userData = userResult.data;
userInfoReloading = false;
}
let userOrders = [];
let numPagesUserOrders = 1;
let currentPageUserOrders = 1;
let disablePagesUserOrders = false;
let ordersFilter = "1";
async function getUserOrders() {
disablePagesUserOrders = true;
const result = await makePost(
"admin/getUserOrders",
{
token: token,
page: currentPageUserOrders,
// orderBy: "id",
statuses_to_send: Number(ordersFilter),
},
makeAuthHeaderForAxios(getAuthInfo()?.a)
);
if (result.status === 401) {
sayError("Данные авторизации устарели");
// window.location.href = "/";
redirect("/admin/");
disablePagesUserOrders = false;
return;
}
if (result.error) {
sayError("Не удалось получить ордеры пользователя");
disablePagesUserOrders = false;
return;
}
userOrders = result.data.data;
if(!Array.isArray(userOrders)) userOrders = [];
numPagesUserOrders = Number(result.data?.pages);
if (numPagesUserOrders === 0) numPagesUserOrders = 1;
console.log(result.data);
disablePagesUserOrders = false;
}
let reqsCurrentPage = 1;
let reqsMaxPage = 1;
let userRequisites = [];
async function getUserRequisites() {
const result = await makePost(
"admin/getRequisite",
{
page: Number(reqsCurrentPage),
token: token,
},
makeAuthHeaderForAxios(getAuthInfo()?.a)
);
if (result.status === 401) {
sayError("Данные авторизации устарели");
redirect("/admin/");
return;
}
if (result.error) {
sayError("Не удалось получить реквизиты пользователя");
return;
}
userRequisites = result.data.data;
if(!Array.isArray(userDeposits)) userRequisites = [];
reqsMaxPage = Number(result.data.pages);
console.log(result.data);
}
let userDeposits = [];
let numOfPagesUserDeposits = 1;
let currentPageUserDeposits = 1;
let disablePagesUserDeposits = false;
const depoStatusMap = {
"0": "Активна",
"1": "Завершена",
"2": "Отклонена"
};
///api/v1/admin/getUserDeposits
async function getUserDeposits() {
disablePagesUserDeposits = true;
const result = await makePost(
"admin/getUserDeposits",
{
token: token,
page: 1,
},
makeAuthHeaderForAxios(getAuthInfo()?.a)
);
if (result.status === 401) {
sayError("Данные авторизации устарели");
redirect("/admin/");
disablePagesUserDeposits = false;
return;
}
if (result.error) {
sayError("Не удалось получить депозиты пользователя");
disablePagesUserDeposits = false;
return;
}
userDeposits = result.data.deposits;
if(!Array.isArray(userDeposits)) userDeposits = [];
numPagesUserOrders = result.data.pages;
disablePagesUserDeposits = false;
// console.log(result.data, 'depos');
}
$: if(browser || Number(ordersFilter) > -999) getUserOrders();
if (browser) {
getUserOrders();
getUserRequisites();
getUserDeposits();
}
let findFieldValue = "";
let showLoadingFind = false;
let showFoundedOrderWindow = false;
async function findOrder() {
showLoadingFind = true;
const res = await makePost("admin/find", {
}, makeAuthHeaderForAxios(getAuthInfo()?.a));
}
showLoadingFind = false;
const orderTypesMap = {
"card": "Карта",
"sbp": "СБП",
"clearing_account": "По номеру счёта"
}
</script>
<div class="w-full flex flex-col gap-8">
<div class="flex gap-4">
<div class="bg-accent rounded-[4px] w-[10px] h-full"></div>
<h1 class="text-2xl font-semibold">Информация о пользователе</h1>
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300">
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Токен:</p>
<p class="text-info">{token}</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Имя и фамилия:</p>
<p class="text-info">{userData.name} {userData.surname}</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Валюта:</p>
<p class="text-info">{userData?.code}</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Баланс:</p>
<p class="text-info">{Number(userData.balance)/1e6} USDT</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Заморожено:</p>
<p class="text-info">{userData?.insurance} USDT</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Ставка:</p>
<p class="text-info">{userData.bid} %</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Ставка на выплаты:</p>
<p class="text-info">{userData.payout_bid} %</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg flex-wrap">
<p class="font-bold">Кошелёк пополнения:</p>
<p class="text-info text-sm">{userData.deposit_address}</p>
</div>
<div class="flex gap-2 p-2 items-center text-lg">
<p class="font-bold">Торговля:</p>
<p class={userData["can_trade"] === "t" ? "text-primary" : "text-error"}>
{userData["can_trade"] === "t" ? "Активна" : "Отключена"}
</p>
</div>
<div class="w-full flex gap-4 mt-8">
<button
class="btn btn-neutral w-[100px]"
on:click={() => {
reloadUserInfo();
}}
disabled={userInfoReloading}
>
{#if !userInfoReloading}
{"Обновить"}
{:else}
<span class="loading loading-spinner"></span>
{/if}
</button>
<a
href={window.location.pathname.replace("profile", "change")}
class="btn btn-info">Изменить</a
>
<button
on:click={() => {
deleteUser();
}}
class="btn btn-error ml-auto">Удалить</button
>
</div>
</div>
<div class="flex items-center gap-4">
<div class="bg-accent rounded-[4px] w-[10px] h-full"></div>
<h1 class="text-2xl font-semibold">Реквизиты пользователя</h1>
<button disabled class="btn btn-accent">Добавить реквизит</button>
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300">
<div class="w-full flex flex-col justify-center items-center">
<Pagination
totalPages={reqsMaxPage}
pageChangedCallback={(n) => {
reqsCurrentPage = n;
getUserRequisites();
}}
disableButtons={false}
css={"btn-neutral mt-2"}
/>
<p class="opacity-50 text-xs mt-1">Всего страниц: {reqsMaxPage}</p>
</div>
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300">
<div class="overflow-x-auto mt-4">
<table class="table">
<!-- head -->
<thead>
<tr>
<th>ID</th>
<th>Статус</th>
<th>Банк</th>
<th>СБП</th>
<th>Карта</th>
<th>Телефон</th>
<th>Имя</th>
<th>Девайс</th>
<th>Объем {userData.code}</th>
<th>Лимит {userData.code}</th>
<th>Опции</th>
<!-- <th></th> -->
</tr>
</thead>
<tbody>
{#each userRequisites as requisite}
<tr class="hover:bg-neutral group">
<td class="font-semibold">{requisite["id"]}</td>
<td class=""
>{requisite["status"] === "t" ? "активен" : "отключен"}</td
>
<td>{requisite["bank_name"]}</td>
<td>{requisite["is_sbp"] === "t" ? "да" : "нет"}</td>
<td>{requisite["cardnumber"]}</td>
<td>{requisite["phone"]}</td>
<td>{requisite["name"]}</td>
<td>{requisite["device_uuid"]}</td>
<td>{requisite["daily_volume"]}</td>
<td>{requisite["daily_volume_limit"]}</td>
<td class="flex gap-2">
<a
href={"/admin/user/edit/req/" + token + "/" + requisite["id"] + "_" + userData.code}
class="btn btn-info">Изменить</a
>
<button class="btn btn-error">Удалить</button>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
<!-- <div class="flex gap-4">
<div class="bg-accent rounded-[4px] w-[10px] h-full"></div>
<h1 class="text-2xl font-semibold">Девайсы пользователя</h1>
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300"></div> -->
<div class="flex items-center gap-4">
<div class="bg-accent rounded-[4px] w-[10px] h-full"></div>
<h1 class="text-2xl font-semibold">Текущие заявки</h1>
<!-- <button href={"/user/neworder/"+token} disabled class="btn btn-accent">Добавить заявку</button> -->
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300">
<div class="w-full flex flex-col justify-center items-center">
<!-- <div class="flex items-center gap-2">
<input bind:value={findFieldValue} type="text" class="input input-bordered">
<button on:click={()=>{showFoundedOrderWindow = true;}} class="btn btn-outline">Найти</button>
</div> -->
<Pagination
totalPages={numPagesUserOrders}
pageChangedCallback={(n) => {
currentPageUserOrders = n;
getUserOrders();
}}
disableButtons={disablePagesUserOrders}
css={"btn-neutral mt-2"}
/>
<p class="opacity-50 text-xs mt-1">Всего страниц: {numPagesUserOrders}</p>
<select
bind:value={ordersFilter}
class="select select-bordered min-w-[230px] mt-2"
>
<!-- <option value="-1"> Все выплаты </option> -->
<option value="1"> {orderStatusMap["1"]} </option>
<option value="2"> {orderStatusMap["2"]} </option>
<option value="3"> {orderStatusMap["3"]} </option>
</select>
</div>
<div class="overflow-x-auto mt-4">
<table class="table">
<!-- head -->
<thead>
<tr>
<!-- <th>ID заявки</th> -->
<th>UUID</th>
<th>ID клиента</th>
<th>Статус</th>
<th>Сумма</th>
<th>Тип заявки</th>
<!-- <th>Курс</th> -->
<!-- <th>Название реквизита</th> -->
<!-- <th>СБП</th> -->
<th>Мерчант</th>
<th>Время создания</th>
<th>Время закрытия</th>
<!-- <th>Опции</th> -->
<!-- <th></th> -->
</tr>
</thead>
<tbody>
{#each userOrders as order}
<tr class="hover:bg-neutral group">
<!-- <td class="font-semibold">{order["id"]}</td> -->
<td class="font-semibold">{order["uuid"]}</td>
<td class="font-semibold">{order["external_user_id"]}</td>
<td class="">{order["status"]}</td>
<td>{order["summa"]} {userData?.code}</td>
<td>{orderTypesMap[order["order_type"]]}</td>
<!-- <td>{order["rate"]} {userData?.code}</td> -->
<!-- <td>{order["is_sbp"] === "t" ? "да" : "нет"}</td> -->
<td>{order["merchant"]}</td>
<td>{order["creation_time"]}</td>
<td>{order["closetime"]}</td>
<!-- <td>
<button class="btn btn-outline">Закрыть ручками</button>
</td> -->
<!-- <td class="flex gap-2">
<a href="" class="btn btn-info">Изменить</a>
<button class="btn btn-error">Удалить</button>
</td> -->
</tr>
{/each}
</tbody>
</table>
</div>
</div>
<div class="flex gap-4">
<div class="bg-accent rounded-[4px] w-[10px] h-full"></div>
<h1 class="text-2xl font-semibold">Заявки на пополнение</h1>
</div>
<div class="w-full flex flex-col p-4 rounded-box bg-base-300">
<div class="w-full flex flex-col justify-center items-center">
<Pagination
totalPages={numOfPagesUserDeposits}
pageChangedCallback={(n) => {
currentPageUserDeposits = n;
getUserDeposits();
}}
disableButtons={disablePagesUserDeposits}
css={"btn-neutral"}
/>
<p class="opacity-50 text-xs mt-1">
Всего страниц: {numOfPagesUserDeposits}
</p>
</div>
<div class="overflow-x-auto mt-4">
<table class="table">
<!-- head -->
<thead>
<tr>
<th>Статус</th>
<th>Сумма</th>
<th>Время создания</th>
<!-- <th>Опции</th> -->
<!-- <th></th> -->
</tr>
</thead>
<tbody>
{#each userDeposits as depo}
<tr class="hover:bg-neutral group">
<td class="">{depoStatusMap[depo["pending"]]}</td>
<td>{Number(depo["amount"])/1e6} USDT</td>
<td>{depo["creationtime"]}</td>
<!-- <td class="flex gap-2">
<a href="" class="btn btn-info">Изменить</a>
<button class="btn btn-error">Удалить</button>
</td> -->
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>
<!-- {#if showFoundedOrderWindow}
<div class="fixed z-[1000] inset-0 flex justify-center items-center bg-black bg-opacity-50">
<div class="bg-base-100 rounded-md p-4 flex flex-col">
<button class="btn btn-outline" on:click={()=>{showFoundedOrderWindow = false;}}>Закрыть</button>
<button class="btn btn-outline" on:click={()=>{showFoundedOrderWindow = false;}}>Закрыть</button>
</div>
</div>
{/if} -->