forked from erp-dev/erp
feat: refactor flower.utils to sub package, added some sync api in package, added plate_order sync result model but relation of plate_order was not query (do it next step)
This commit is contained in:
225
flower/utils/mingdaoyun/fetch.py
Normal file
225
flower/utils/mingdaoyun/fetch.py
Normal file
@@ -0,0 +1,225 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from asgiref.sync import sync_to_async
|
||||
|
||||
from .client import MDY_ENDPOINT_GET_FILTER_ROWS, get_default_mingdaoyun_client
|
||||
from .mappings import (
|
||||
MDY_WORKSHEET_ID_CUSTOMER,
|
||||
MDY_WORKSHEET_ID_FABRIC,
|
||||
MDY_WORKSHEET_ID_PLATE_ORDER,
|
||||
MDY_WORKSHEET_ID_PRODUCT,
|
||||
)
|
||||
from .models import Customer, Fabric, Product
|
||||
from .parsers import pick_customer, pick_fabric, pick_product
|
||||
|
||||
|
||||
async def fetch_products_from_mingdaoyun(page: int = 1, page_size: int = 100) -> tuple[list[Product], int]:
|
||||
"""从明道云获取产品列表"""
|
||||
|
||||
client = get_default_mingdaoyun_client()
|
||||
response = await client.post(
|
||||
endpoint=MDY_ENDPOINT_GET_FILTER_ROWS,
|
||||
data={
|
||||
"worksheetId": MDY_WORKSHEET_ID_PRODUCT,
|
||||
"pageIndex": page,
|
||||
"pageSize": page_size,
|
||||
"sortId": "ctime",
|
||||
"isAsc": True,
|
||||
},
|
||||
)
|
||||
|
||||
data = response.get("data") if isinstance(response, dict) else None
|
||||
if data:
|
||||
print(
|
||||
f'[product-sync] page={page} size={page_size} rows={len(data.get("rows", []))} total={data.get("total")}'
|
||||
)
|
||||
else:
|
||||
print(f"[product-sync] page={page} size={page_size} received empty data")
|
||||
if not data:
|
||||
return [], 0
|
||||
|
||||
products = [pick_product(item) for item in data.get("rows", [])]
|
||||
total_count = data.get("total", 0)
|
||||
return products, total_count
|
||||
|
||||
|
||||
async def fetch_customers_from_mingdaoyun(page: int = 1, page_size: int = 100) -> tuple[list[Customer], int]:
|
||||
"""从明道云获取客户列表"""
|
||||
|
||||
client = get_default_mingdaoyun_client()
|
||||
response = await client.post(
|
||||
endpoint=MDY_ENDPOINT_GET_FILTER_ROWS,
|
||||
data={
|
||||
"worksheetId": MDY_WORKSHEET_ID_CUSTOMER,
|
||||
"pageIndex": page,
|
||||
"pageSize": page_size,
|
||||
"sortId": "ctime",
|
||||
"isAsc": True,
|
||||
},
|
||||
)
|
||||
|
||||
data = response.get("data") if isinstance(response, dict) else None
|
||||
if data:
|
||||
print(
|
||||
f'[customer-sync] page={page} size={page_size} rows={len(data.get("rows", []))} total={data.get("total")}'
|
||||
)
|
||||
else:
|
||||
print(f"[customer-sync] page={page} size={page_size} received empty data")
|
||||
if not data:
|
||||
return [], 0
|
||||
|
||||
customers = [pick_customer(item) for item in data.get("rows", [])]
|
||||
total_count = data.get("total", 0)
|
||||
return customers, total_count
|
||||
|
||||
|
||||
async def fetch_row_by_rowid_from_mingdaoyun(
|
||||
worksheet_id: str,
|
||||
rowid: str,
|
||||
*,
|
||||
sort_id: str = "ctime",
|
||||
is_asc: bool = False,
|
||||
list_type: int = 1,
|
||||
not_get_total: bool = True,
|
||||
data_type: int = 2,
|
||||
filter_type: int = 3,
|
||||
control_id: str = "rowId",
|
||||
) -> dict[str, Any] | None:
|
||||
"""按 rowId 查询工作表的单条记录(仅封装 rowId 等值查询)。
|
||||
|
||||
按照明道云 getFilterRows 的 filters 结构构造请求:
|
||||
- dataType=2 表示字符串
|
||||
- filterType=3 表示“相等”
|
||||
|
||||
返回:
|
||||
- 匹配到记录:返回第一条 row dict
|
||||
- 未匹配或响应无 data:返回 None
|
||||
"""
|
||||
|
||||
client = get_default_mingdaoyun_client()
|
||||
response = await client.post(
|
||||
endpoint=MDY_ENDPOINT_GET_FILTER_ROWS,
|
||||
data={
|
||||
"worksheetId": worksheet_id,
|
||||
"listType": list_type,
|
||||
"sortId": sort_id,
|
||||
"isAsc": is_asc,
|
||||
"notGetTotal": not_get_total,
|
||||
"filters": [
|
||||
{
|
||||
"controlId": control_id,
|
||||
"dataType": data_type,
|
||||
"filterType": filter_type,
|
||||
"value": rowid,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
data = response.get("data") if isinstance(response, dict) else None
|
||||
if not data:
|
||||
return None
|
||||
|
||||
rows = data.get("rows") or []
|
||||
if not rows:
|
||||
return None
|
||||
if isinstance(rows[0], dict):
|
||||
return rows[0]
|
||||
return None
|
||||
|
||||
|
||||
async def fetch_plate_orders_from_mingdaoyun(
|
||||
page: int = 1,
|
||||
page_size: int = 100,
|
||||
*,
|
||||
sort_id: str = "ctime",
|
||||
is_asc: bool = True,
|
||||
) -> tuple[list[dict[str, Any]], int]:
|
||||
"""从明道云获取“开版数据表”记录列表(原始行字典,不做字段映射解析)"""
|
||||
|
||||
client = get_default_mingdaoyun_client()
|
||||
response = await client.post(
|
||||
endpoint=MDY_ENDPOINT_GET_FILTER_ROWS,
|
||||
data={
|
||||
"worksheetId": MDY_WORKSHEET_ID_PLATE_ORDER,
|
||||
"pageIndex": page,
|
||||
"pageSize": page_size,
|
||||
"sortId": sort_id,
|
||||
"isAsc": is_asc,
|
||||
},
|
||||
)
|
||||
|
||||
data = response.get("data") if isinstance(response, dict) else None
|
||||
if data:
|
||||
print(
|
||||
f'[plate-order-fetch] page={page} size={page_size} rows={len(data.get("rows", []))} total={data.get("total")}'
|
||||
)
|
||||
else:
|
||||
print(f"[plate-order-fetch] page={page} size={page_size} received empty data")
|
||||
if not data:
|
||||
return [], 0
|
||||
|
||||
rows = data.get("rows", [])
|
||||
total_count = data.get("total", 0)
|
||||
return rows, total_count
|
||||
|
||||
|
||||
async def sync_fabric_from_mingdaoyun(page: int = 1, page_size: int = 100) -> int:
|
||||
"""从明道云同步面料数据(用于创建/更新 QuickInput: 布料名)"""
|
||||
|
||||
client = get_default_mingdaoyun_client()
|
||||
response = await client.post(
|
||||
endpoint=MDY_ENDPOINT_GET_FILTER_ROWS,
|
||||
data={
|
||||
"worksheetId": MDY_WORKSHEET_ID_FABRIC,
|
||||
"pageIndex": page,
|
||||
"pageSize": page_size,
|
||||
"sortId": "ctime",
|
||||
"isAsc": False,
|
||||
},
|
||||
)
|
||||
|
||||
data = response.get("data") if isinstance(response, dict) else None
|
||||
if data:
|
||||
rows = data.get("rows", [])
|
||||
print(f"[fabric-sync] fetch rows={len(rows)} total={data.get('total')}")
|
||||
if rows:
|
||||
print(f"[fabric-sync] first row keys: {list(rows[0].keys())[:10]}")
|
||||
print(f"[fabric-sync] first row sample: {rows[0]}")
|
||||
else:
|
||||
print(f"[fabric-sync] fetch empty data (page={page}, size={page_size})")
|
||||
if not data:
|
||||
return 0
|
||||
|
||||
fabrics = [pick_fabric(item) for item in data.get("rows", [])]
|
||||
total_count = data.get("total", 0)
|
||||
|
||||
await sync_to_async(_create_fabric_quick_inputs)(
|
||||
page,
|
||||
page_size,
|
||||
fabrics,
|
||||
)
|
||||
return total_count
|
||||
|
||||
|
||||
def _create_fabric_quick_inputs(page: int, page_size: int, fabrics: list[Fabric]) -> None:
|
||||
from basic_info import models as basic_models
|
||||
|
||||
total = len(fabrics)
|
||||
created_count = 0
|
||||
sample_names = [fabric.name for fabric in fabrics[:5]]
|
||||
print(f"[fabric-sync] page={page} size={page_size} fetched={total}")
|
||||
print(f"[fabric-sync] sample names: {sample_names}")
|
||||
for fabric in fabrics:
|
||||
if not fabric.name:
|
||||
continue
|
||||
obj, created = basic_models.QuickInput.objects.update_or_create(
|
||||
name=fabric.name,
|
||||
group="布料名",
|
||||
defaults={"value": fabric.name},
|
||||
)
|
||||
if created:
|
||||
created_count += 1
|
||||
print(f"[fabric-sync] page={page} new_records={created_count} updated_or_existing={total - created_count}")
|
||||
Reference in New Issue
Block a user