add ai models
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
- admin/admin123
|
||||
- chenze/admin123
|
||||
|
||||
演示地址:https://demo.ywwuzi.cn
|
||||
体验地址:https://demo.ywwuzi.cn
|
||||
|
||||
文档地址:https://docs.ywwuzi.cn
|
||||
|
||||
|
||||
@@ -18,4 +18,9 @@ class PlatformChoices(models.TextChoices):
|
||||
ZHIPU = 'ZhiPu', '智谱'
|
||||
MINIMAX = 'MiniMax', 'MiniMax'
|
||||
MOONSHOT = 'Moonshot', '月之暗灭'
|
||||
BAICHUAN = 'BaiChuan', '百川智能'
|
||||
BAICHUAN = 'BaiChuan', '百川智能'
|
||||
|
||||
|
||||
class MessageType(models.TextChoices):
|
||||
USER = 'user', '用户发送'
|
||||
ASSISTANT = 'assistant', '模型回复'
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,262 +0,0 @@
|
||||
# Generated by Django 5.2.1 on 2025-07-10 04:07
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("ai", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="api_key",
|
||||
field=models.CharField(
|
||||
db_comment="密钥", max_length=255, verbose_name="密钥"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="create_time",
|
||||
field=models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
db_comment="创建时间",
|
||||
help_text="创建时间",
|
||||
null=True,
|
||||
verbose_name="创建时间",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="creator",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="创建人",
|
||||
help_text="创建人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="创建人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="is_deleted",
|
||||
field=models.BooleanField(
|
||||
db_comment="是否软删除", default=False, verbose_name="是否软删除"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="modifier",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="修改人",
|
||||
help_text="修改人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="修改人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="name",
|
||||
field=models.CharField(
|
||||
db_comment="名称", max_length=255, verbose_name="名称"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="platform",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("AzureOpenAI", "OpenAI 微软"),
|
||||
("OpenAI", "OpenAI"),
|
||||
("Ollama", "Ollama"),
|
||||
("YiYan", "文心一言"),
|
||||
("XingHuo", "讯飞星火"),
|
||||
("TongYi", "通义千问"),
|
||||
("StableDiffusion", "StableDiffusion"),
|
||||
("Midjourney", "Midjourney"),
|
||||
("Suno", "Suno"),
|
||||
("DeepSeek", "DeepSeek"),
|
||||
("DouBao", "字节豆包"),
|
||||
("HunYuan", "腾讯混元"),
|
||||
("SiliconFlow", "硅基流动"),
|
||||
("ZhiPu", "智谱"),
|
||||
("MiniMax", "MiniMax"),
|
||||
("Moonshot", "月之暗灭"),
|
||||
("BaiChuan", "百川智能"),
|
||||
],
|
||||
db_comment="平台",
|
||||
max_length=100,
|
||||
verbose_name="平台",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="remark",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="备注",
|
||||
help_text="备注",
|
||||
max_length=256,
|
||||
null=True,
|
||||
verbose_name="备注",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="update_time",
|
||||
field=models.DateTimeField(
|
||||
auto_now=True,
|
||||
db_comment="修改时间",
|
||||
help_text="修改时间",
|
||||
null=True,
|
||||
verbose_name="修改时间",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aiapikey",
|
||||
name="url",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="自定义 API 地址",
|
||||
max_length=255,
|
||||
null=True,
|
||||
verbose_name="自定义 API 地址",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="create_time",
|
||||
field=models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
db_comment="创建时间",
|
||||
help_text="创建时间",
|
||||
null=True,
|
||||
verbose_name="创建时间",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="creator",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="创建人",
|
||||
help_text="创建人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="创建人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="is_deleted",
|
||||
field=models.BooleanField(
|
||||
db_comment="是否软删除", default=False, verbose_name="是否软删除"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="key",
|
||||
field=models.ForeignKey(
|
||||
db_comment="API 秘钥编号",
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="ai.aiapikey",
|
||||
verbose_name="API 秘钥编号",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="max_contexts",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
db_comment="上下文的最大 Message 数量",
|
||||
null=True,
|
||||
verbose_name="上下文的最大 Message 数量",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="max_tokens",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
db_comment="单条回复的最大 Token 数量",
|
||||
null=True,
|
||||
verbose_name="单条回复的最大 Token 数量",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="model",
|
||||
field=models.CharField(
|
||||
db_comment="模型标识", max_length=64, verbose_name="模型标识"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="modifier",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="修改人",
|
||||
help_text="修改人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="修改人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="name",
|
||||
field=models.CharField(
|
||||
db_comment="模型名字", max_length=64, verbose_name="模型名字"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="platform",
|
||||
field=models.CharField(
|
||||
db_comment="模型平台", max_length=32, verbose_name="模型平台"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="remark",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="备注",
|
||||
help_text="备注",
|
||||
max_length=256,
|
||||
null=True,
|
||||
verbose_name="备注",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="sort",
|
||||
field=models.IntegerField(
|
||||
db_comment="排序", default=0, verbose_name="排序"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="temperature",
|
||||
field=models.FloatField(
|
||||
blank=True, db_comment="温度参数", null=True, verbose_name="温度参数"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="aimodel",
|
||||
name="update_time",
|
||||
field=models.DateTimeField(
|
||||
auto_now=True,
|
||||
db_comment="修改时间",
|
||||
help_text="修改时间",
|
||||
null=True,
|
||||
verbose_name="修改时间",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -1,105 +0,0 @@
|
||||
# Generated by Django 5.2.1 on 2025-07-11 02:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("ai", "0002_alter_aiapikey_api_key_alter_aiapikey_create_time_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Tool",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"remark",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_comment="备注",
|
||||
help_text="备注",
|
||||
max_length=256,
|
||||
null=True,
|
||||
verbose_name="备注",
|
||||
),
|
||||
),
|
||||
(
|
||||
"creator",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_comment="创建人",
|
||||
help_text="创建人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="创建人",
|
||||
),
|
||||
),
|
||||
(
|
||||
"modifier",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_comment="修改人",
|
||||
help_text="修改人",
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="修改人",
|
||||
),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(
|
||||
auto_now=True,
|
||||
db_comment="修改时间",
|
||||
help_text="修改时间",
|
||||
null=True,
|
||||
verbose_name="修改时间",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
db_comment="创建时间",
|
||||
help_text="创建时间",
|
||||
null=True,
|
||||
verbose_name="创建时间",
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_deleted",
|
||||
models.BooleanField(
|
||||
db_comment="是否软删除",
|
||||
default=False,
|
||||
verbose_name="是否软删除",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=128, verbose_name="工具名称")),
|
||||
(
|
||||
"description",
|
||||
models.CharField(
|
||||
blank=True, max_length=256, null=True, verbose_name="工具描述"
|
||||
),
|
||||
),
|
||||
("status", models.SmallIntegerField(verbose_name="状态")),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "AI 工具",
|
||||
"verbose_name_plural": "AI 工具",
|
||||
"db_table": "ai_tool",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="aimodel",
|
||||
options={"verbose_name": "模型配置", "verbose_name_plural": "模型配置"},
|
||||
),
|
||||
]
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.db import models
|
||||
|
||||
from ai.choices import PlatformChoices
|
||||
from ai.choices import PlatformChoices, MessageType
|
||||
from backend import settings
|
||||
from utils.models import CommonStatus, CoreModel
|
||||
|
||||
class AIApiKey(CoreModel):
|
||||
@@ -63,9 +64,9 @@ class AIModel(CoreModel):
|
||||
|
||||
class Tool(CoreModel):
|
||||
""" AI 工具表 """
|
||||
name = models.CharField(max_length=128, verbose_name="工具名称")
|
||||
description = models.CharField(max_length=256, null=True, blank=True, verbose_name="工具描述")
|
||||
status = models.SmallIntegerField(verbose_name="状态")
|
||||
name = models.CharField(max_length=128, verbose_name="工具名称", db_comment="工具名称")
|
||||
description = models.CharField(max_length=256, null=True, blank=True, verbose_name="工具描述", db_comment="工具描述")
|
||||
status = models.SmallIntegerField(verbose_name="状态", db_comment="状态", default=0)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_tool"
|
||||
@@ -73,4 +74,258 @@ class Tool(CoreModel):
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return self.name
|
||||
|
||||
|
||||
class Knowledge(CoreModel):
|
||||
""" AI 知识库表 """
|
||||
name = models.CharField(max_length=255, verbose_name="知识库名称", db_comment="知识库名称")
|
||||
description = models.TextField(null=True, blank=True, verbose_name="知识库描述", db_comment="知识库描述")
|
||||
embedding_model_id = models.ForeignKey(
|
||||
'AIModel',
|
||||
on_delete=models.CASCADE,
|
||||
db_column='embedding_model_id',
|
||||
db_comment='向量模型编号', verbose_name="向量模型编号"
|
||||
)
|
||||
embedding_model = models.CharField(max_length=32, verbose_name="向量模型标识", db_comment="向量模型标识")
|
||||
top_k = models.IntegerField(verbose_name="topK", db_comment="topK", default=0)
|
||||
similarity_threshold = models.FloatField(verbose_name="相似度阈值", db_comment="相似度阈值")
|
||||
status = models.SmallIntegerField(
|
||||
choices=CommonStatus.choices,
|
||||
default=CommonStatus.DISABLED,
|
||||
verbose_name="状态",
|
||||
db_comment="状态",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_knowledge"
|
||||
verbose_name = "AI 知识库"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class KnowledgeDocument(CoreModel):
|
||||
""" AI 知识库文档表 """
|
||||
knowledge = models.ForeignKey(
|
||||
Knowledge,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="documents",
|
||||
verbose_name="知识库",
|
||||
db_comment="知识库"
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name="文档名称", db_comment="文档名称")
|
||||
url = models.CharField(max_length=1024, verbose_name="文件 URL", db_comment="文件 URL")
|
||||
content = models.TextField(verbose_name="内容", db_comment="内容")
|
||||
content_length = models.IntegerField(verbose_name="字符数", db_comment="字符数")
|
||||
tokens = models.IntegerField(verbose_name="token 数量", db_comment="token 数量")
|
||||
segment_max_tokens = models.IntegerField(verbose_name="分片最大 Token 数", db_comment="分片最大 Token 数")
|
||||
retrieval_count = models.IntegerField(default=0, verbose_name="召回次数", db_comment="召回次数")
|
||||
status = models.SmallIntegerField(
|
||||
choices=CommonStatus.choices,
|
||||
default=CommonStatus.DISABLED,
|
||||
verbose_name="状态",
|
||||
db_comment="状态",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_knowledge_document"
|
||||
verbose_name = "AI 知识库文档"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class KnowledgeSegment(CoreModel):
|
||||
""" AI 知识库分段表 """
|
||||
knowledge = models.ForeignKey(
|
||||
Knowledge,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="segments",
|
||||
verbose_name="知识库",
|
||||
db_comment="知识库"
|
||||
)
|
||||
document = models.ForeignKey(
|
||||
KnowledgeDocument,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="segments",
|
||||
verbose_name="文档",
|
||||
db_comment="文档"
|
||||
)
|
||||
content = models.TextField(verbose_name="分段内容", db_comment="分段内容")
|
||||
content_length = models.IntegerField(verbose_name="字符数", db_comment="字符数")
|
||||
tokens = models.IntegerField(verbose_name="token 数量", db_comment="token 数量")
|
||||
vector_id = models.CharField(
|
||||
max_length=100,
|
||||
null=True, blank=True,
|
||||
verbose_name="向量库的编号",
|
||||
db_comment="向量库的编号"
|
||||
)
|
||||
retrieval_count = models.IntegerField(default=0, verbose_name="召回次数", db_comment="召回次数")
|
||||
status = models.SmallIntegerField(
|
||||
choices=CommonStatus.choices,
|
||||
default=CommonStatus.DISABLED,
|
||||
verbose_name="状态",
|
||||
db_comment="状态"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_knowledge_segment"
|
||||
verbose_name = "AI 知识库分段"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f"Segment {self.id}"
|
||||
|
||||
|
||||
class ChatRole(CoreModel):
|
||||
""" AI 聊天角色表 """
|
||||
name = models.CharField(max_length=128, verbose_name="角色名称", db_comment="角色名称")
|
||||
avatar = models.CharField(max_length=256, verbose_name="头像", db_comment="头像")
|
||||
description = models.CharField(max_length=256, verbose_name="角色描述", db_comment="角色描述")
|
||||
status = models.SmallIntegerField(
|
||||
choices=CommonStatus.choices,
|
||||
default=CommonStatus.DISABLED,
|
||||
verbose_name="状态",
|
||||
db_comment="状态"
|
||||
)
|
||||
sort = models.IntegerField(default=0, verbose_name="角色排序", db_comment="角色排序")
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name="用户",
|
||||
db_comment="用户编号"
|
||||
)
|
||||
public_status = models.BooleanField(default=False, verbose_name="是否公开", db_comment="是否公开")
|
||||
category = models.CharField(max_length=32, null=True, blank=True, verbose_name="角色类别", db_comment="角色类别")
|
||||
model_id = models.ForeignKey(
|
||||
'AIModel',
|
||||
on_delete=models.CASCADE,
|
||||
db_column='model_id',
|
||||
verbose_name="向量模型编号",
|
||||
db_comment='向量模型编号'
|
||||
)
|
||||
system_message = models.CharField(
|
||||
max_length=1024, null=True, blank=True,
|
||||
verbose_name="角色上下文",
|
||||
db_comment="角色上下文"
|
||||
)
|
||||
knowledge = models.ManyToManyField(
|
||||
'Knowledge',
|
||||
blank=True,
|
||||
related_name="roles",
|
||||
verbose_name="关联的知识库",
|
||||
db_comment="关联的知识库"
|
||||
)
|
||||
tools = models.ManyToManyField(
|
||||
'Tool',
|
||||
blank=True,
|
||||
related_name="roles",
|
||||
verbose_name="关联的工具",
|
||||
db_comment="关联的工具"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_chat_role"
|
||||
verbose_name = "AI 聊天角色"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ChatConversation(CoreModel):
|
||||
""" AI 聊天对话表 """
|
||||
title = models.CharField(max_length=256, verbose_name="对话标题", db_comment="对话标题")
|
||||
pinned = models.BooleanField(default=False, verbose_name="是否置顶", db_comment="是否置顶")
|
||||
pinned_time = models.DateTimeField(null=True, blank=True, verbose_name="置顶时间", db_comment="置顶时间")
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name="用户",
|
||||
db_comment="用户编号"
|
||||
)
|
||||
role = models.ForeignKey(
|
||||
'ChatRole',
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name="聊天角色",
|
||||
db_comment="聊天角色"
|
||||
)
|
||||
model_id = models.ForeignKey(
|
||||
'AIModel',
|
||||
on_delete=models.CASCADE,
|
||||
db_column='model_id',
|
||||
verbose_name="向量模型编号",
|
||||
db_comment='向量模型编号'
|
||||
)
|
||||
model = models.CharField(max_length=32, verbose_name="模型标识", db_comment="模型标识")
|
||||
system_message = models.CharField(
|
||||
max_length=1024, null=True, blank=True,
|
||||
verbose_name="角色设定",
|
||||
db_comment="角色设定"
|
||||
)
|
||||
temperature = models.FloatField(verbose_name="温度参数", db_comment="温度参数")
|
||||
max_tokens = models.IntegerField(verbose_name="单条回复的最大 Token 数量", db_comment="单条回复的最大 Token 数量")
|
||||
max_contexts = models.IntegerField(verbose_name="上下文的最大 Message 数量", db_comment="上下文的最大 Message 数量")
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_chat_conversation"
|
||||
verbose_name = "AI 聊天对话"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class ChatMessage(CoreModel):
|
||||
""" AI 聊天消息表 """
|
||||
conversation_id = models.BigIntegerField(verbose_name="对话编号", db_comment="对话编号")
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name="用户",
|
||||
db_comment="用户编号"
|
||||
)
|
||||
role = models.ForeignKey(
|
||||
'ChatRole',
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name="聊天角色",
|
||||
db_comment="聊天角色"
|
||||
)
|
||||
model = models.CharField(max_length=32, verbose_name="模型标识", db_comment="模型标识")
|
||||
model_id = models.ForeignKey(
|
||||
'AIModel',
|
||||
on_delete=models.CASCADE,
|
||||
db_column='model_id',
|
||||
verbose_name="向量模型编号",
|
||||
db_comment='向量模型编号'
|
||||
)
|
||||
type = models.CharField(
|
||||
max_length=16,
|
||||
choices=MessageType.choices,
|
||||
verbose_name="消息类型",
|
||||
db_comment="消息类型",
|
||||
)
|
||||
reply_id = models.BigIntegerField(null=True, blank=True, verbose_name="回复编号", db_comment="回复编号")
|
||||
content = models.CharField(max_length=2048, verbose_name="消息内容", db_comment="消息内容")
|
||||
use_context = models.BooleanField(default=False, verbose_name="是否携带上下文", db_comment="是否携带上下文")
|
||||
segment_ids = models.CharField(
|
||||
max_length=2048, null=True, blank=True,
|
||||
verbose_name="段落编号数组",
|
||||
db_comment="段落编号数组"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "ai_chat_message"
|
||||
verbose_name = "AI 聊天消息"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.content[:30]
|
||||
|
||||
@@ -173,11 +173,9 @@ class Command(BaseCommand):
|
||||
field_config = self.generate_grid_form_field(field)
|
||||
if field_config:
|
||||
grid_form_fields.append(field_config)
|
||||
|
||||
|
||||
# 生成 useColumns
|
||||
columns = []
|
||||
for field in business_fields + core_fields:
|
||||
columns.append(f" {{\n field: '{field.name}',\n title: '{getattr(field, 'verbose_name', field.name)}',\n }},")
|
||||
columns = self.get_columns_code(business_fields + core_fields)
|
||||
context = get_context(app_name, model_name, model, model_name_snake)
|
||||
context['form_fields'] = '\n'.join(form_fields)
|
||||
context['grid_form_fields'] = '\n'.join(grid_form_fields)
|
||||
@@ -218,28 +216,41 @@ class Command(BaseCommand):
|
||||
return 'any'
|
||||
|
||||
def generate_form_field(self, field):
|
||||
"""生成表单字段配置"""
|
||||
field_name = field.name
|
||||
field_label = getattr(field, 'verbose_name', field_name)
|
||||
if field_name == 'status':
|
||||
return "{ component: 'RadioGroup', componentProps: { buttonStyle: 'solid', options: [{ label: $t('common.enabled'), value: 1 }, { label: $t('common.disabled'), value: 0 }], optionType: 'button' }, defaultValue: 1, fieldName: 'status', label: $t('system.status') },"
|
||||
if isinstance(field, models.CharField):
|
||||
return f''' {{\n component: 'Input',\n fieldName: '{field_name}',\n label: '{field_label}',\n rules: z\n .string()\n .min(1, $t('ui.formRules.required', ['{field_label}']))\n .max(100, $t('ui.formRules.maxLength', ['{field_label}', 100])),\n }},'''
|
||||
return f"{{ component: 'Input', fieldName: '{field_name}', label: '{field_label}', rules: z.string().min(1, $t('ui.formRules.required', ['{field_label}'])).max(100, $t('ui.formRules.maxLength', ['{field_label}', 100])) }},"
|
||||
elif isinstance(field, models.TextField):
|
||||
return f''' {{\n component: 'Input',\n componentProps: {{\n rows: 3,\n showCount: true,\n }},\n fieldName: '{field_name}',\n label: '{field_label}',\n rules: z\n .string()\n .max(500, $t('ui.formRules.maxLength', ['{field_label}', 500]))\n .optional(),\n }},'''
|
||||
return f"{{ component: 'Input', componentProps: {{ rows: 3, showCount: true }}, fieldName: '{field_name}', label: '{field_label}', rules: z.string().max(500, $t('ui.formRules.maxLength', ['{field_label}', 500])).optional() }},"
|
||||
elif isinstance(field, models.IntegerField):
|
||||
return f''' {{\n component: 'InputNumber',\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
return f"{{ component: 'InputNumber', fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
elif isinstance(field, models.BooleanField):
|
||||
return f''' {{\n component: 'RadioGroup',\n componentProps: {{\n buttonStyle: 'solid',\n options: [\n {{ label: '开启', value: 1 }},\n {{ label: '关闭', value: 0 }},\n ],\n optionType: 'button',\n }},\n defaultValue: 1,\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
return f"{{ component: 'RadioGroup', componentProps: {{ buttonStyle: 'solid', options: [{{ label: '开启', value: 1 }}, {{ label: '关闭', value: 0 }}], optionType: 'button' }}, defaultValue: 1, fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
else:
|
||||
return f''' {{\n component: 'Input',\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
return f"{{ component: 'Input', fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
|
||||
def generate_grid_form_field(self, field):
|
||||
field_name = field.name
|
||||
field_label = getattr(field, 'verbose_name', field_name)
|
||||
# 查询表单一般只需要 component/fieldName/label,不需要 rules
|
||||
if field_name == 'status':
|
||||
return "{ component: 'Select', fieldName: 'status', label: '状态', componentProps: { allowClear: true, options: [{ label: '启用', value: 1 }, { label: '禁用', value: 0 }] } },"
|
||||
if isinstance(field, models.CharField):
|
||||
return f''' {{\n component: 'Input',\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
return f"{{ component: 'Input', fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
elif isinstance(field, models.IntegerField):
|
||||
return f''' {{\n component: 'InputNumber',\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
# 其他类型同理
|
||||
return f"{{ component: 'InputNumber', fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
else:
|
||||
return f''' {{\n component: 'Input',\n fieldName: '{field_name}',\n label: '{field_label}',\n }},'''
|
||||
return f"{{ component: 'Input', fieldName: '{field_name}', label: '{field_label}' }},"
|
||||
|
||||
def get_columns_code(self, fields):
|
||||
columns = []
|
||||
for field in fields:
|
||||
if field.name == 'status':
|
||||
columns.append("{ field: 'status', title: '状态', cellRender: { name: 'CellTag' } },")
|
||||
continue
|
||||
if isinstance(field, (models.DateField, models.DateTimeField)):
|
||||
columns.append(f"{{ field: '{field.name}', title: '{getattr(field, 'verbose_name', field.name)}', width: 150, formatter: ({{ cellValue }}) => format_datetime(cellValue) }},")
|
||||
continue
|
||||
columns.append(f"{{ field: '{field.name}', title: '{getattr(field, 'verbose_name', field.name)}' }},")
|
||||
return columns
|
||||
@@ -1,5 +1,7 @@
|
||||
# Generated by Django 5.2.1 on 2025-07-10 04:07
|
||||
# Generated by Django 5.2.1 on 2025-07-11 07:44
|
||||
|
||||
import django.contrib.auth.validators
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -572,6 +574,45 @@ class Migration(migrations.Migration):
|
||||
verbose_name="创建人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="date_joined",
|
||||
field=models.DateTimeField(
|
||||
db_comment="date joined",
|
||||
default=django.utils.timezone.now,
|
||||
verbose_name="date joined",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="email",
|
||||
field=models.EmailField(
|
||||
blank=True,
|
||||
db_comment="email address",
|
||||
max_length=254,
|
||||
verbose_name="email address",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="first_name",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="first name",
|
||||
max_length=150,
|
||||
verbose_name="first name",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="is_active",
|
||||
field=models.BooleanField(
|
||||
db_comment="active",
|
||||
default=True,
|
||||
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
|
||||
verbose_name="active",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="is_deleted",
|
||||
@@ -579,6 +620,46 @@ class Migration(migrations.Migration):
|
||||
db_comment="是否软删除", default=False, verbose_name="是否软删除"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="is_staff",
|
||||
field=models.BooleanField(
|
||||
db_comment="staff status",
|
||||
default=False,
|
||||
help_text="Designates whether the user can log into this admin site.",
|
||||
verbose_name="staff status",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="is_superuser",
|
||||
field=models.BooleanField(
|
||||
db_comment="superuser status",
|
||||
default=False,
|
||||
help_text="Designates that this user has all permissions without explicitly assigning them.",
|
||||
verbose_name="superuser status",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="last_login",
|
||||
field=models.DateTimeField(
|
||||
blank=True,
|
||||
db_comment="last login",
|
||||
null=True,
|
||||
verbose_name="last login",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="last_name",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_comment="last name",
|
||||
max_length=150,
|
||||
verbose_name="last name",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="modifier",
|
||||
@@ -591,6 +672,13 @@ class Migration(migrations.Migration):
|
||||
verbose_name="修改人",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="password",
|
||||
field=models.CharField(
|
||||
db_comment="password", max_length=128, verbose_name="password"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="remark",
|
||||
@@ -614,4 +702,17 @@ class Migration(migrations.Migration):
|
||||
verbose_name="修改时间",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="username",
|
||||
field=models.CharField(
|
||||
db_comment="username",
|
||||
error_messages={"unique": "A user with that username already exists."},
|
||||
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
|
||||
max_length=150,
|
||||
unique=True,
|
||||
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
|
||||
verbose_name="username",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -9,7 +9,20 @@ class CommonStatus(models.IntegerChoices):
|
||||
DISABLED = 0, '禁用'
|
||||
ENABLED = 1, '启用'
|
||||
|
||||
class CoreModel(models.Model):
|
||||
|
||||
class AutoCommentModel(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
# 给字段自动添加db_comment
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
for field in cls._meta.fields:
|
||||
if getattr(field, 'verbose_name', None) and not getattr(field, 'db_comment', None):
|
||||
field.db_comment = field.verbose_name
|
||||
|
||||
|
||||
class CoreModel(AutoCommentModel):
|
||||
remark = models.CharField(max_length=256, db_comment="备注", null=True, blank=True, help_text="备注",
|
||||
verbose_name="备注")
|
||||
creator = models.CharField(max_length=64, null=True, blank=True, help_text="创建人", db_comment="创建人",
|
||||
|
||||
Reference in New Issue
Block a user