Files
ai-ticket-platform/backend/apps/tickets/models.py
2026-07-03 16:17:32 +08:00

151 lines
5.1 KiB
Python

from django.conf import settings
from django.db import models
class TicketStatus(models.TextChoices):
PENDING_INFO = "pending_info", "Pending info"
PENDING = "pending", "Pending"
IN_PROGRESS = "in_progress", "In progress"
PENDING_CONFIRM = "pending_confirm", "Pending confirm"
RESOLVED = "resolved", "Resolved"
CLOSED = "closed", "Closed"
class TicketPriority(models.TextChoices):
LOW = "low", "Low"
MEDIUM = "medium", "Medium"
HIGH = "high", "High"
URGENT = "urgent", "Urgent"
class TicketCategory(models.Model):
parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=120)
code = models.CharField(max_length=80, unique=True)
description = models.TextField(blank=True)
enabled = models.BooleanField(default=True)
sort_order = models.PositiveIntegerField(default=0)
class Meta:
ordering = ["sort_order", "name"]
def __str__(self) -> str:
return self.name
class Ticket(models.Model):
ticket_no = models.CharField(max_length=32, unique=True)
title = models.CharField(max_length=200)
description = models.TextField()
category = models.ForeignKey(TicketCategory, null=True, blank=True, on_delete=models.SET_NULL)
status = models.CharField(
max_length=32,
choices=TicketStatus.choices,
default=TicketStatus.PENDING,
)
priority = models.CharField(
max_length=20,
choices=TicketPriority.choices,
default=TicketPriority.MEDIUM,
)
problem_performance = models.TextField(blank=True)
problem_object = models.CharField(max_length=160, blank=True)
submitter_name = models.CharField(max_length=80, blank=True)
submitter_org = models.CharField(max_length=160, blank=True)
ai_solution = models.TextField(blank=True)
resolution_summary = models.TextField(blank=True)
is_resolved = models.BooleanField(default=False)
replied_to_customer = models.BooleanField(default=False)
impact_scope = models.CharField(max_length=80, blank=True)
environment = models.CharField(max_length=80, blank=True)
related_system = models.CharField(max_length=120, blank=True)
requester = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="requested_tickets",
)
assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="assigned_tickets",
)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="created_tickets",
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
resolved_at = models.DateTimeField(null=True, blank=True)
closed_at = models.DateTimeField(null=True, blank=True)
class Meta:
ordering = ["-created_at"]
indexes = [
models.Index(fields=["ticket_no"]),
models.Index(fields=["status", "priority"]),
models.Index(fields=["created_at"]),
]
def __str__(self) -> str:
return f"{self.ticket_no} {self.title}"
class TicketComment(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name="comments")
content = models.TextField()
comment_type = models.CharField(max_length=40, default="user")
visibility = models.CharField(max_length=40, default="internal")
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["created_at"]
class TicketAttachment(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name="attachments")
file_name = models.CharField(max_length=255)
file_type = models.CharField(max_length=80, blank=True)
mime_type = models.CharField(max_length=120, blank=True)
file_size = models.PositiveBigIntegerField(default=0)
storage_path = models.CharField(max_length=500)
ocr_text = models.TextField(blank=True)
parsed_text = models.TextField(blank=True)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
)
created_at = models.DateTimeField(auto_now_add=True)
class TicketEvent(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name="events")
event_type = models.CharField(max_length=80)
from_value = models.JSONField(default=dict, blank=True)
to_value = models.JSONField(default=dict, blank=True)
operator = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
)
remark = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["created_at"]