This commit is contained in:
parent
5921c8874d
commit
ab4454320a
2021
logs/app.log
2021
logs/app.log
File diff suppressed because it is too large
Load Diff
25
main.py
25
main.py
|
@ -3,7 +3,7 @@ from fastapi.responses import RedirectResponse
|
|||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from model.database import init_db
|
||||
from routers import index, logins, users, product, profile, jobs
|
||||
from routers import index, logins, users, product, profile, jobs, client
|
||||
|
||||
import logging
|
||||
|
||||
|
@ -12,7 +12,16 @@ import logging
|
|||
init_db()
|
||||
|
||||
# Инициализация приложения
|
||||
app = FastAPI()
|
||||
app = FastAPI(title="API для turboapply",
|
||||
description="🚀 Это кастомное описание для Swagger UI", # ✅ Описание
|
||||
version="1.0.3", # ✅ Версия API
|
||||
# docs_url="/api/v1/documentation/",
|
||||
redoc_url=None,
|
||||
# docs_url=None, # Отключаем дефолтный Swagger
|
||||
openapi_url="/openapi.json",
|
||||
swagger_ui_parameters={"filter": True},
|
||||
# on_startup=[start_workers]
|
||||
)
|
||||
|
||||
# Настройка шаблонов
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
@ -21,14 +30,16 @@ templates = Jinja2Templates(directory="templates")
|
|||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
# Подключение маршрутов
|
||||
app.include_router(index.router, tags=["callback"])
|
||||
app.include_router(logins.router, tags=["login"])
|
||||
app.include_router(users.router, tags=["users"])
|
||||
app.include_router(product.router, tags=["product"])
|
||||
app.include_router(index.router, tags=["callback"], include_in_schema=False)
|
||||
app.include_router(logins.router, tags=["login"], include_in_schema=False)
|
||||
app.include_router(users.router, tags=["users"], include_in_schema=False)
|
||||
app.include_router(product.router, tags=["product"], include_in_schema=False)
|
||||
app.include_router(client.router, tags=["client"])
|
||||
|
||||
|
||||
# Подключение роутеров
|
||||
app.include_router(profile.router, tags=["Profile"])
|
||||
app.include_router(jobs.router, tags=["Jobs"])
|
||||
app.include_router(jobs.router, tags=["Jobs"], include_in_schema=False)
|
||||
|
||||
# Обработка 404
|
||||
@app.exception_handler(404)
|
||||
|
|
|
@ -126,16 +126,33 @@ class Client(Base):
|
|||
__tablename__ = "client"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
username = Column(String(55), unique=True, index=True, nullable=False) # ✅ Правильно
|
||||
phone = Column(String(55), unique=True, index=True, nullable=True) # ✅ Правильно
|
||||
email = Column(String(55), unique=True, index=True, nullable=True) # ✅ Правильно
|
||||
link = Column(String(2083), nullable=True) # URL вакансии
|
||||
is_active = Column(Boolean, default=True)
|
||||
user_login = Column(String(55), unique=True, index=True, nullable=False) # ✅ Правильно
|
||||
user_nicename = Column(String(55), unique=True, index=True, nullable=True) # ✅ Правильно
|
||||
user_email = Column(String(55), unique=True, index=True, nullable=True) # ✅ Правильно
|
||||
# user_registered = Column(String(2083), nullable=True) # URL вакансии
|
||||
user_status = Column(Boolean, default=True)
|
||||
|
||||
# Связь с AppliedJobs (заявки на вакансии)
|
||||
applications = relationship("AppliedJob", back_populates="client")
|
||||
|
||||
class MetaClient(Base):
|
||||
__tablename__ = "meta_client"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey("client.id"), nullable=False)
|
||||
meta_key = Column(String(255), nullable=False)
|
||||
meta_value = Column(Text, nullable=True)
|
||||
|
||||
# Связь с Client
|
||||
client = relationship("Client", back_populates="meta")
|
||||
|
||||
# Добавляем обратную связь в Client
|
||||
Client.meta = relationship("MetaClient", back_populates="client", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class AppliedJob(Base):
|
||||
__tablename__ = "applied_jobs"
|
||||
|
||||
|
@ -151,3 +168,6 @@ class AppliedJob(Base):
|
|||
job = relationship("Job", back_populates="applications")
|
||||
users = relationship("User", back_populates="applications")
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
from fastapi import FastAPI, HTTPException, APIRouter, Request, Header
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from typing import Dict
|
||||
from pydantic import BaseModel
|
||||
import json
|
||||
|
||||
router = APIRouter()
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
API_KEY = "4545454"
|
||||
|
||||
# Пример данных
|
||||
clients = {
|
||||
27: {"username": "John Doe", "email": "john@example.com", "phone": "+123456781"},
|
||||
44: {"username": "Jane Smith", "email": "jane@example.com", "phone": "+987654321"}
|
||||
}
|
||||
@router.get("/get_client/{client_id}", include_in_schema=False)
|
||||
async def get_client_modal(client_id: int):
|
||||
client = clients.get(client_id) # Используй clients вместо clients_db
|
||||
if not client:
|
||||
raise HTTPException(status_code=404, detail="Client not found")
|
||||
return JSONResponse(content=client)
|
||||
|
||||
class JsonData(BaseModel):
|
||||
json_data: str
|
||||
|
||||
@router.post("/client/")
|
||||
async def client(data: JsonData, x_api_key: str = Header(None)):
|
||||
# Проверяем API-ключ
|
||||
if x_api_key != "4545454":
|
||||
raise HTTPException(status_code=403, detail="Invalid API Key")
|
||||
|
||||
try:
|
||||
parsed_data = json.loads(data.json_data) # Декодируем JSON
|
||||
print("Полученные данные:", parsed_data)
|
||||
return {"message": "JSON получен", "data": parsed_data}
|
||||
except json.JSONDecodeError as e:
|
||||
raise HTTPException(status_code=400, detail=f"Invalid JSON: {str(e)}")
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
function updateStatus(selectElement, jobId) {
|
||||
let selectedStatus = selectElement.value;
|
||||
|
||||
fetch('/update_status/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
job_id: jobId,
|
||||
status: selectedStatus
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Успешно обновлено:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateAssignee(selectElement, jobId) {
|
||||
let selectedUserId = selectElement.value;
|
||||
|
||||
fetch('/update_assignee/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
job_id: jobId,
|
||||
assignee_id: selectedUserId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Успешно обновлено:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
|
||||
<!-- Модальное окно ×-->
|
||||
|
||||
|
||||
<!-- Модальное окно ×-->
|
||||
<div id="client-modal" class="fixed inset-0 hidden bg-gray-800 bg-opacity-75 flex items-center justify-center z-50">
|
||||
<div class="bg-white rounded-lg p-6 w-1/3 relative shadow-2xl">
|
||||
<span id="close-modal" class="absolute top-2 right-4 text-xl cursor-pointer"></span>
|
||||
<h2 class="modal__content">Client Details</h2>
|
||||
<div class="post intro-y overflow-hidden box mt-5">
|
||||
<div class="post__tabs nav-tabs flex flex-col sm:flex-row bg-gray-200 text-gray-600">
|
||||
<a title="Main" data-toggle="tab" data-target="#content" href="javascript:;" class="tooltip w-full sm:w-40 py-4 text-center flex justify-center items-center active"> <i data-feather="file-text" class="w-4 h-4 mr-2"></i> Main </a>
|
||||
<a title="Profile" data-toggle="tab" data-target="#prom" href="javascript:;" class="tooltip w-full sm:w-40 py-4 text-center flex justify-center items-center"> <i data-feather="code" class="w-4 h-4 mr-2"></i> Profile </a>
|
||||
<a title="Knowledge Base" data-toggle="tab" data-target="#rozetka" href="javascript:;" class="tooltip w-full sm:w-40 py-4 text-center flex justify-center items-center"> <i data-feather="align-left" class="w-4 h-4 mr-2"></i> Knowledge Base </a>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="post__content tab-content">
|
||||
<div class="tab-content__pane p-5 active" id="content">
|
||||
<div class="border border-gray-200 rounded-md p-5 mt-5">
|
||||
|
||||
<p><strong>Name:</strong> <span id="client-name"></span></p>
|
||||
<p><strong>Email:</strong> <span id="client-email"></span></p>
|
||||
<p><strong>Phone:</strong> <span id="client-phone"></span></p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-content__pane p-5 " id="prom">
|
||||
<div class="border border-gray-200 rounded-md p-5 mt-5">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-content__pane p-5" id="rozetka">
|
||||
<div class="border border-gray-200 rounded-md p-5 mt-5">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END: Post Content -->
|
||||
<!-- BEGIN: Post Info -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- JS только для модалки -->
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const modal = document.getElementById("client-modal");
|
||||
const closeModal = document.getElementById("close-modal");
|
||||
|
||||
// Открытие модалки по клику на имя клиента
|
||||
document.querySelectorAll(".client-link").forEach(link => {
|
||||
link.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
const clientId = link.getAttribute("data-client-id");
|
||||
|
||||
fetch(`/get_client/${clientId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.getElementById("client-name").textContent = data.username;
|
||||
document.getElementById("client-email").textContent = data.email;
|
||||
document.getElementById("client-phone").textContent = data.phone;
|
||||
modal.classList.remove("hidden");
|
||||
})
|
||||
.catch(err => console.error("Error fetching client data:", err));
|
||||
});
|
||||
});
|
||||
|
||||
// Закрытие модалки
|
||||
closeModal.addEventListener("click", () => {
|
||||
modal.classList.add("hidden");
|
||||
});
|
||||
|
||||
// Закрытие по клику вне модалки
|
||||
modal.addEventListener("click", (e) => {
|
||||
if (e.target === modal) {
|
||||
modal.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -35,7 +35,12 @@
|
|||
<div class="text-gray-600 text-xs whitespace-no-wrap">{{ job.job.job_id }}</div>
|
||||
</td>
|
||||
<td class="text-center border-b">Company</td>
|
||||
<td class="text-center border-b">{{job.client.username}}</td>
|
||||
<td class="text-center border-b">
|
||||
|
||||
<a href="#" class="client-link text-blue-500" data-client-id="{{ job.client.id }}">{{ job.client.user_nicename }}</a>
|
||||
|
||||
</td>
|
||||
|
||||
<td class="text-center border-b">Requested on</td>
|
||||
<td class="text-center border-b">Posted on</td>
|
||||
<td class="text-center border-b">
|
||||
|
@ -66,52 +71,9 @@
|
|||
</table>
|
||||
</div>
|
||||
<!-- END: Datatable -->
|
||||
<!-- Включаем модалку -->
|
||||
<!-- Модальное окно -->
|
||||
{% include "modal.html" %}
|
||||
<script src="/static/dist/js/prod.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
function updateStatus(selectElement, jobId) {
|
||||
let selectedStatus = selectElement.value;
|
||||
|
||||
fetch('/update_status/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
job_id: jobId,
|
||||
status: selectedStatus
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Успешно обновлено:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateAssignee(selectElement, jobId) {
|
||||
let selectedUserId = selectElement.value;
|
||||
|
||||
fetch('/update_assignee/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
job_id: jobId,
|
||||
assignee_id: selectedUserId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Успешно обновлено:', data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue