305 lines
9.6 KiB
Svelte
305 lines
9.6 KiB
Svelte
<script>
|
||
import { getAuthInfo, makeAuthHeaderForAxios } from "$lib/auth/Auth";
|
||
import { makePost } from "$lib/tools/requests/requests";
|
||
import { sayError, sayInfo } from "$lib/tools/toaster/Toaster";
|
||
import Pagination from "$lib/ui-components/pagination.svelte";
|
||
import { redirect } from "$lib/tools/url/URLTools";
|
||
import axios from "axios";
|
||
|
||
const disputesStatusMap = {
|
||
"4": "Требует проверки",
|
||
"5": "На проверке у трейдера",
|
||
"6": "Принят",
|
||
"7": "Отклонён",
|
||
};
|
||
|
||
const disputesStatusMapColors = {
|
||
"4": "text-white",
|
||
"5": "text-warning",
|
||
"6": "text-primary",
|
||
"7": "text-error",
|
||
};
|
||
|
||
//admin/getDisputes
|
||
let disputes = [];
|
||
let numOfPagesDisputes = 1;
|
||
let currentPageDisputes = 1;
|
||
let disablePagesDisputes = false;
|
||
|
||
async function getDisputes() {
|
||
disablePagesDisputes = true;
|
||
const result = await makePost(
|
||
"admin/getDisputes",
|
||
{
|
||
page: 1,
|
||
},
|
||
makeAuthHeaderForAxios(getAuthInfo()?.a)
|
||
);
|
||
console.log(result);
|
||
if (result.status === 401) {
|
||
sayError("Данные авторизации устарели");
|
||
redirect("/");
|
||
disablePagesDisputes = false;
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
if (result.error) {
|
||
sayError("Не удалось получить депозиты пользователя");
|
||
disablePagesDisputes = false;
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
disputes = result.data.disputes;
|
||
numOfPagesDisputes = result.data.pages;
|
||
disablePagesDisputes = false;
|
||
}
|
||
getDisputes();
|
||
|
||
let selectedDispute = {
|
||
amount: "",
|
||
is_sbp: "",
|
||
name: "",
|
||
order_creationtime: "",
|
||
order_id: "",
|
||
order_rate: "",
|
||
order_requisites_id: "",
|
||
order_status: "",
|
||
receipt: "",
|
||
requisite_cardnumber: "",
|
||
requisite_phone: "",
|
||
};
|
||
let showFullInfo = false;
|
||
|
||
async function acceptDispute() {
|
||
//admin/changeDispute
|
||
const result = await makePost(
|
||
"admin/changeDispute",
|
||
{
|
||
action: 1,
|
||
order_id: selectedDispute.order_id,
|
||
},
|
||
makeAuthHeaderForAxios(getAuthInfo()?.a)
|
||
);
|
||
console.log(result);
|
||
if (result.status === 401) {
|
||
sayError("Данные авторизации устарели");
|
||
redirect("/");
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
if (result.error) {
|
||
sayError("Не удалось принять спор");
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
sayInfo("Спор одобрен!");
|
||
showFullInfo = false;
|
||
getDisputes();
|
||
}
|
||
|
||
async function rejectDispute() {
|
||
const result = await makePost(
|
||
"admin/changeDispute",
|
||
{
|
||
action: 2,
|
||
order_id: selectedDispute.order_id,
|
||
},
|
||
makeAuthHeaderForAxios(getAuthInfo()?.a)
|
||
);
|
||
console.log(result);
|
||
if (result.status === 401) {
|
||
sayError("Данные авторизации устарели");
|
||
redirect("/");
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
if (result.error) {
|
||
sayError("Не удалось отклонить спор");
|
||
// disablePagesUserDeposits = false;
|
||
return;
|
||
}
|
||
sayInfo("Спор отклонён!");
|
||
showFullInfo = false;
|
||
getDisputes();
|
||
}
|
||
|
||
function mimeToExtension(mimeType) {
|
||
const mimeTypes = {
|
||
"application/pdf": "pdf",
|
||
"application/zip": "zip",
|
||
"image/jpeg": "jpg",
|
||
"image/jpg": "jpg",
|
||
"image/png": "png",
|
||
"text/plain": "txt",
|
||
"application/msword": "doc",
|
||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
||
"docx",
|
||
// Добавьте дополнительные MIME-типы по необходимости
|
||
};
|
||
return mimeTypes[mimeType] || "bin"; // Если тип неизвестен, возвращаем .bin
|
||
}
|
||
</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 bg-base-300 p-4 rounded-box">
|
||
<div class="w-full flex flex-col justify-center items-center">
|
||
<Pagination
|
||
totalPages={numOfPagesDisputes}
|
||
pageChangedCallback={(n) => {
|
||
currentPageDisputes = n;
|
||
getDisputes();
|
||
}}
|
||
disableButtons={disablePagesDisputes}
|
||
css={"btn-neutral"}
|
||
/>
|
||
<p class="opacity-50 text-xs mt-1">
|
||
Всего страниц: {numOfPagesDisputes}
|
||
</p>
|
||
</div>
|
||
<div class="overflow-x-auto mt-4 flex flex-col">
|
||
{#if !disablePagesDisputes}
|
||
<table class="table">
|
||
<!-- head -->
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Статус</th>
|
||
<th>СБП</th>
|
||
<th>Карта</th>
|
||
<th>Телефон</th>
|
||
<th>Курс</th>
|
||
<th>Сумма</th>
|
||
<th>Время создания</th>
|
||
<th>Опции</th>
|
||
<!-- <th></th> -->
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{#each disputes as dispute}
|
||
<tr class="hover:bg-neutral group">
|
||
<td class="font-semibold">{dispute["order_id"]}</td>
|
||
<td class={disputesStatusMapColors[dispute["order_status"]]}
|
||
>{disputesStatusMap[dispute["order_status"]]}</td
|
||
>
|
||
<td>{dispute["is_sbp"] === "t" ? "да" : "нет"}</td>
|
||
<td>{dispute["requisite_cardnumber"]}</td>
|
||
<td>{dispute["requisite_phone"]}</td>
|
||
<td>{dispute["order_rate"]}</td>
|
||
<td>{dispute["amount"]}</td>
|
||
<td>{dispute["order_creationtime"]}</td>
|
||
<td
|
||
on:click={() => {
|
||
selectedDispute = dispute;
|
||
showFullInfo = true;
|
||
}}
|
||
class="flex gap-2"
|
||
>
|
||
<button class="btn btn-info">Подробнее</button>
|
||
</td>
|
||
</tr>
|
||
{/each}
|
||
</tbody>
|
||
</table>
|
||
{:else}
|
||
<span class="loading loading-spinner self-center"></span>
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{#if showFullInfo}
|
||
<div
|
||
class="fixed inset-0 flex justify-center items-center md:p-32 p-8 pt-[68px] bg-black bg-opacity-50"
|
||
>
|
||
<div class="flex flex-col w-full max-w-[600px] p-4 rounded-box bg-base-300">
|
||
<p class="self-center opacity-60">ID: {selectedDispute.order_id}</p>
|
||
<p
|
||
class={"self-center text-3xl " +
|
||
disputesStatusMapColors[selectedDispute["order_status"]]}
|
||
>
|
||
{disputesStatusMap[selectedDispute["order_status"]]}
|
||
</p>
|
||
<p class="self-center opacity-60">{selectedDispute.order_creationtime}</p>
|
||
<div class="rounded-box flex flex-col bg-base-100 p-4 gap-1 mt-4">
|
||
<p class="text-lg font-bold">{selectedDispute.name}</p>
|
||
<p class="">Карта: {selectedDispute.requisite_cardnumber}</p>
|
||
<p class="">Телефон: {selectedDispute.requisite_phone}</p>
|
||
</div>
|
||
<div class="rounded-box flex flex-col bg-base-100 p-4 gap-1 mt-4">
|
||
<p class="text-lg font-bold">Курс</p>
|
||
<p>{selectedDispute.order_rate} RUB</p>
|
||
</div>
|
||
<div class="rounded-box flex flex-col bg-base-100 p-4 gap-1 mt-4">
|
||
<p class="text-lg font-bold">Сумма по факту</p>
|
||
<p>
|
||
{Number(selectedDispute.order_rate) * Number(selectedDispute.amount)} RUB
|
||
</p>
|
||
</div>
|
||
{#if selectedDispute["order_status"] === "4"}
|
||
<button
|
||
on:click={() => {
|
||
acceptDispute();
|
||
}}
|
||
class="btn btn-outline btn-primary mt-4"
|
||
>
|
||
Одобрить
|
||
</button>
|
||
<button on:click={() => {}} class="btn btn-outline btn-error mt-1">
|
||
Отклонить
|
||
</button>
|
||
{/if}
|
||
{#if selectedDispute["order_status"] !== "4"}
|
||
<button
|
||
on:click={() => {
|
||
axios
|
||
.get(
|
||
"https://test.0x000f.ru/api/v1/loadFile?dispute=" +
|
||
selectedDispute["order_id"],
|
||
{
|
||
responseType: "blob",
|
||
headers: makeAuthHeaderForAxios(getAuthInfo()?.a).headers,
|
||
}
|
||
)
|
||
.then(function (response) {
|
||
// Создаем ссылку для скачивания
|
||
const url = window.URL.createObjectURL(
|
||
new Blob([response.data])
|
||
);
|
||
const contentType = response?.data?.type; // Извлекаем MIME-тип из Blob
|
||
let extension = mimeToExtension(contentType); // Получаем расширение из функции
|
||
const a = document.createElement("a");
|
||
a.style.display = "none";
|
||
a.href = url;
|
||
a.download = `Чек_${Date.now()}.${extension}`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
|
||
// Очищаем
|
||
window.URL.revokeObjectURL(url);
|
||
document.body.removeChild(a);
|
||
})
|
||
.catch(function (error) {
|
||
console.error("Error:", error);
|
||
});
|
||
}}
|
||
class="btn btn-outline btn-info mt-4"
|
||
>
|
||
Скачать чек
|
||
</button>
|
||
{/if}
|
||
<button
|
||
on:click={() => {
|
||
showFullInfo = false;
|
||
}}
|
||
class="btn btn-outline btn-ghost mt-4"
|
||
>
|
||
Закрыть
|
||
</button>
|
||
</div>
|
||
</div>
|
||
{/if}
|