feat(T+): 完成数据贯通与自动接入闭环

打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。
新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。
补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
This commit is contained in:
liuwenxin committed 2026-11-05 18:47:13 +08:00
1 parent 3efe72c344
commit 1e53792ad6
151 files changed
+8842 -401

No files matched your search

+14 -1
View File
@@ -15,7 +15,8 @@ from fastapi import APIRouter, Depends, Path, Query
from app.api.deps import DbSession, PayrollWriter, RequestMetaDep, get_current_user
from app.core.response import ApiResponse, PageQuery, PageResult, ok
from app.models import User
from app.models import Customer, User
from app.schemas.category_batch import CustomerCategoryBatch, CustomerOwnershipBatch
from app.schemas.customer import (
CustomerCreateIn,
CustomerOut,
@@ -33,6 +34,18 @@ router = APIRouter(prefix="/customers", tags=["客户管理"])
CurrentUser = Annotated[User, Depends(get_current_user)]
@router.put("/batch-category")
def batch_category(payload: CustomerCategoryBatch, session: DbSession, actor: PayrollWriter, meta: RequestMetaDep):
from app.services.category_batch import fill_missing
return ok(fill_missing(session, Customer, payload, actor, meta))
@router.put("/batch-ownership")
def batch_ownership(payload: CustomerOwnershipBatch, session: DbSession, actor: PayrollWriter, meta: RequestMetaDep):
return ok(customer_service.batch_change_ownership(session, payload, operator=actor, meta=meta))
@router.get("", response_model=ApiResponse[PageResult[CustomerOut]], summary="客户列表")
def list_customers(
session: DbSession,
+9 -1
View File
@@ -16,7 +16,8 @@ from fastapi import APIRouter, Depends, Path, Query
from app.api.deps import DbSession, PayrollWriter, RequestMetaDep, get_current_user
from app.core.response import ApiResponse, PageResult, ok
from app.models import User
from app.models import Product, User
from app.schemas.category_batch import ProductCategoryBatch
from app.schemas.product import (
ProductCreateIn,
ProductExtractIn,
@@ -32,6 +33,13 @@ CurrentUser = Annotated[User, Depends(get_current_user)]
router = APIRouter(prefix="/products", tags=["产品管理"])
@router.put("/batch-category")
def batch_category(payload: ProductCategoryBatch, session: DbSession, actor: PayrollWriter, meta: RequestMetaDep):
from app.services.category_batch import fill_missing
return ok(fill_missing(session, Product, payload, actor, meta))
@router.get("/extract/candidates")
def extraction_candidates(session: DbSession, _: CurrentUser, keyword: str = "", page_num: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100)):
from app.services.product_completion import candidates