This commit is contained in:
zlwu committed 2026-05-20 21:12:16 +08:00
1 parent e6b4b9a8d7
commit 6272d107dc
29 files changed
+5840 -4504

No files matched your search

+29 -4
View File
@@ -6,6 +6,7 @@ from typing import Any, List, Optional
from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import or_
from sqlalchemy.orm import Session
from app.core.database import get_db
@@ -121,14 +122,31 @@ def _row_to_dict_project_price(row: BizInsuranceProjectPrice) -> dict:
def _list_insurance_companies(
db: Session, *, page: int, page_size: int, keyword: Optional[str], tenant_no: str, user_info=None
db: Session,
*,
page: int,
page_size: int,
keyword: Optional[str],
status: Optional[str],
tenant_no: str,
user_info=None,
):
q = db.query(BizInsuranceCompany).filter(
BizInsuranceCompany.tenant_no == tenant_no,
BizInsuranceCompany.del_flag == 0,
)
if keyword:
q = q.filter(BizInsuranceCompany.company_name.like(f"%{keyword}%"))
kw = (keyword or "").strip()
if kw:
like = f"%{kw}%"
q = q.filter(
or_(
BizInsuranceCompany.company_name.like(like),
BizInsuranceCompany.contact_name.like(like),
)
)
st = (status or "").strip()
if st in ("0", "1"):
q = q.filter(BizInsuranceCompany.status == st)
if user_info:
from app.core.data_scope import apply_data_scope
q = apply_data_scope(q, BizInsuranceCompany, user_info, db, tenant_no)
@@ -532,12 +550,19 @@ async def list_insurance_companies(
page: int = Query(1, ge=1),
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
keyword: Optional[str] = None,
status: Optional[str] = None,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
tenant_no = _get_tenant_no(db, user)
items, total = _list_insurance_companies(
db, page=page, page_size=pageSize, keyword=keyword, tenant_no=tenant_no, user_info=user
db,
page=page,
page_size=pageSize,
keyword=keyword,
status=status,
tenant_no=tenant_no,
user_info=user,
)
tp = _total_pages(total, pageSize)
return success_response(
+119 -3
View File
@@ -1,5 +1,6 @@
"""市场物料库 API"""
from typing import Optional
from datetime import datetime
from typing import List, Optional
from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, ConfigDict, Field
@@ -7,6 +8,7 @@ from sqlalchemy.orm import Session
from app.api.sample_reception import _get_current_user_id, _get_tenant_no, _page_payload
from app.core.database import get_db
from app.core.utils import parse_datetime
from app.core.menu_guard import require_admin_or_super_admin, require_menu_code
from app.core.response import error_response, success_response
from app.crud import material as mat_svc
@@ -48,6 +50,7 @@ class StockInBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
qty: float = Field(..., gt=0)
remark: Optional[str] = None
stock_in_time: Optional[str] = Field(None, alias="stockInTime")
class StockOutBody(BaseModel):
@@ -56,6 +59,37 @@ class StockOutBody(BaseModel):
receiver: Optional[str] = None
purpose: Optional[str] = None
remark: Optional[str] = None
stock_out_time: Optional[str] = Field(None, alias="stockOutTime")
class BatchStockInItem(BaseModel):
model_config = ConfigDict(populate_by_name=True)
material_id: str = Field(..., alias="materialId")
qty: float = Field(..., gt=0)
remark: Optional[str] = None
class BatchStockInBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
items: List[BatchStockInItem] = Field(..., min_length=1)
remark: Optional[str] = None
stock_in_time: Optional[str] = Field(None, alias="stockInTime")
class BatchStockOutItem(BaseModel):
model_config = ConfigDict(populate_by_name=True)
material_id: str = Field(..., alias="materialId")
qty: float = Field(..., gt=0)
remark: Optional[str] = None
class BatchStockOutBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
items: List[BatchStockOutItem] = Field(..., min_length=1)
receiver: Optional[str] = None
purpose: Optional[str] = None
remark: Optional[str] = None
stock_out_time: Optional[str] = Field(None, alias="stockOutTime")
# ---------- 物料 CRUD ----------
@@ -154,6 +188,76 @@ async def delete_material(
return error_response(str(e))
@router.post("/materials/batch-stock-in")
async def batch_stock_in_material(
body: BatchStockInBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:material:list")),
):
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_in_time:
rt = parse_datetime(body.stock_in_time)
if not rt:
return error_response("入库时间格式无效")
operate_time = rt
items = [
{"material_id": x.material_id, "qty": x.qty, "remark": x.remark}
for x in body.items
]
count = mat_svc.batch_stock_in(
db,
items=items,
remark=body.remark,
tenant_no=tenant_no,
user_id=user_id,
operate_time=operate_time,
)
return success_response({"count": count}, message=f"批量入库成功,共 {count} 项")
except ValueError as e:
return error_response(str(e))
except Exception as e:
return error_response(str(e))
@router.post("/materials/batch-stock-out")
async def batch_stock_out_material(
body: BatchStockOutBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:material:list")),
):
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_out_time:
rt = parse_datetime(body.stock_out_time)
if not rt:
return error_response("出库时间格式无效")
operate_time = rt
items = [
{"material_id": x.material_id, "qty": x.qty, "remark": x.remark}
for x in body.items
]
count = mat_svc.batch_stock_out(
db,
items=items,
receiver=body.receiver,
purpose=body.purpose,
remark=body.remark,
tenant_no=tenant_no,
user_id=user_id,
operate_time=operate_time,
)
return success_response({"count": count}, message=f"批量出库成功,共 {count} 项")
except ValueError as e:
return error_response(str(e))
except Exception as e:
return error_response(str(e))
@router.post("/materials/{material_id}/stock-in")
async def stock_in_material(
material_id: str,
@@ -164,9 +268,15 @@ async def stock_in_material(
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_in_time:
rt = parse_datetime(body.stock_in_time)
if not rt:
return error_response("入库时间格式无效")
operate_time = rt
obj = mat_svc.stock_in(
db, material_id, qty=body.qty, remark=body.remark,
tenant_no=tenant_no, user_id=user_id,
tenant_no=tenant_no, user_id=user_id, operate_time=operate_time,
)
return success_response(obj, message="入库成功")
except ValueError as e:
@@ -185,10 +295,16 @@ async def stock_out_material(
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_out_time:
rt = parse_datetime(body.stock_out_time)
if not rt:
return error_response("出库时间格式无效")
operate_time = rt
obj = mat_svc.stock_out(
db, material_id, qty=body.qty, receiver=body.receiver,
purpose=body.purpose, remark=body.remark,
tenant_no=tenant_no, user_id=user_id,
tenant_no=tenant_no, user_id=user_id, operate_time=operate_time,
)
return success_response(obj, message="出库成功")
except ValueError as e: