v0.2.0: CRM/ERP 系统升级 - 清理 .gitignore 并移除误提交的 venv/env/db 文件

- 更新 .gitignore:全面覆盖环境变量、数据库、日志、缓存、上传文件
- 移除误跟踪的 server/venv/、crm_data.db、.env 文件
- 新增 server/.env.example 模板
- 新增合同管理、利润核算、AI教练等功能模块
- 新增 Playwright e2e 测试套件
- 前后端多项功能升级和 bug 修复
This commit is contained in:
hankin
2026-05-11 07:24:19 +00:00
parent 0f4c6b7924
commit 815cbf9d8c
2526 changed files with 11875 additions and 804148 deletions
+11 -2
View File
@@ -9,6 +9,7 @@ from sqlalchemy import func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.exceptions import BizException, ForbiddenException, NotFoundException
from app.models.finance import FinExpenseDetail, FinExpenseRecord, FinInvoicePool
from app.models.sys import SysUser
from app.schemas.auth import CurrentUserPayload
from app.schemas.finance import (
ExpenseBriefResponse, ExpenseCreate, ExpenseDetailResponse,
@@ -84,12 +85,13 @@ async def _release_invoices(db: AsyncSession, expense_id: uuid.UUID, now: dateti
# ── Service Functions ────────────────────────────────────
async def create_invoice(db: AsyncSession, user: CurrentUserPayload, body: InvoiceCreate) -> InvoiceResponse:
async def create_invoice(db: AsyncSession, user: CurrentUserPayload, body: InvoiceCreate, company_id: uuid.UUID) -> InvoiceResponse:
invoice = FinInvoicePool(
uploader_id=user.user_id, file_url=body.file_url,
merchant_name=body.merchant_name, amount=body.amount,
invoice_date=body.invoice_date, type=body.type,
ai_extracted_data=body.ai_extracted_data, is_used=False,
company_id=company_id,
)
db.add(invoice)
await db.commit()
@@ -101,8 +103,11 @@ async def list_invoices(
db: AsyncSession, user: CurrentUserPayload,
page: int = 1, size: int = 20,
inv_type: str | None = None, is_used: bool | None = None,
company_id: uuid.UUID | None = None,
) -> InvoiceListResponse:
where = [FinInvoicePool.is_deleted.is_(False)]
if company_id:
where.append(FinInvoicePool.company_id == company_id)
if user.data_scope == "self":
where.append(FinInvoicePool.uploader_id == user.user_id)
elif user.data_scope == "dept_and_sub":
@@ -135,7 +140,7 @@ async def void_invoice(db: AsyncSession, user: CurrentUserPayload, invoice_id: u
await db.commit()
async def create_expense(db: AsyncSession, user: CurrentUserPayload, body: ExpenseCreate) -> ExpenseResponse:
async def create_expense(db: AsyncSession, user: CurrentUserPayload, body: ExpenseCreate, company_id: uuid.UUID) -> ExpenseResponse:
invoice_ids = [item.invoice_id for item in body.items]
try:
async with db.begin_nested():
@@ -154,6 +159,7 @@ async def create_expense(db: AsyncSession, user: CurrentUserPayload, body: Expen
system_no = await _generate_expense_no(db)
expense = FinExpenseRecord(
system_no=system_no, applicant_id=user.user_id,
company_id=company_id,
total_amount=body.total_amount, status="submitted", remark=body.remark,
)
db.add(expense)
@@ -184,8 +190,11 @@ async def list_expenses(
db: AsyncSession, user: CurrentUserPayload,
page: int = 1, size: int = 20,
status: str | None = None, applicant_id: uuid.UUID | None = None,
company_id: uuid.UUID | None = None,
) -> ExpenseListResponse:
where = [FinExpenseRecord.is_deleted.is_(False)]
if company_id:
where.append(FinExpenseRecord.company_id == company_id)
if user.data_scope == "self":
where.append(FinExpenseRecord.applicant_id == user.user_id)
elif user.data_scope == "dept_and_sub":