Files
assist/src/core/models.py

216 lines
9.3 KiB
Python
Raw Normal View History

2025-09-06 21:06:18 +08:00
from sqlalchemy import Column, Integer, String, Text, DateTime, Float, Boolean, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from datetime import datetime
import hashlib
2025-09-06 21:06:18 +08:00
Base = declarative_base()
class WorkOrder(Base):
"""工单模型"""
__tablename__ = "work_orders"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
order_id = Column(String(50), unique=True, nullable=False)
title = Column(String(200), nullable=False)
description = Column(Text, nullable=False)
category = Column(String(100), nullable=False)
priority = Column(String(20), nullable=False)
status = Column(String(20), nullable=False)
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
resolution = Column(Text)
satisfaction_score = Column(Float)
# 飞书集成字段
feishu_record_id = Column(String(100), unique=True, nullable=True) # 飞书记录ID
assignee = Column(String(100), nullable=True) # 负责人
solution = Column(Text, nullable=True) # 解决方案
ai_suggestion = Column(Text, nullable=True) # AI建议
# 扩展飞书字段
source = Column(String(50), nullable=True) # 来源Mail, Telegram bot等
module = Column(String(100), nullable=True) # 模块local O&M, OTA等
created_by = Column(String(100), nullable=True) # 创建人
wilfulness = Column(String(100), nullable=True) # 责任人
date_of_close = Column(DateTime, nullable=True) # 关闭日期
vehicle_type = Column(String(100), nullable=True) # 车型
vin_sim = Column(String(50), nullable=True) # 车架号/SIM
app_remote_control_version = Column(String(100), nullable=True) # 应用远程控制版本
hmi_sw = Column(String(100), nullable=True) # HMI软件版本
parent_record = Column(String(100), nullable=True) # 父记录
has_updated_same_day = Column(String(50), nullable=True) # 是否同日更新
operating_time = Column(String(100), nullable=True) # 操作时间
# 工单分发和权限管理字段
assigned_module = Column(String(50), nullable=True) # 分配的模块TBOX、OTA等
module_owner = Column(String(100), nullable=True) # 业务接口人/模块负责人
dispatcher = Column(String(100), nullable=True) # 分发人(运维人员)
dispatch_time = Column(DateTime, nullable=True) # 分发时间
region = Column(String(50), nullable=True) # 区域overseas/domestic- 用于区分海外/国内
2025-09-06 21:06:18 +08:00
# 关联对话记录
conversations = relationship("Conversation", back_populates="work_order")
# 关联处理过程记录
process_history = relationship("WorkOrderProcessHistory", back_populates="work_order", order_by="WorkOrderProcessHistory.process_time")
2025-09-06 21:06:18 +08:00
class Conversation(Base):
"""对话记录模型"""
__tablename__ = "conversations"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
work_order_id = Column(Integer, ForeignKey("work_orders.id"))
user_message = Column(Text, nullable=False)
assistant_response = Column(Text, nullable=False)
timestamp = Column(DateTime, default=datetime.now)
confidence_score = Column(Float)
knowledge_used = Column(Text) # 使用的知识库条目
response_time = Column(Float) # 响应时间(秒)
2025-09-06 21:06:18 +08:00
work_order = relationship("WorkOrder", back_populates="conversations")
class KnowledgeEntry(Base):
"""知识库条目模型"""
__tablename__ = "knowledge_entries"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
question = Column(Text, nullable=False)
answer = Column(Text, nullable=False)
category = Column(String(100), nullable=False)
confidence_score = Column(Float, default=0.0)
usage_count = Column(Integer, default=0)
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
is_active = Column(Boolean, default=True)
is_verified = Column(Boolean, default=False) # 是否已验证
verified_by = Column(String(100)) # 验证人
verified_at = Column(DateTime) # 验证时间
vector_embedding = Column(Text) # 向量嵌入的JSON字符串
search_frequency = Column(Integer, default=0) # 搜索频率
last_accessed = Column(DateTime) # 最后访问时间
relevance_score = Column(Float, default=0.0) # 相关性评分
2025-09-06 21:06:18 +08:00
class VehicleData(Base):
"""车辆实时数据模型"""
__tablename__ = "vehicle_data"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
vehicle_id = Column(String(50), nullable=False) # 车辆ID
vehicle_vin = Column(String(17)) # 车架号
data_type = Column(String(50), nullable=False) # 数据类型(位置、状态、故障等)
data_value = Column(Text, nullable=False) # 数据值JSON格式
timestamp = Column(DateTime, default=datetime.now) # 数据时间戳
is_active = Column(Boolean, default=True) # 是否有效
2025-09-06 21:06:18 +08:00
# 索引
__table_args__ = (
{'extend_existing': True}
)
class Analytics(Base):
"""分析统计模型"""
__tablename__ = "analytics"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
date = Column(DateTime, nullable=False)
total_orders = Column(Integer, default=0)
resolved_orders = Column(Integer, default=0)
avg_resolution_time = Column(Float, default=0.0)
satisfaction_avg = Column(Float, default=0.0)
knowledge_hit_rate = Column(Float, default=0.0)
category_distribution = Column(Text) # JSON格式的类别分布
created_at = Column(DateTime, default=datetime.now)
class Alert(Base):
"""预警模型"""
__tablename__ = "alerts"
2025-09-06 21:06:18 +08:00
id = Column(Integer, primary_key=True)
rule_name = Column(String(100), nullable=False)
alert_type = Column(String(50), nullable=False)
level = Column(String(20), nullable=False) # info, warning, error, critical
2025-09-08 15:27:22 +08:00
severity = Column(String(20), nullable=False, default="medium") # low, medium, high, critical
2025-09-06 21:06:18 +08:00
message = Column(Text, nullable=False)
data = Column(Text) # JSON格式的预警数据
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.now)
resolved_at = Column(DateTime)
class WorkOrderSuggestion(Base):
"""工单AI建议与人工描述表"""
__tablename__ = "work_order_suggestions"
id = Column(Integer, primary_key=True)
work_order_id = Column(Integer, ForeignKey("work_orders.id"), nullable=False)
ai_suggestion = Column(Text)
human_resolution = Column(Text)
ai_similarity = Column(Float)
approved = Column(Boolean, default=False)
use_human_resolution = Column(Boolean, default=False) # 是否使用人工描述入库
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
class WorkOrderProcessHistory(Base):
"""工单处理过程记录表"""
__tablename__ = "work_order_process_history"
id = Column(Integer, primary_key=True)
work_order_id = Column(Integer, ForeignKey("work_orders.id"), nullable=False)
# 处理人员信息
processor_name = Column(String(100), nullable=False) # 处理人员姓名
processor_role = Column(String(50), nullable=True) # 处理人员角色(运维、业务方等)
processor_region = Column(String(50), nullable=True) # 处理人员区域overseas/domestic
# 处理内容
process_content = Column(Text, nullable=False) # 处理内容/操作描述
action_type = Column(String(50), nullable=False) # 操作类型dispatch、process、close、reassign等
# 处理结果
previous_status = Column(String(50), nullable=True) # 处理前的状态
new_status = Column(String(50), nullable=True) # 处理后的状态
assigned_module = Column(String(50), nullable=True) # 分配的模块(如果是分发操作)
# 时间戳
process_time = Column(DateTime, default=datetime.now, nullable=False) # 处理时间
created_at = Column(DateTime, default=datetime.now)
# 关联工单
work_order = relationship("WorkOrder", back_populates="process_history")
class User(Base):
"""用户模型"""
__tablename__ = "users"
id = Column(Integer, primary_key=True)
username = Column(String(50), unique=True, nullable=False)
password_hash = Column(String(128), nullable=False)
email = Column(String(120), unique=True, nullable=True)
name = Column(String(100), nullable=True)
role = Column(String(20), default='user') # admin, user, operator
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.now)
last_login = Column(DateTime)
def set_password(self, password):
"""设置密码哈希"""
self.password_hash = hashlib.sha256(password.encode()).hexdigest()
def check_password(self, password):
"""验证密码"""
return self.password_hash == hashlib.sha256(password.encode()).hexdigest()
def to_dict(self):
"""转换为字典格式用于API响应"""
return {
'id': self.id,
'username': self.username,
'email': self.email,
'name': self.name,
'role': self.role,
'is_active': self.is_active,
'created_at': self.created_at.isoformat() if self.created_at else None,
'last_login': self.last_login.isoformat() if self.last_login else None
}