feat: add admin client policy control

This commit is contained in:
QiuSW
2026-07-28 15:42:23 +08:00
parent 9544aaf4cc
commit 2171968780
17 changed files with 558 additions and 21 deletions
+78
View File
@@ -12,6 +12,84 @@ from django.db.models import Q
from django.utils import timezone
class ClientSubscriptionPolicy(models.Model):
"""The one global policy published to supported cmshopee clients."""
class Mode(models.TextChoices):
OFF = "off", "关闭"
OBSERVE = "observe", "仅检测"
ENFORCE = "enforce", "检测并门禁"
singleton_id = models.PositiveSmallIntegerField(
"固定配置标识",
primary_key=True,
default=1,
editable=False,
)
mode = models.CharField("客户端策略", max_length=16, choices=Mode.choices)
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="最后操作人",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="client_subscription_policy_updates",
)
created_at = models.DateTimeField("创建时间", auto_now_add=True)
updated_at = models.DateTimeField("更新时间", auto_now=True)
class Meta:
db_table = "client_subscription_policy"
verbose_name = "客户端订阅策略"
verbose_name_plural = "客户端订阅策略"
constraints = [
models.CheckConstraint(
condition=Q(singleton_id=1),
name="client_subscription_policy_singleton_only",
),
]
def __str__(self) -> str:
return f"客户端订阅策略:{self.get_mode_display()}"
def save(self, *args, **kwargs):
self.singleton_id = 1
super().save(*args, **kwargs)
class ClientSubscriptionPolicyAudit(models.Model):
policy = models.ForeignKey(
ClientSubscriptionPolicy,
verbose_name="客户端订阅策略",
on_delete=models.PROTECT,
related_name="audits",
)
previous_mode = models.CharField("变更前策略", max_length=16, blank=True)
mode = models.CharField("变更后策略", max_length=16, choices=ClientSubscriptionPolicy.Mode.choices)
reason = models.CharField("变更原因", max_length=255)
changed_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="操作人",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="client_subscription_policy_audits",
)
changed_at = models.DateTimeField("变更时间", auto_now_add=True)
class Meta:
db_table = "client_subscription_policy_audit"
verbose_name = "客户端订阅策略审计"
verbose_name_plural = "客户端订阅策略审计"
ordering = ("-changed_at", "-id")
indexes = [
models.Index(fields=("policy", "changed_at")),
]
def __str__(self) -> str:
return f"{self.policy} {self.previous_mode or '未配置'} -> {self.mode}"
class ClientDevice(models.Model):
class ProductCode(models.TextChoices):
CMSHOPEE = "cmshopee", "虾皮圈优化助手"