| | | 1 | | @{ |
| | 0 | 2 | | ViewData["Title"] = "Список задач"; |
| | | 3 | | } |
| | | 4 | | |
| | | 5 | | <!DOCTYPE html> |
| | | 6 | | <html lang="ru"> |
| | | 7 | | <head> |
| | | 8 | | <meta charset="UTF-8"> |
| | | 9 | | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | 0 | 10 | | <title>@ViewData["Title"]</title> |
| | | 11 | | <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> |
| | | 12 | | <link href="~/css/tree-cards.css" rel="stylesheet" /> |
| | | 13 | | <style> |
| | | 14 | | .container { |
| | | 15 | | display: flex; |
| | | 16 | | width: 100%; |
| | | 17 | | align-items: flex-start; |
| | | 18 | | gap: 20px; |
| | | 19 | | } |
| | | 20 | | |
| | | 21 | | .tasks-table-container { |
| | | 22 | | flex: 0 0 90%; |
| | | 23 | | overflow: auto; |
| | | 24 | | border: 1px solid #000; |
| | | 25 | | } |
| | | 26 | | |
| | | 27 | | .tasks-table { |
| | | 28 | | width: 100%; |
| | | 29 | | border-collapse: collapse; |
| | | 30 | | } |
| | | 31 | | |
| | | 32 | | .tasks-table th, |
| | | 33 | | .tasks-table td { |
| | | 34 | | border: 1px solid #000; |
| | | 35 | | padding: 8px; |
| | | 36 | | text-align: left; |
| | | 37 | | } |
| | | 38 | | |
| | | 39 | | /* Стили для модального окна */ |
| | | 40 | | .modal { |
| | | 41 | | display: none; /* по умолчанию скрыто */ |
| | | 42 | | position: fixed; |
| | | 43 | | z-index: 1000; |
| | | 44 | | left: 0; |
| | | 45 | | top: 0; |
| | | 46 | | width: 100%; |
| | | 47 | | height: 100%; |
| | | 48 | | overflow: auto; |
| | | 49 | | background-color: rgba(0,0,0,0.6); /* затемнение фона */ |
| | | 50 | | } |
| | | 51 | | |
| | | 52 | | .modal-content { |
| | | 53 | | background-color: #fff; |
| | | 54 | | margin: 5% auto; |
| | | 55 | | padding: 20px; |
| | | 56 | | border: 1px solid #000; |
| | | 57 | | overflow-y: auto; |
| | | 58 | | } |
| | | 59 | | |
| | | 60 | | .close-button { |
| | | 61 | | color: #aaa; |
| | | 62 | | float: right; |
| | | 63 | | font-size: 28px; |
| | | 64 | | font-weight: bold; |
| | | 65 | | cursor: pointer; |
| | | 66 | | } |
| | | 67 | | |
| | | 68 | | .close-button:hover, |
| | | 69 | | .close-button:focus { |
| | | 70 | | color: black; |
| | | 71 | | text-decoration: none; |
| | | 72 | | } |
| | | 73 | | </style> |
| | | 74 | | </head> |
| | | 75 | | <body> |
| | | 76 | | <div class="container"> |
| | | 77 | | <div class="tasks-table-container"> |
| | | 78 | | <table class="tasks-table" border="1"> |
| | | 79 | | <thead> |
| | | 80 | | <tr> |
| | | 81 | | <th>ID</th> |
| | | 82 | | <th>Task ID</th> |
| | | 83 | | <th>Mongo ID</th> |
| | | 84 | | <th>Название</th> |
| | | 85 | | <th>Создано</th> |
| | | 86 | | <th>Ozon Client</th> |
| | | 87 | | <th>Последний статус</th> |
| | | 88 | | <th>Время проверки</th> |
| | | 89 | | <th>Действия</th> |
| | | 90 | | </tr> |
| | | 91 | | </thead> |
| | | 92 | | <tbody id="tasksTable"></tbody> |
| | | 93 | | </table> |
| | | 94 | | </div> |
| | | 95 | | |
| | | 96 | | <!-- Модальное окно --> |
| | | 97 | | <div id="taskInfoModal" class="modal"> |
| | | 98 | | <div class="modal-content"> |
| | | 99 | | <span class="close-button">×</span> |
| | | 100 | | <h2>Информация о задаче</h2> |
| | | 101 | | <div id="taskInfoContent"></div> |
| | | 102 | | </div> |
| | | 103 | | </div> |
| | | 104 | | </div> |
| | | 105 | | |
| | | 106 | | <script> |
| | | 107 | | $(document).ready(function () { |
| | | 108 | | fetchTasks(); |
| | | 109 | | }); |
| | | 110 | | |
| | | 111 | | function fetchTasks() { |
| | | 112 | | if (window.SkeletonLoader) SkeletonLoader.table('#tasksTable', { columns: 9, rows: 6 }); |
| | | 113 | | $.ajax({ |
| | | 114 | | url: "https://card-api.interparts.ru/api/tasks", |
| | | 115 | | method: "GET", |
| | | 116 | | dataType: "json", |
| | | 117 | | success: function (response) { |
| | | 118 | | if (!response.error && response.result) { |
| | | 119 | | if (window.SkeletonLoader) SkeletonLoader.finish('#tasksTable'); |
| | | 120 | | const sortedTasks = response.result.sort((a, b) => new Date(b.createTime) - new Date(a.createTim |
| | | 121 | | let rows = ""; |
| | | 122 | | sortedTasks.forEach(task => { |
| | | 123 | | rows += `<tr id="taskRow_${task.id}"> |
| | | 124 | | <td>${task.id}</td> |
| | | 125 | | <td>${task.taskId}</td> |
| | | 126 | | <td>${task.mongoId}</td> |
| | | 127 | | <td>${task.name}</td> |
| | | 128 | | <td>${new Date(task.createTime).toLocaleString()}</td> |
| | | 129 | | <td>${task.ozonClient}</td> |
| | | 130 | | <td id="status_${task.id}">${task.lastStatus}</td> |
| | | 131 | | <td id="checkTime_${task.id}">${new Date(task.checkTime).toLocaleString()}</td> |
| | | 132 | | <td> |
| | | 133 | | <button style="display: block; width: 100%;" onclick="fetchTaskInfo(${task.taskId}, |
| | | 134 | | <button style="display: block; width: 100%; margin-top: 5px;" onclick="deleteTask(${ |
| | | 135 | | </td> |
| | | 136 | | </tr>`; |
| | | 137 | | }); |
| | | 138 | | $("#tasksTable").html(rows); |
| | | 139 | | } else { |
| | | 140 | | if (window.SkeletonLoader) SkeletonLoader.finish('#tasksTable'); |
| | | 141 | | console.error("Ошибка получения списка задач", response.message); |
| | | 142 | | } |
| | | 143 | | }, |
| | | 144 | | error: function (xhr, status, error) { |
| | | 145 | | if (window.SkeletonLoader) SkeletonLoader.finish('#tasksTable'); |
| | | 146 | | $('#tasksTable').html('<tr><td colspan="9" class="text-danger text-center">Не удалось загрузить зада |
| | | 147 | | console.error("Ошибка при запросе списка задач:", error); |
| | | 148 | | } |
| | | 149 | | }); |
| | | 150 | | } |
| | | 151 | | |
| | | 152 | | function fetchTaskInfo(taskId, mongoId, taskRowId) { |
| | | 153 | | let infoHtml = ""; |
| | | 154 | | let latestStatus = "Не указан"; |
| | | 155 | | if (window.SkeletonLoader) { |
| | | 156 | | SkeletonLoader.lines('#taskInfoContent', { count: 8 }); |
| | | 157 | | $('#taskInfoModal').fadeIn(); |
| | | 158 | | } |
| | | 159 | | |
| | | 160 | | $.ajax({ |
| | | 161 | | url: "https://card-api.interparts.ru/api/OzonApi/product/import/info", |
| | | 162 | | method: "POST", |
| | | 163 | | contentType: "application/json", |
| | | 164 | | data: JSON.stringify({ taskId: taskId }), |
| | | 165 | | dataType: "json", |
| | | 166 | | success: function (response) { |
| | | 167 | | if (!response.error && response.result) { |
| | | 168 | | const result = response.result.result; |
| | | 169 | | if (result.items && result.items.length > 0) { |
| | | 170 | | result.items.forEach(item => { |
| | | 171 | | latestStatus = item.status; |
| | | 172 | | infoHtml += `<div><strong>Статус:</strong> ${item.status}</div>`; |
| | | 173 | | if (item.errors && item.errors.length > 0) { |
| | | 174 | | infoHtml += "<div><strong>Ошибки:</strong><ul>"; |
| | | 175 | | item.errors.forEach(error => { |
| | | 176 | | infoHtml += `<li><b>${error.code}</b> / ${error.message}</li>`; |
| | | 177 | | }); |
| | | 178 | | infoHtml += "</ul></div>"; |
| | | 179 | | } |
| | | 180 | | }); |
| | | 181 | | } else { |
| | | 182 | | infoHtml = "Нет данных о задаче."; |
| | | 183 | | } |
| | | 184 | | |
| | | 185 | | $(`#status_${taskRowId}`).text(latestStatus); |
| | | 186 | | $(`#checkTime_${taskRowId}`).text(new Date().toLocaleString()); |
| | | 187 | | } else { |
| | | 188 | | console.error("Ошибка получения информации о задаче", response.message); |
| | | 189 | | infoHtml = "<p>Ошибка получения информации о задаче.</p>"; |
| | | 190 | | } |
| | | 191 | | |
| | | 192 | | fetchJsonData(mongoId, infoHtml); |
| | | 193 | | }, |
| | | 194 | | error: function (xhr, status, error) { |
| | | 195 | | console.error("Ошибка при запросе информации о задаче:", error); |
| | | 196 | | infoHtml = "<p>Ошибка при запросе информации о задаче.</p>"; |
| | | 197 | | fetchJsonData(mongoId, infoHtml); |
| | | 198 | | } |
| | | 199 | | }); |
| | | 200 | | } |
| | | 201 | | |
| | | 202 | | function fetchJsonData(mongoId, infoHtml) { |
| | | 203 | | $.ajax({ |
| | | 204 | | url: `https://card-api.interparts.ru/api/dynamic/CardsData/${mongoId}`, |
| | | 205 | | method: "GET", |
| | | 206 | | dataType: "json", |
| | | 207 | | success: function (jsonResponse) { |
| | | 208 | | if (window.SkeletonLoader) SkeletonLoader.finish('#taskInfoContent'); |
| | | 209 | | const jsonString = JSON.stringify(jsonResponse, null, 2); |
| | | 210 | | infoHtml += `<h3>Данные JSON:</h3> |
| | | 211 | | <textarea id="jsonEditor" style="width:100%; height:500px;">${jsonString}</textarea> |
| | | 212 | | <button onclick="sendEditedJson('${mongoId}')">Отправить</button>`; |
| | | 213 | | $("#taskInfoContent").html(infoHtml); |
| | | 214 | | $("#taskInfoModal").fadeIn(); // Показать модальное окно |
| | | 215 | | }, |
| | | 216 | | error: function (xhr, status, error) { |
| | | 217 | | if (window.SkeletonLoader) SkeletonLoader.finish('#taskInfoContent'); |
| | | 218 | | console.error("Ошибка при получении JSON данных:", error); |
| | | 219 | | infoHtml += "<p>Ошибка загрузки JSON.</p>"; |
| | | 220 | | $("#taskInfoContent").html(infoHtml); |
| | | 221 | | $("#taskInfoModal").fadeIn(); // Показать модальное окно |
| | | 222 | | } |
| | | 223 | | }); |
| | | 224 | | } |
| | | 225 | | |
| | | 226 | | // Обработка закрытия модального окна |
| | | 227 | | $(document).on('click', '.close-button', function () { |
| | | 228 | | $("#taskInfoModal").fadeOut(); |
| | | 229 | | }); |
| | | 230 | | |
| | | 231 | | // Закрытие при клике вне содержимого |
| | | 232 | | $(window).on('click', function (event) { |
| | | 233 | | if ($(event.target).is('#taskInfoModal')) { |
| | | 234 | | $("#taskInfoModal").fadeOut(); |
| | | 235 | | } |
| | | 236 | | }); |
| | | 237 | | |
| | | 238 | | |
| | | 239 | | function sendEditedJson(mongoId) { |
| | | 240 | | const editedJson = $("#jsonEditor").val(); |
| | | 241 | | |
| | | 242 | | try { |
| | | 243 | | const parsedJson = JSON.parse(editedJson); |
| | | 244 | | $.ajax({ |
| | | 245 | | url: `https://card-api.interparts.ru/api/dynamic/CardsData/${mongoId}`, |
| | | 246 | | method: "PUT", |
| | | 247 | | contentType: "application/json", |
| | | 248 | | data: JSON.stringify(parsedJson), |
| | | 249 | | success: function () { |
| | | 250 | | alert("JSON успешно обновлен"); |
| | | 251 | | }, |
| | | 252 | | error: function (xhr, status, error) { |
| | | 253 | | console.error("Ошибка при обновлении JSON:", error); |
| | | 254 | | alert("Ошибка при обновлении JSON"); |
| | | 255 | | } |
| | | 256 | | }); |
| | | 257 | | |
| | | 258 | | $.ajax({ |
| | | 259 | | url: "https://card-api.interparts.ru/api/OzonApi/product-import", |
| | | 260 | | method: "POST", |
| | | 261 | | contentType: "application/json", |
| | | 262 | | data: JSON.stringify(parsedJson), |
| | | 263 | | dataType: "json", |
| | | 264 | | success: function (response) { |
| | | 265 | | console.log("Карточка успешно создана!"); |
| | | 266 | | |
| | | 267 | | const taskData = { |
| | | 268 | | taskId: response.result.result.taskId, |
| | | 269 | | mongoId: mongoId, |
| | | 270 | | name: "Название задачи", |
| | | 271 | | ozonClient: 482702, |
| | | 272 | | lastStatus: "Создан" |
| | | 273 | | }; |
| | | 274 | | |
| | | 275 | | $.ajax({ |
| | | 276 | | url: "https://card-api.interparts.ru/api/tasks", |
| | | 277 | | method: "POST", |
| | | 278 | | contentType: "application/json", |
| | | 279 | | data: JSON.stringify(taskData), |
| | | 280 | | dataType: "json", |
| | | 281 | | success: function (taskResponse) { |
| | | 282 | | console.log("Задача успешно создана:", taskResponse); |
| | | 283 | | location.reload(); |
| | | 284 | | }, |
| | | 285 | | error: function (xhr, status, error) { |
| | | 286 | | console.error("Ошибка при вызове /api/tasks:", error); |
| | | 287 | | } |
| | | 288 | | }); |
| | | 289 | | }, |
| | | 290 | | error: function (xhr, status, error) { |
| | | 291 | | console.error("Ошибка создания карточки:", error); |
| | | 292 | | } |
| | | 293 | | }); |
| | | 294 | | |
| | | 295 | | } catch (e) { |
| | | 296 | | alert("Ошибка: Некорректный JSON"); |
| | | 297 | | } |
| | | 298 | | } |
| | | 299 | | |
| | | 300 | | async function deleteTask(taskId) { |
| | | 301 | | if (!(await St2Dialog.confirm("Вы уверены, что хотите удалить задачу?", { variant: 'danger', confirmText: 'У |
| | | 302 | | return; |
| | | 303 | | } |
| | | 304 | | $.ajax({ |
| | | 305 | | url: `https://card-api.interparts.ru/api/tasks/${taskId}`, |
| | | 306 | | method: "DELETE", |
| | | 307 | | success: function () { |
| | | 308 | | $(`#taskRow_${taskId}`).remove(); |
| | | 309 | | }, |
| | | 310 | | error: function (xhr, status, error) { |
| | | 311 | | console.error("Ошибка удаления задачи:", error); |
| | | 312 | | } |
| | | 313 | | }); |
| | | 314 | | } |
| | | 315 | | </script> |
| | | 316 | | </body> |
| | | 317 | | </html> |