v0.1.0: CRM/ERP 系统内测版本 - 安全加固完成

- Docker bridge 网络隔离(8000 端口封死)
- Gunicorn 4 Worker 多进程
- Alembic 数据库迁移基线
- 日志轮转 20m×3
- JWT 密钥 + DB 密码 + CORS 收紧
- 3-2-1 备份链路(NAS + R740-B 冷备)
- 连接池 pool_pre_ping + pool_recycle=3600
This commit is contained in:
hankin
2026-03-16 07:31:37 +00:00
commit 423baff73b
2578 changed files with 824643 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
"""
联系人服务 — CRUD (V5.0)
"""
from __future__ import annotations
import uuid
from sqlalchemy import select, func, and_
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.crm import CrmContact
async def list_contacts(
db: AsyncSession,
customer_id: uuid.UUID,
) -> list[dict]:
"""列出某客户下所有未删除的联系人"""
stmt = (
select(CrmContact)
.where(
CrmContact.customer_id == customer_id,
CrmContact.is_deleted.is_(False),
)
.order_by(CrmContact.created_at)
)
rows = (await db.execute(stmt)).scalars().all()
return [_to_dict(c) for c in rows]
async def create_contact(
db: AsyncSession,
customer_id: uuid.UUID,
data: dict,
) -> dict:
"""新增联系人"""
contact = CrmContact(
customer_id=customer_id,
name=data["name"],
phone=data.get("phone"),
title=data.get("title"),
)
db.add(contact)
await db.commit()
await db.refresh(contact)
return _to_dict(contact)
async def update_contact(
db: AsyncSession,
contact_id: uuid.UUID,
data: dict,
) -> dict:
"""编辑联系人"""
contact = await db.get(CrmContact, contact_id)
if not contact or contact.is_deleted:
raise ValueError("联系人不存在")
for field in ("name", "phone", "title"):
if field in data:
setattr(contact, field, data[field])
await db.commit()
await db.refresh(contact)
return _to_dict(contact)
async def delete_contact(
db: AsyncSession,
contact_id: uuid.UUID,
) -> None:
"""软删除联系人"""
contact = await db.get(CrmContact, contact_id)
if not contact or contact.is_deleted:
raise ValueError("联系人不存在")
contact.is_deleted = True
await db.commit()
def _to_dict(c: CrmContact) -> dict:
return {
"id": str(c.id),
"customer_id": str(c.customer_id),
"name": c.name,
"phone": c.phone,
"title": c.title,
"ai_buyer_persona": c.ai_buyer_persona or {},
"created_at": c.created_at.isoformat() if c.created_at else None,
"updated_at": c.updated_at.isoformat() if c.updated_at else None,
}