This commit is contained in:
2025-10-31 16:21:28 +08:00
parent ebd59b5830
commit b0f6bf88f4
14 changed files with 484 additions and 297 deletions
+3
View File
@@ -74,3 +74,6 @@ jspm_packages/
.yarn-integrity
.env
test/
*.ipynb
+121
View File
@@ -0,0 +1,121 @@
from datetime import datetime
import requests
from typing import NamedTuple, List
# origin_url = "http://129.211.172.205:12980"
# acctid = "65a48b111c0197"
# username = "demo2"
# password = "88888888"
# lcid = "2052"
class FieldInfo(NamedTuple):
target_name: str
target_desc: str
this_name: str
this_desc: str
class FormInfo(NamedTuple):
form_id: str
field_infos: List[FieldInfo]
form_infos = [
FormInfo(
form_id="BD_MATERIAL",
field_infos=[
FieldInfo("fNumber", "编码", "materialNo", "*料号"),
FieldInfo("fName", "名称", "materialDesc", "*物料名称"),
FieldInfo("fWorkShopId.fName", "生产车间", "plant", "工厂"),
FieldInfo("fFixLeadTime", "固定提前期", "fixLeadTime", "固定提前期"),
FieldInfo("fFixLeadTimeType.fCaption", "固定提前期单位", "fixLeadTimeType", "固定提前期单位"),
FieldInfo("fReOrderGood", "再订货点", "lotPoint", "重订货点"),
FieldInfo("fErpClsId.fCaption", "物料属性", "erpCls", "物料属性"),
FieldInfo("fCategoryId.fName", "存货类别", "planItem", "产品组"),
FieldInfo("fProduceUnitId.fName", "生产单位", "unit", "单位"),
FieldInfo("fSpecification", "规格型号", "size", "规格"),
FieldInfo("fExpPeriod", "保质期", "expPeriod", "保质期"),
FieldInfo("fExpUnit.fCaption", "保质期单位", "expUnit", "质保期单位"),
FieldInfo("fMaxPoQty", "最大订货量", "lotMax", "最大批"),
FieldInfo("fMinPoQty", "最小订货量", "lotMin", "最小批"),
FieldInfo("fCheckLeadTime", "检验提前期", "checkLeadTime", "检验提前期"),
FieldInfo("fCheckLeadTimeType.fCaption", "检验提前期单位", "checkLeadTimeType", "检验提前期单位"),
FieldInfo("fPlanerId.fName", "计划员", "planner", "计划员"),
FieldInfo("fRefCost", "参考成本", "price", "单价"),
FieldInfo("fPlanIntervalsDays", "批量拆分间隔天数", "dayGap", "MTO拆分天数"),
FieldInfo("fCanDelayDays", "允许延后天数", "canDelay", "可否延迟"),
FieldInfo("fMaxStock", "最大库存", "lotTop", "最大库存"),
FieldInfo("fEOQ", "固定/经济批量", "lotFix", "固定批"),
FieldInfo("fPlanSafeStockQty", "安全库存", "lotSS", "安全库存"),
FieldInfo("fMaterialId", "🔑", "id", "ERP数据ID")
]),
]
class K3CloudConnector():
def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
self.origin_url = kwargs.get("origin_url")
self.acctid = kwargs.get("acctid")
self.username = kwargs.get("username")
self.password = kwargs.get("password")
self.lcid = kwargs.get("lcid")
self._cookie = None
self._cookie_expire = None
self._session = requests.Session()
def auth(self, *args, **kwargs):
if self._cookie and self._cookie_expire and datetime.now() < self._cookie_expire:
return
response = self._session.post(
f"{self.origin_url}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc",
data={
"acctid": self.acctid,
"username": self.username,
"password": self.password,
"lcid": self.lcid,
},
)
# 处理cookie
set_cookies = response.headers['Set-Cookie'].split(';')
self._cookie = set_cookies[0] + ';' + set_cookies[3].split(',')[1].strip()
self._cookie_expire = datetime.strptime(set_cookies[1].split('=')[1], "%a, %d-%b-%Y %H:%M:%S %Z")
def get_data(self, *args, **kwargs):
for form_info in form_infos:
form_id = form_info.form_id
field_infos = form_info.field_infos
k3Fields = ",".join([field_info.target_name for field_info in field_infos])
# 发送请求
response = self._session.post(
url=f"{self.origin_url}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc",
headers={
"Content-Type": "application/json;charset=UTF-8",
"Cookie": self._cookie,
},
json={
"data": {
"FormId": form_id,
"FieldKeys": k3Fields,
"FilterString": None,
"StartRow": 0,
"Limit": 1000,
"TopRowCount": 100000,
"SubSystemId": ""
}
},
)
# 处理响应
data = response.json()
print(data)
def set_data(self, *args, **kwargs):
pass
k3_connector = K3CloudConnector(origin_url="http://129.211.172.205:12980", acctid="65a48b111c0197", username="demo2", password="88888888", lcid="2052")
k3_connector.auth()
k3_connector.get_data()
-127
View File
@@ -1,127 +0,0 @@
from datetime import datetime
import requests
from typing import NamedTuple, List
origin_url = "http://129.211.172.205:12980"
acctid = "65a48b111c0197"
username = "demo2"
password = "88888888"
lcid = "2052"
class FieldInfo(NamedTuple):
target_name: str
target_desc: str
this_name: str
this_desc: str
class FormInfo(NamedTuple):
form_id: str
field_infos: List[FieldInfo]
form_infos = [
FormInfo(form_id="BD_MATERIAL", field_infos=[
FieldInfo("fNumber", "编码", "materialNo", "*料号"),
FieldInfo("fName", "名称", "materialDesc", "*物料名称"),
FieldInfo("fWorkShopId.fName", "生产车间", "plant", "工厂"),
FieldInfo("fFixLeadTime", "固定提前期", "fixLeadTime", "固定提前期"),
FieldInfo("fFixLeadTimeType.fCaption", "固定提前期单位", "fixLeadTimeType", "固定提前期单位"),
FieldInfo("fReOrderGood", "再订货点", "lotPoint", "重订货点"),
FieldInfo("fErpClsId.fCaption", "物料属性", "erpCls", "物料属性"),
FieldInfo("fCategoryId.fName", "存货类别", "planItem", "产品组"),
FieldInfo("fProduceUnitId.fName", "生产单位", "unit", "单位"),
FieldInfo("fSpecification", "规格型号", "size", "规格"),
FieldInfo("fExpPeriod", "保质期", "expPeriod", "保质期"),
FieldInfo("fExpUnit.fCaption", "保质期单位", "expUnit", "质保期单位"),
FieldInfo("fMaxPoQty", "最大订货量", "lotMax", "最大批"),
FieldInfo("fMinPoQty", "最小订货量", "lotMin", "最小批"),
FieldInfo("fCheckLeadTime", "检验提前期", "checkLeadTime", "检验提前期"),
FieldInfo("fCheckLeadTimeType.fCaption", "检验提前期单位", "checkLeadTimeType", "检验提前期单位"),
FieldInfo("fPlanerId.fName", "计划员", "planner", "计划员"),
FieldInfo("fRefCost", "参考成本", "price", "单价"),
FieldInfo("fPlanIntervalsDays", "批量拆分间隔天数", "dayGap", "MTO拆分天数"),
FieldInfo("fCanDelayDays", "允许延后天数", "canDelay", "可否延迟"),
FieldInfo("fMaxStock", "最大库存", "lotTop", "最大库存"),
FieldInfo("fEOQ", "固定/经济批量", "lotFix", "固定批"),
FieldInfo("fPlanSafeStockQty", "安全库存", "lotSS", "安全库存"),
FieldInfo("fMaterialId", "🔑", "id", "ERP数据ID"),
# FieldInfo(),
]),
]
class K3CloudConnector:
_cookie = None
_cookie_expire = None
_seession = requests.Session()
# def __init__(self, *args, **kwargs):
# # super().__init__(*args, **kwargs)
# self.cookie = None
# self.cookie_expire = None
# self.seession = requests.Session()
def auth(self, *args, **kwargs):
if _cookie and _cookie_expire:
if datetime.now() < _cookie_expire:
return
response = _seession.post(
f"{origin_url}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc",
data={
"acctid": acctid,
"username": username,
"password": password,
"lcid": lcid,
},
)
# 处理cookie
set_cookies = response.headers['Set-Cookie'].split(';')
_cookie = set_cookies[0] + ';' + set_cookies[3].split(',')[1].strip()
_cookie_expire = datetime.strptime(set_cookies[1].split('=')[1], "%a, %d-%b-%Y %H:%M:%S %Z")
return
def get_data(self, *args, **kwargs):
for form_info in form_infos:
form_id = form_info.form_id
field_infos = form_info.field_infos
k3Fields = ",".join([field_info.target_name for field_info in field_infos])
# 发送请求
response = _seession.post(
url=f"{origin_url}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc",
headers={
"Content-Type": "application/json;charset=UTF-8",
"Cookie": _cookie,
},
json={
"data": {
"FormId": form_id,
"FieldKeys": k3Fields,
"FilterString": None,
"StartRow": 0,
"Limit": 1000,
"TopRowCount": 100000,
"SubSystemId": ""
}
},
)
# 处理响应
data = response.json()
print(data)
def set_data(self, *args, **kwargs):
pass
if __name__ == "__main__":
k3cloud = K3CloudConnector()
k3cloud.auth()
k3cloud.get_data()
+1 -1
View File
@@ -205,7 +205,7 @@ async def get_supply(
summary="新增或修改供应记录(供应来源包含:生产生产计划PL、生产工单MO、库存ST、采购订单PO)",
description="根据🗝️【料号+供应号】新增或修改生产记录"
)
async def post_mat_production(
async def post_supply(
data: List[AcceptSupply],
db_name: str = common_params["db_name"]
):
+245 -111
View File
@@ -9,43 +9,40 @@ from config import uservar as uv
class AcceptMaterial(BaseModel):
materialno: str = Field(..., alias=uv.t_material.get("MaterialNo", "materialno"), description="料号")
description: str = Field(..., alias=uv.t_material.get("Description", "description"), description="物料名称")
size: str = Field(None, alias=uv.t_material.get("Size", "size"), description="规格")
materialno: str = Field(..., alias=uv.t_material.get("MaterialNo", "materialno"), description="料号", example="M001")
description: str = Field(..., alias=uv.t_material.get("Description", "description"), description="物料名称", example="测试物料A")
size: str = Field(None, alias=uv.t_material.get("Size", "size"), description="规格", example="100x100mm")
plant: str = Field(..., alias=uv.t_material.get("Plant", "plant"), example=uv.default_plant, description='工厂')
planner: str = Field(uv.default_planner, alias=uv.t_material.get("Planner", "planner"), description="计划员")
planner: str = Field(uv.default_planner, alias=uv.t_material.get("Planner", "planner"), description="计划员", example="张三")
fifo: int = Field(uv.default_fifo, alias=uv.t_material.get("FIFO", "fifo"), ge=0, le=1, description='1-FIFO 0-最近原则')
leadday: int = Field(alias=uv.t_material.get("LeadDay", "leadday"), ge=0, description="交期(天)")
expday: int = Field(uv.default_expday, alias=uv.t_material.get("ExpDay", "expday"), ge=0, description="保质期(天)")
grday: int = Field(alias=uv.t_material.get("GRDay", "grday"), ge=0, description="收货质检(天)")
leadday: int = Field(alias=uv.t_material.get("LeadDay", "leadday"), ge=0, description="交期(天)", example=7)
expday: int = Field(uv.default_expday, alias=uv.t_material.get("ExpDay", "expday"), ge=0, description="保质期(天)", example=365)
grday: int = Field(alias=uv.t_material.get("GRDay", "grday"), ge=0, description="收货质检(天)", example=1)
abc: str = Field(alias=uv.t_material.get("ABC", "abc"), enum=["A", "B", "C"], example="A", description="ABC分类")
unit: str = Field(alias=uv.t_material.get("Unit", "unit"), description='单位')
price: Decimal = Field(uv.default_price, alias=uv.t_material.get("Price", "price"), description="价格")
groupno: str = Field(..., alias=uv.t_material.get("GroupNo", "groupno"), description="型号")
unit: str = Field(alias=uv.t_material.get("Unit", "unit"), description='单位', example="PCS")
price: Decimal = Field(uv.default_price, alias=uv.t_material.get("Price", "price"), description="价格", example=100.50)
groupno: str = Field(..., alias=uv.t_material.get("GroupNo", "groupno"), description="型号", example="G001")
type: str = Field(... if uv.myaps_is_pro else None, alias=uv.t_material.get("type", "type"), enum=["E", "F"], example="E", description="物料类型 E-自制件 F-采购件")
phantom: str = Field(uv.default_phantom, alias=uv.t_material.get("Phantom", "phantom"), enum=["N", "Y"], example="N", description='虚拟件')
phantommin: int = Field(uv.default_phantommin, alias=uv.t_material.get("PhantomMin", "phantommin"), ge=0, description='虚拟时间(Minute)')
firmday: int = Field(uv.default_firmday, alias=uv.t_material.get("FirmDay", "firmday"), ge=0, description="固定天数")
daygap: int = Field(uv.default_daygap, alias=uv.t_material.get("DayGap", "daygap"), ge=0, description='MTO拆分天数')
phantommin: int = Field(uv.default_phantommin, alias=uv.t_material.get("PhantomMin", "phantommin"), ge=0, description='虚拟时间(Minute)', example=0)
firmday: int = Field(uv.default_firmday, alias=uv.t_material.get("FirmDay", "firmday"), ge=0, description="固定天数", example=0)
daygap: int = Field(uv.default_daygap, alias=uv.t_material.get("DayGap", "daygap"), ge=0, description='MTO拆分天数', example=1)
candelay: str = Field(uv.default_candelay, alias=uv.t_material.get("CanDelay", "candelay"), enum=["N", "Y"], example="N", description='可否延迟')
lotsize: str = Field(
uv.default_lotsize, alias=uv.t_material.get("LotSize", "lotsize"),
enum=["EX", "FX", "D1", "D2", "D3", "D4", "D5", "D6", "W1", "W2", "W3", "W4", "M1", "M2", "VB"],
example="EX", description='批量')
lotfix: float = Field(uv.default_lotfix, alias=uv.t_material.get("LotFix", "lotfix"), ge=0, description='固定批')
lotmin: float = Field(uv.default_lotmin, alias=uv.t_material.get("LotMin", "lotmin"), ge=0, description='最小批')
lotmax: float = Field(uv.default_lotmax, alias=uv.t_material.get("LotMax", "lotmax"), ge=0, description='最大批')
lotround: float = Field(uv.default_lotround, alias=uv.t_material.get("LotRound", "lotround"), ge=0, description='取整')
lotss: float = Field(uv.default_lotss, alias=uv.t_material.get("LotSS", "lotss"), ge=0, description='安全库存')
lotpoint: float = Field(uv.default_lotpoint, alias=uv.t_material.get("LotPoint", "lotpoint"), ge=0, description='重订货点')
lottop: float = Field(uv.default_lottop, alias=uv.t_material.get("LotTop", "lottop"), ge=0, description='最大库存点')
planitem: str = Field(None, alias=uv.t_material.get("PlanItem", "planitem"), description='产品组')
preday: int = Field(uv.default_preday, alias=uv.t_material.get("PreDay", "preday"), ge=0, description='向前冲销(天)')
subday: int = Field(uv.default_subday, alias=uv.t_material.get("SubDay", "subday"), ge=0, description='向后冲销(天)')
memo: str = Field(None,alias=uv.t_material.get("Memo", "memo"), description='备注')
# free1: str = Field(alias='Free1', max_length=255)
# free2: str = Field(alias='Free2', max_length=255)
# free3: str = Field(alias='Free3', max_length=255)
lotfix: float = Field(uv.default_lotfix, alias=uv.t_material.get("LotFix", "lotfix"), ge=0, description='固定批', example=0.0)
lotmin: float = Field(uv.default_lotmin, alias=uv.t_material.get("LotMin", "lotmin"), ge=0, description='最小批', example=0.0)
lotmax: float = Field(uv.default_lotmax, alias=uv.t_material.get("LotMax", "lotmax"), ge=0, description='最大批', example=0.0)
lotround: float = Field(uv.default_lotround, alias=uv.t_material.get("LotRound", "lotround"), ge=0, description='取整', example=0.0)
lotss: float = Field(uv.default_lotss, alias=uv.t_material.get("LotSS", "lotss"), ge=0, description='安全库存', example=0.0)
lotpoint: float = Field(uv.default_lotpoint, alias=uv.t_material.get("LotPoint", "lotpoint"), ge=0, description='重订货点', example=0.0)
lottop: float = Field(uv.default_lottop, alias=uv.t_material.get("LotTop", "lottop"), ge=0, description='最大库存点', example=0.0)
planitem: str = Field(None, alias=uv.t_material.get("PlanItem", "planitem"), description='产品组', example="PI001")
preday: int = Field(uv.default_preday, alias=uv.t_material.get("PreDay", "preday"), ge=0, description='向前冲销(天)', example=999)
subday: int = Field(uv.default_subday, alias=uv.t_material.get("SubDay", "subday"), ge=0, description='向后冲销(天)', example=999)
memo: str = Field(None,alias=uv.t_material.get("Memo", "memo"), description='备注', example="无特殊要求")
@field_validator("leadday")
def leadday_valid(cls, v, values):
@@ -67,156 +64,293 @@ class AcceptMaterial(BaseModel):
class Config:
title = "验证规则 - 物料"
json_schema_extra = {
"example": {
"materialno": "M001",
"description": "测试物料A",
"size": "100x100mm",
"plant": "1600",
"planner": "haida",
"fifo": 1,
"leadday": 7,
"expday": 365,
"grday": 1,
"abc": "A",
"unit": "PCS",
"price": 100.50,
"groupno": "G001",
"type": "E",
"phantom": "N",
"memo": "标准物料"
}
}
class AcceptWorkcenter(BaseModel):
workcenter: str = Field(..., alias=uv.t_workcenter.get("WorkCenter", "workcenter"), max_length=32, description="工作中心代码")
workcentername: str = Field(..., alias=uv.t_workcenter.get("WorkCenterName", "workcentername"), max_length=255, description="工作中心名称")
pri_wc: int = Field(1, alias=uv.t_workcenter.get("Pri_Wc", "pri_wc"), description='优先级')
workcenter: str = Field(..., alias=uv.t_workcenter.get("WorkCenter", "workcenter"), max_length=32, description="工作中心代码", example="WC001")
workcentername: str = Field(..., alias=uv.t_workcenter.get("WorkCenterName", "workcentername"), max_length=255, description="工作中心名称", example="装配车间")
pri_wc: int = Field(1, alias=uv.t_workcenter.get("Pri_Wc", "pri_wc"), description='优先级', example=1)
bottleneck: str = Field("N", alias=uv.t_workcenter.get("Bottleneck", "bottleneck"), enum=["N", "Y"], example="N", description='瓶颈')
sortno: str = Field(None, alias=uv.t_workcenter.get("SortNo", "sortno"), max_length=4, description="序号")
plant: str = Field(None, alias=uv.t_workcenter.get("Plant", "plant"), max_length=32, description="工厂")
location: str = Field(None, alias=uv.t_workcenter.get("Location", "location"), max_length=32, description="车间")
sortno: str = Field(None, alias=uv.t_workcenter.get("SortNo", "sortno"), max_length=4, description="序号", example="0001")
plant: str = Field(uv.default_plant, alias=uv.t_workcenter.get("Plant", "plant"), max_length=32, description="工厂", example="1600")
location: str = Field(None, alias=uv.t_workcenter.get("Location", "location"), max_length=32, description="车间", example="A区")
finite: str = Field(None, alias=uv.t_workcenter.get("Finite", "finite"), enum=["N", "Y"], example="N", description='有限')
type: str = Field(None, alias=uv.t_workcenter.get("Type", "type"), enum=["N", "Y"], example="N", description="首页显示")
capnum: int = Field(None, alias=uv.t_workcenter.get("CapNum", "capnum"), gt=0, description="默认机台数")
capmax: int = Field(None, alias=uv.t_workcenter.get("CapMax", "capmax"), gt=0, description="最大机台数")
worker: float = Field(None, alias=uv.t_workcenter.get("Worker", "worker"), ge=0, description='工时')
setupno: str = Field(None, alias=uv.t_workcenter.get("SetupNo", "setupno"), max_length=6, description='切换组别')
grpno: str = Field(None, alias=uv.t_workcenter.get("GrpNo", "grpno"), max_length=6, description='同组号')
memo: str = Field(None, alias=uv.t_workcenter.get("Memo", "memo"), max_length=255, description="备注")
capnum: int = Field(None, alias=uv.t_workcenter.get("CapNum", "capnum"), gt=0, description="默认机台数", example=5)
capmax: int = Field(None, alias=uv.t_workcenter.get("CapMax", "capmax"), gt=0, description="最大机台数", example=10)
worker: float = Field(None, alias=uv.t_workcenter.get("Worker", "worker"), ge=0, description='工时', example=8.0)
setupno: str = Field(None, alias=uv.t_workcenter.get("SetupNo", "setupno"), max_length=6, description='切换组别', example="S001")
grpno: str = Field(None, alias=uv.t_workcenter.get("GrpNo", "grpno"), max_length=6, description='同组号', example="G001")
memo: str = Field(None, alias=uv.t_workcenter.get("Memo", "memo"), max_length=255, description="备注", example="标准工作中心")
class Config:
title = "验证规则 - 工作中心"
json_schema_extra = {
"example": {
"workcenter": "WC001",
"workcentername": "装配车间",
"pri_wc": 1,
"bottleneck": "N",
"plant": "1600",
"capnum": 5,
"capmax": 10,
"worker": 8.0,
"memo": "标准工作中心"
}
}
@field_validator("sortno")
def sortno_valid(cls, v, values):
if v is None:
workcenter = values.get("workcenter")
v = uv.workcenter_sort.get(workcenter, workcenter)
return v
class AcceptMatWc(BaseModel):
materialno: str = Field(..., alias=uv.t_mat_wc.get("MaterialNo", "materialno"), max_length=64, description='料号')
materialno: str = Field(..., alias=uv.t_mat_wc.get("MaterialNo", "materialno"), max_length=64, description='料号', example="M001")
matver: str = Field(..., alias=uv.t_mat_wc.get("MatVer", "matver"), max_length=4, example=uv.example_matver, description='产线版本')
itemno: str = Field(..., alias=uv.t_mat_wc.get("ItemNo", "itemno"), max_length=6, description='工序项目')
workcenter: str = Field(..., alias=uv.t_mat_wc.get("WorkCenter", "workcenter"), max_length=32, description='工作中心')
sortno: int = Field(..., alias=uv.t_mat_wc.get("SortNo", "sortno"), ge=0, description='序号')
basesec: int = Field(..., alias=uv.t_mat_wc.get("BaseSec", "basesec"), ge=0, description='节拍T/T(秒/100)')
fixqty: int = Field(0, alias=uv.t_mat_wc.get("FixQty", "fixqty"), ge=0, description='额定量')
fixsec: int = Field(0, alias=uv.t_mat_wc.get("FixSec", "fixsec"), ge=0, description='额定时间(秒)')
itemno: str = Field(..., alias=uv.t_mat_wc.get("ItemNo", "itemno"), max_length=6, description='工序项目', example="0010")
workcenter: str = Field(..., alias=uv.t_mat_wc.get("WorkCenter", "workcenter"), max_length=32, description='工作中心', example="WC001")
sortno: int = Field(..., alias=uv.t_mat_wc.get("SortNo", "sortno"), ge=0, description='序号', example=1)
basesec: int = Field(..., alias=uv.t_mat_wc.get("BaseSec", "basesec"), ge=0, description='节拍T/T(秒/100)', example=600)
fixqty: int = Field(0, alias=uv.t_mat_wc.get("FixQty", "fixqty"), ge=0, description='额定量', example=100)
fixsec: int = Field(0, alias=uv.t_mat_wc.get("FixSec", "fixsec"), ge=0, description='额定时间(秒)', example=300)
sf: str = Field(..., alias=uv.t_mat_wc.get("SF", "sf"), enum=["S", "F"], example="F", description='并行S/串行F')
offsetsec: int = Field(0, alias=uv.t_mat_wc.get("OffsetSec", "offsetsec"), description='偏置+/-(秒)')
memo: str = Field(None, alias=uv.t_mat_wc.get("Memo", "memo"), max_length=255, description='备注')
offsetsec: int = Field(0, alias=uv.t_mat_wc.get("OffsetSec", "offsetsec"), description='偏置+/-(秒)', example=0)
memo: str = Field(None, alias=uv.t_mat_wc.get("Memo", "memo"), max_length=255, description='备注', example="标准工序")
class Config:
title = "验证规则 - 工序"
json_schema_extra = {
"example": {
"materialno": "M001",
"matver": "V1",
"itemno": "0010",
"workcenter": "WC001",
"sortno": 1,
"basesec": 600,
"fixqty": 100,
"fixsec": 300,
"sf": "F",
"offsetsec": 0,
"memo": "标准工序"
}
}
class AcceptMatVer(BaseModel):
materialno: str = Field(..., alias=uv.t_mat_ver.get("MaterialNo", "materialno"), max_length=64, description='料号')
materialno: str = Field(..., alias=uv.t_mat_ver.get("MaterialNo", "materialno"), max_length=64, description='料号', example="M001")
matver: str = Field(..., alias=uv.t_mat_ver.get("MatVer", "matver"), example=uv.example_matver, max_length=4, description='产线版本号')
lotfrom: int = Field(0, alias=uv.t_mat_ver.get("LotFrom", "lotfrom"), description='批量起点')
lotto: int = Field(9999999, alias=uv.t_mat_ver.get("LotTo", "lotto"), description='批量终点')
priority: int = Field(1, alias=uv.t_mat_ver.get("Priority", "priority"), description='优先级')
refno: str = Field(None, alias=uv.t_mat_ver.get("RefNo", "refno"), max_length=64, description='MTO订单号/认证线')
lotfrom: int = Field(0, alias=uv.t_mat_ver.get("LotFrom", "lotfrom"), description='批量起点', example=1)
lotto: int = Field(9999999, alias=uv.t_mat_ver.get("LotTo", "lotto"), description='批量终点', example=9999999)
priority: int = Field(1, alias=uv.t_mat_ver.get("Priority", "priority"), description='优先级', example=1)
refno: str = Field(None, alias=uv.t_mat_ver.get("RefNo", "refno"), max_length=64, description='MTO订单号/认证线', example="SO123456")
active: str = Field("Y", alias=uv.t_mat_ver.get("Active", "active"), enum=["N", "Y"], example="Y", description='生效')
memo: str = Field(None, alias=uv.t_mat_ver.get("Memo", "memo"), max_length=255, description='备注')
memo: str = Field(None, alias=uv.t_mat_ver.get("Memo", "memo"), max_length=255, description='备注', example="标准版本")
class Config:
title = "验证规则 - 产线版本"
json_schema_extra = {
"example": {
"materialno": "M001",
"matver": "V1",
"lotfrom": 1,
"lotto": 9999999,
"priority": 1,
"active": "Y",
"memo": "标准版本"
}
}
class AcceptMatWcBom(BaseModel):
productno: str = Field(..., alias=uv.t_mat_wc_bom.get("ProductNo", "productno"), max_length=64, description='产品料号')
productno: str = Field(..., alias=uv.t_mat_wc_bom.get("ProductNo", "productno"), max_length=64, description='产品料号', example="P001")
matver: str = Field(..., alias=uv.t_mat_wc_bom.get("MatVer", "matver"), example=uv.example_matver, max_length=4, description='产线版本')
itemno: str = Field(..., alias=uv.t_mat_wc_bom.get("ItemNo", "itemno"), max_length=6, description='工序项目')
materialno: str = Field(..., alias=uv.t_mat_wc_bom.get("MaterialNo", "materialno"), max_length=64, description='子件料号')
qty: float = Field(..., alias=uv.t_mat_wc_bom.get("Qty", "qty"), ge=0, description='数量')
offsethour: int = Field(0, alias=uv.t_mat_wc_bom.get("OffsetHour", "offsethour"), description='偏置+/-(小时)')
treeno: int = Field(None, alias=uv.t_mat_wc_bom.get("TreeNo", "treeno"), description='层级')
itemno: str = Field(..., alias=uv.t_mat_wc_bom.get("ItemNo", "itemno"), max_length=6, description='工序项目', example="0010")
materialno: str = Field(..., alias=uv.t_mat_wc_bom.get("MaterialNo", "materialno"), max_length=64, description='子件料号', example="M001")
qty: float = Field(..., alias=uv.t_mat_wc_bom.get("Qty", "qty"), ge=0, description='数量', example=2.0)
offsethour: int = Field(0, alias=uv.t_mat_wc_bom.get("OffsetHour", "offsethour"), description='偏置+/-(小时)', example=0)
treeno: int = Field(None, alias=uv.t_mat_wc_bom.get("TreeNo", "treeno"), description='层级', example=1)
mto: str = Field("N", alias=uv.t_mat_wc_bom.get("MTO", "mto"), enum=["N", "Y"], example="N", description='MTO')
scrap: float = Field(0, alias=uv.t_mat_wc_bom.get("Scrap", "scrap"), description='报废率%')
scrap: float = Field(0, alias=uv.t_mat_wc_bom.get("Scrap", "scrap"), description='报废率%', example=0.0)
alt: str = Field("N", alias=uv.t_mat_wc_bom.get("Alt", "alt"), enum=["N", "Y"], example="N", description='Y/N是否是替代')
memo: str = Field(None, alias=uv.t_mat_wc_bom.get("Memo", "memo"), max_length=255, description='备注')
memo: str = Field(None, alias=uv.t_mat_wc_bom.get("Memo", "memo"), max_length=255, description='备注', example="标准BOM组件")
class Config:
title = "验证规则 - BOM"
json_schema_extra = {
"example": {
"productno": "P001",
"matver": "V1",
"itemno": "0010",
"materialno": "M001",
"qty": 2.0,
"offsethour": 0,
"treeno": 1,
"mto": "N",
"scrap": 0.0,
"alt": "N",
"memo": "标准BOM组件"
}
}
class AcceptMold(BaseModel):
moldno: str = Field(..., alias=uv.t_mold.get("MoldNo", "moldno"), max_length=64, description='模具编号')
moldname: str = Field(..., alias=uv.t_mold.get("MoldName", "moldname"), max_length=64, description='模具名称')
type: str = Field(..., alias=uv.t_mold.get("Type", "type"), example=uv.example_matver, max_length=4, description='类型')
status: str = Field(..., alias=uv.t_mold.get("Status", "status"), max_length=6, description='状态')
moldnum: int = Field(..., alias=uv.t_mold.get("MoldNum", "moldnum"), ge=0, description='模具穴数')
qty: int = Field(..., alias=uv.t_mold.get("Qty", "qty"), ge=0, description='模具台数')
memo: str = Field(None, alias=uv.t_mold.get("Memo", "memo"), max_length=255, description="备注")
moldno: str = Field(..., alias=uv.t_mold.get("MoldNo", "moldno"), max_length=64, description='模具编号', example="MOLD001")
moldname: str = Field(..., alias=uv.t_mold.get("MoldName", "moldname"), max_length=64, description='模具名称', example="测试模具A")
type: str = Field(..., alias=uv.t_mold.get("Type", "type"), example="T1", max_length=4, description='类型')
status: str = Field(..., alias=uv.t_mold.get("Status", "status"), max_length=6, description='状态', example="AVL")
moldnum: int = Field(..., alias=uv.t_mold.get("MoldNum", "moldnum"), ge=0, description='模具穴数', example=4)
qty: int = Field(..., alias=uv.t_mold.get("Qty", "qty"), ge=0, description='模具台数', example=2)
memo: str = Field(None, alias=uv.t_mold.get("Memo", "memo"), max_length=255, description="备注", example="标准模具")
class Config:
title = "验证规则 - 模具"
json_schema_extra = {
"example": {
"moldno": "MOLD001",
"moldname": "测试模具A",
"type": "T1",
"status": "AVL",
"moldnum": 4,
"qty": 2,
"memo": "标准模具"
}
}
class AcceptMatWcMold(BaseModel):
materialno: str = Field(..., alias=uv.t_mat_wc_mold.get("MaterialNo", "materialno"), max_length=64, description='料号')
workcenter: str = Field(..., alias=uv.t_mat_wc_mold.get("WorkCenter", "workcenter"), max_length=64, description='工作中心')
moldno: str = Field(..., alias=uv.t_mat_wc_mold.get("MoldNo", "moldno"), max_length=64, description='模具编号')
basesec: int = Field(..., alias=uv.t_mat_wc_mold.get("BaseSec", "basesec"), ge=0, description='节拍T/T(秒/100)')
fixsec: int = Field(0, alias=uv.t_mat_wc_mold.get("FixSec", "fixsec"), ge=0, description='额定时间(秒)')
priority: int = Field(1, alias=uv.t_mat_wc_mold.get("Priority", "priority"), description='优先级')
memo: str = Field(None, alias=uv.t_mat_wc_mold.get("Memo", "memo"), max_length=255, description='备注')
materialno: str = Field(..., alias=uv.t_mat_wc_mold.get("MaterialNo", "materialno"), max_length=64, description='料号', example="M001")
workcenter: str = Field(..., alias=uv.t_mat_wc_mold.get("WorkCenter", "workcenter"), max_length=64, description='工作中心', example="WC001")
moldno: str = Field(..., alias=uv.t_mat_wc_mold.get("MoldNo", "moldno"), max_length=64, description='模具编号', example="MOLD001")
basesec: int = Field(..., alias=uv.t_mat_wc_mold.get("BaseSec", "basesec"), ge=0, description='节拍T/T(秒/100)', example=600)
fixsec: int = Field(..., alias=uv.t_mat_wc_mold.get("FixSec", "fixsec"), ge=0, description='额定时间(秒)', example=300)
priority: int = Field(..., alias=uv.t_mat_wc_mold.get("Priority", "priority"), description='优先级', example=1)
memo: str = Field(None, alias=uv.t_mat_wc_mold.get("Memo", "memo"), max_length=255, description='备注', example="标准机台模具配置")
class Config:
title = "验证规则 - 机台模具"
json_schema_extra = {
"example": {
"materialno": "M001",
"workcenter": "WC001",
"moldno": "MOLD001",
"basesec": 600,
"fixsec": 300,
"priority": 1,
"memo": "标准机台模具配置"
}
}
# @field_validator('priority')
# def validate_priority(cls, value):
# if value == 0:
# raise ValueError('优先级不能为0')
# return value
class AcceptSupply(BaseModel):
materialno: str = Field(..., alias=uv.t_supply.get("MaterialNo", "materialno"), max_length=64, description='料号')
supplyno: str = Field(..., alias=uv.t_supply.get("SupplyNo", "supplyno"), max_length=64, description='供应单号')
materialno: str = Field(..., alias=uv.t_supply.get("MaterialNo", "materialno"), max_length=64, description='料号', example="M001")
supplyno: str = Field(..., alias=uv.t_supply.get("SupplyNo", "supplyno"), max_length=64, description='供应单号', example="MO123456")
matver: Optional[str] = Field(None, alias=uv.t_supply.get("MatVer", "matver"), max_length=32, example=uv.example_matver, description='产线版本')
itemno: str = Field(None, alias=uv.t_supply.get("ItemNo", "itemno"), max_length=6, description='项目号')
itemno: str = Field(None, alias=uv.t_supply.get("ItemNo", "itemno"), max_length=6, description='项目号', example="0010")
type: str = Field(..., alias=uv.t_supply.get("Type", "type"), enum=["PL", "MO", "ST", "PO"], example="MO", description='类型 PL-生产计划 MO-生产工单 ST-库存 PO-采购订单')
category: str = Field(None, alias=uv.t_supply.get("Category", "category"), enum=["MTO", "MTS"], example="MTO", description='分类(MTO/MTS)')
priority: int = Field(1, alias=uv.t_supply.get("Priority", "priority"), description='优先级')
priority: int = Field(..., alias=uv.t_supply.get("Priority", "priority"), description='优先级', example=1)
status: str = Field(
None, alias=uv.t_supply.get("Status", "status"),
enum=["NEW", "CRE", "SCH", "REL", "PNF", "CMP"],
example="NEW", description='状态 NEW-新增 CRE-已创建 SCH-计划 REL-已发布 PNF-已报工, CMP-已完成')
avail_qty: float = Field(..., alias=uv.t_supply.get("Avail_Qty", "avail_qty"), ge=0, description='可用数量')
create_date: Optional[str] = Field(None, alias=uv.t_supply.get("Create_Date", "create_date"), description='创建日期')
avail_date: str = Field(..., alias=uv.t_supply.get("Avail_Date", "avail_date"), description='可用日期 / 开工日期')
dt_req: Optional[str] = Field(..., alias=uv.t_supply.get("DT_Req", "dt_req"), description='需求日期 / 完工日期')
avail_end_date: Optional[str] = Field(None, alias=uv.t_supply.get("Avail_End_Date", "avail_end_date"), description='可用结束日期')
batchno: Optional[str] = Field(None, alias=uv.t_supply.get("BatchNo", "batchno"), max_length=64, description='批次号')
vendorno: Optional[str] = Field(None, alias=uv.t_supply.get("VendorNo", "vendorno"), max_length=64, description='供应商编号')
partnerno: Optional[str] = Field(None, alias=uv.t_supply.get("PartnerNo", "partnerno"), max_length=64, description='合作商编号')
partnername: Optional[str] = Field(None, alias=uv.t_supply.get("PartnerName", "partnername"), max_length=255, description='合作商名称')
# free1: Optional[str] = Field(None, alias=fc.t_supply.get("free1", "free1"), max_length=255, description='自由字段1')
# free2: Optional[str] = Field(None, alias=fc.t_supply.get("free2", "free2"), max_length=255, description='自由字段2')
# free3: Optional[str] = Field(None, alias=fc.t_supply.get("free3", "free3"), max_length=255, description='自由字段3')
memo: Optional[str] = Field(None, alias=uv.t_supply.get("Memo", "memo"), max_length=255, description='备注')
# sys_date: Optional[str] = Field(None, alias=fc.t_supply.get("sys_date", "sys_date"), description='系统日期')
# sys_user: Optional[str] = Field(None, alias=fc.t_supply.get("sys_user", "sys_user"), max_length=32, description='系统用户')
# sys_stamp: Optional[str] = Field(None, alias=fc.t_supply.get("sys_stamp", "sys_stamp"), description='系统时间戳')
avail_qty: float = Field(..., alias=uv.t_supply.get("Avail_Qty", "avail_qty"), ge=0, description='可用数量', example=100.0)
create_date: Optional[str] = Field(None, alias=uv.t_supply.get("Create_Date", "create_date"), description='创建日期', example="2023-01-01")
avail_date: str = Field(..., alias=uv.t_supply.get("Avail_Date", "avail_date"), description='可用日期 / 开工日期', example="2023-01-01")
dt_req: Optional[str] = Field(..., alias=uv.t_supply.get("DT_Req", "dt_req"), description='需求日期 / 完工日期', example="2023-01-07")
avail_end_date: Optional[str] = Field(None, alias=uv.t_supply.get("Avail_End_Date", "avail_end_date"), description='可用结束日期', example="2023-01-07")
batchno: Optional[str] = Field(None, alias=uv.t_supply.get("BatchNo", "batchno"), max_length=64, description='批次号', example="BATCH001")
vendorno: Optional[str] = Field(None, alias=uv.t_supply.get("VendorNo", "vendorno"), max_length=64, description='供应商编号', example="V001")
partnerno: Optional[str] = Field(None, alias=uv.t_supply.get("PartnerNo", "partnerno"), max_length=64, description='合作商编号', example="P001")
partnername: Optional[str] = Field(None, alias=uv.t_supply.get("PartnerName", "partnername"), max_length=255, description='合作商名称', example="合作伙伴A")
memo: Optional[str] = Field(None, alias=uv.t_supply.get("Memo", "memo"), max_length=255, description='备注', example="标准供应单")
class Config:
title = "验证规则 - 供应"
json_schema_extra = {
"example": {
"materialno": "M001",
"supplyno": "MO123456",
"matver": "V1",
"itemno": "0010",
"type": "MO",
"category": "MTO",
"priority": 1,
"status": "NEW",
"avail_qty": 100.0,
"avail_date": "2023-01-01",
"dt_req": "2023-01-07",
"memo": "标准生产工单"
}
}
class AcceptDemand(BaseModel):
materialno: str = Field(..., alias=uv.t_demand.get("MaterialNo", "materialno"), max_length=64, description='料号')
demandno: str = Field(..., alias=uv.t_demand.get("DemandNo", "demandno"), max_length=64, description='需求单号')
itemno: str = Field(..., alias=uv.t_demand.get("ItemNo", "itemno"), max_length=6, description='项目号')
materialno: str = Field(..., alias=uv.t_demand.get("MaterialNo", "materialno"), max_length=64, description='料号', example="M001")
demandno: str = Field(..., alias=uv.t_demand.get("DemandNo", "demandno"), max_length=64, description='需求单号', example="SO123456")
itemno: str = Field(..., alias=uv.t_demand.get("ItemNo", "itemno"), max_length=6, description='项目号', example="0010")
type: str = Field(..., alias=uv.t_demand.get("Type", "type"), enum=["SO", "DM", "RS", "FC", "SS"], example="SO", description='类型 SO-销售订单 DM-计划需求 RS-工单预留 FC-预测 SS-安全库存')
category: str = Field(None, alias=uv.t_demand.get("Category", "category"), enum=["MTO", "MTS"], example="MTO", description='分类(MTO/MTS)')
priority: int = Field(..., alias=uv.t_demand.get("Priority", "priority"), description='优先级')
workcenter: str = Field(..., alias=uv.t_demand.get("WorkCenter", "workcenter"), max_length=32, description='工作中心')
priority: int = Field(..., alias=uv.t_demand.get("Priority", "priority"), description='优先级', example=1)
workcenter: str = Field(..., alias=uv.t_demand.get("WorkCenter", "workcenter"), max_length=32, description='工作中心', example="WC001")
status: str = Field(None, alias=uv.t_demand.get("Status", "status"), enum=["NEW", "CRE", "SCH", "REL", "PNF", "CMP"], example="NEW", description='状态 NEW-新增 CRE-已创建 SCH-计划 REL-已发布 PNF-已报工, CMP-已完成')
req_qty: float = Field(..., alias=uv.t_demand.get("Req_Qty", "req_qty"), le=0, description='需求数量')
# create_date: Optional[str] = Field(None, alias=fc.t_demand.get("Create_Date", "create_date"), description='创建日期')
req_date: datetime = Field(..., alias=uv.t_demand.get("Req_Date", "req_date"), description='需求日期')
refno: Optional[str] = Field(None, alias=uv.t_demand.get("RefNo", "refno"), max_length=64, description='MTO订单号')
partnerno: Optional[str] = Field(None, alias=uv.t_demand.get("PartnerNo", "partnerno"), max_length=64, description='合作商编号')
partnername: Optional[str] = Field(None, alias=uv.t_demand.get("PartnerName", "partnername"), max_length=255, description='合作商名称')
# altgrp: Optional[str] = Field(None, alias=fc.t_demand.get("AltGrp", "altgrp"), max_length=64, description='替代组')
# ori_itemno: Optional[str] = Field(None, alias=fc.t_demand.get("Ori_ItemNo", "ori_itemno"), max_length=6, description='原始项目号')
ori_qty: Optional[float] = Field(None, alias=uv.t_demand.get("Ori_Qty", "ori_qty"), ge=0, description='原始需求数量')
memo: Optional[str] = Field(None, alias=uv.t_demand.get("Memo", "memo"), max_length=255, description='备注')
req_qty: float = Field(..., alias=uv.t_demand.get("Req_Qty", "req_qty"), le=0, description='需求数量', example=-100.0)
req_date: datetime = Field(..., alias=uv.t_demand.get("Req_Date", "req_date"), description='需求日期', example="2023-01-07T10:00:00")
refno: Optional[str] = Field(None, alias=uv.t_demand.get("RefNo", "refno"), max_length=64, description='MTO订单号', example="MTO123456")
partnerno: Optional[str] = Field(None, alias=uv.t_demand.get("PartnerNo", "partnerno"), max_length=64, description='合作商编号', example="P001")
partnername: Optional[str] = Field(None, alias=uv.t_demand.get("PartnerName", "partnername"), max_length=255, description='合作商名称', example="客户A")
ori_qty: Optional[float] = Field(None, alias=uv.t_demand.get("Ori_Qty", "ori_qty"), ge=0, description='原始需求数量', example=100.0)
memo: Optional[str] = Field(None, alias=uv.t_demand.get("Memo", "memo"), max_length=255, description='备注', example="标准销售订单")
class Config:
title = "验证规则 - 需求"
json_schema_extra = {
"example": {
"materialno": "M001",
"demandno": "SO123456",
"itemno": "0010",
"type": "SO",
"category": "MTO",
"priority": 1,
"workcenter": "WC001",
"status": "NEW",
"req_qty": -100.0,
"req_date": "2023-01-07T10:00:00",
"refno": "MTO123456",
"ori_qty": 100.0,
"memo": "标准销售订单"
}
}
+3
View File
@@ -30,6 +30,9 @@ default_subday = 999 # 默认向后冲销(天)
example_matver = "V1"
workcenter_sort = {'SP-01':'A150','SP-02':'A160','JP-01':'B110','JP-02':'B120','JP-03':'B130','JP-04':'B140','JP-05':'B150','JP-06':'B160','JP-07':'B170','JP-08':'B180','JP-09':'B190','JP-10':'B200','JP-11':'B210','GJ-01':'C110','GJ-02':'C120','GJ-03':'C130','GJ-04':'C140','A-01':'DA01','A-02':'DA02','A-03':'DA03','A-04':'DA04','A-05':'DA05','A-06':'DA06','A-07':'DA07','B-01':'DB01','B-02':'DB02','B-03':'DB03','B-04':'DB04','B-05':'DB05','B-06':'DB06','B-07':'DB07','B-08':'DB08','B-09':'DB09','B-10':'DB10','C-01':'DC01','C-02':'DC02','C-03':'DC03','C-04':'DC04','C-05':'DC05','C-06':'DC06','C-07':'DC07','C-08':'DC08','C-09':'DC09','C-10':'DC10','C-11':'DC11','C-12':'DC12','C-13':'DC13','C-14':'DC14','C-15':'DC15','C-16':'DC16','D-01':'DD01','D-02':'DD02','D-03':'DD03','D-04':'DD04','D-05':'DD05','D-06':'DD06','D-07':'DD07','D-08':'DD08','D-09':'DD09','D-10':'DD10','D-11':'DD11','E-01':'DE01','E-02':'DE02','E-03':'DE03','E-04':'DE04','E-05':'DE05','E-06':'DE06','E-07':'DE07','E-08':'DE08','E-09':'DE09','E-10':'DE10','F-01':'DF01','F-02':'DF02','F-03':'DF03','F-04':'DF04','F-05':'DF05','F-06':'DF06','F-07':'DF07','F-08':'DF08','G-01':'DG01','G-02':'DG02','G-03':'DG03','G-04':'DG04','G-05':'DG05','ZDX-01':'E110','ZDX-02':'E120','ZDX-03':'E130','ZDX-04':'E140','ZDX-05':'E150','ZDX-06':'E160','ZDX-07':'E170','ZDX-08':'E180','ZDX-09':'E190','ZDX-10':'E200','ZDX-11':'E210','YZ-01':'E220','XM-01':'E230','XM-02':'E240','XM-03':'E250','XM-04':'E260','GZX-01':'E270','GZX-02':'E280','GZX-03':'E290','GZX-04':'E300','GZX-05':'E310','GZX-06':'E320','YZ-06':'E330','NTFX-01':'E340','DLS-01':'E350','YZ-20':'E360','HJ-01':'E370','YM-01':'E380','GZ-02':'E390','PM-01':'E400','TM-01':'E410','BZ-01':'E420','BZ-02':'E430','PQ-01':'E440'}
# 前后端字段映射关系,某些客户可能需要
# {数据库字段: 客户字段}
t_material = {
+53 -2
View File
@@ -16,7 +16,7 @@ from apps.io_api.common import register_exception_handlers
# 创建FastAPI应用实例
app = FastAPI(
title="MyAPS API",
description="MyAPS API",
description="MyAPS API系统接口文档,提供物料、工作中心、工序、BOM等主数据管理,以及供应需求等生产数据管理功能。",
version="1.0.0",
# 配置文档页面URL,禁用默认的 Swagger UI​,防止CDN资源不稳定导致无法访问文档页
docs_url=None,
@@ -24,9 +24,60 @@ app = FastAPI(
swagger_js_url="/static/swagger/swagger-ui-bundle.js",
swagger_css_url="/static/swagger/swagger-ui.css",
swagger_favicon_url="/static/swagger/favicon-32x32.png",
swagger_ui_parameters={"configUrl": None}
swagger_ui_parameters={
"configUrl": None,
"defaultModelsExpandDepth": 2, # 默认展开模型深度
"defaultModelExpandDepth": 3, # 默认展开模型属性深度
"displayRequestDuration": True, # 显示请求持续时间
"docExpansion": "list", # 文档展开方式: 'list', 'full', 'none'
"tryItOutEnabled": True, # 启用"Try it out"功能
"jsonEditor": True, # 使用JSON编辑器编辑请求体
"showCommonExtensions": True, # 显示扩展字段
"showExtensions": True, # 显示OpenAPI扩展
"showMutatedRequest": True # 显示修改后的请求
}
)
# 增强OpenAPI schema配置
app.openapi_version = "3.0.2"
# 保存原始的openapi方法
original_openapi = app.openapi
# 自定义OpenAPI schema生成
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
# 调用原始的openapi方法获取schema
openapi_schema = original_openapi()
# 确保所有schemas都有详细的描述和示例
for schema_name, schema in openapi_schema.get("components", {}).get("schemas", {}).items():
# 添加更多描述信息
if "properties" in schema:
for prop_name, prop in schema["properties"].items():
# 确保每个属性都有描述
if "description" not in prop and "title" not in prop:
prop["description"] = f"字段: {prop_name}"
# 确保每个属性都有示例值
if "example" not in prop and "examples" not in prop:
# 根据类型设置默认示例值
if prop.get("type") == "string":
prop["example"] = f"示例{prop_name}"
elif prop.get("type") == "integer":
prop["example"] = 1
elif prop.get("type") == "number":
prop["example"] = 1.0
elif prop.get("type") == "boolean":
prop["example"] = True
app.openapi_schema = openapi_schema
return app.openapi_schema
# 设置自定义的OpenAPI schema生成函数
app.openapi = custom_openapi
# 配置CORS中间件解决跨域访问问题
# app.add_middleware(
# CORSMiddleware,
@@ -1,39 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
# 只创建非抽象模型的表
# Storage是具体模型,需要创建表
# OptMaterial如果设置了managed=False,则不应创建表
sql = """
CREATE TABLE IF NOT EXISTS `a_storage` (
`id` SERIAL PRIMARY KEY,
`namespace` VARCHAR(64) NOT NULL,
`item` VARCHAR(256) NOT NULL,
`content` TEXT NOT NULL,
`remark` TEXT
);
-- OptMaterial表的创建根据模型设置决定
-- 如果models.py中设置了managed=False,这里应该注释掉表创建语句
CREATE TABLE IF NOT EXISTS `opt_material` (
`_id` SERIAL PRIMARY KEY,
`_oid` VARCHAR(64) NOT NULL,
`_createtime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`_updatetime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`_syncstatus` INTEGER NOT NULL DEFAULT 0,
`_synctime` TIMESTAMP,
`_sysprompt` TEXT
);
"""
return sql
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP TABLE IF EXISTS `opt_material`;
DROP TABLE IF EXISTS `a_storage`;
"""
@@ -0,0 +1,57 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE TABLE IF NOT EXISTS `opt_material` (
`_id` SERIAL NOT NULL,
`_oid` VARCHAR(32) NOT NULL,
`_createtime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`_updatetime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`_deletetime` TIMESTAMP NULL,
`_createby` VARCHAR(32) NULL,
`_updateby` VARCHAR(32) NULL,
`materialno` VARCHAR(32) NOT NULL,
`description` VARCHAR(200) NULL,
`rev` VARCHAR(32) NULL,
`dwgno` VARCHAR(32) NULL,
`dwgrev` VARCHAR(32) NULL,
`mattype` VARCHAR(32) NULL,
`model` VARCHAR(32) NULL,
`std` VARCHAR(32) NULL,
`unit` VARCHAR(16) NULL,
`weight` DECIMAL(10,4) NULL,
`length` DECIMAL(10,4) NULL,
`width` DECIMAL(10,4) NULL,
`height` DECIMAL(10,4) NULL,
`volumn` DECIMAL(10,4) NULL,
`color` VARCHAR(32) NULL,
`surface` VARCHAR(32) NULL,
`material` VARCHAR(32) NULL,
`supplier` VARCHAR(32) NULL,
`supplier_part_no` VARCHAR(32) NULL,
`manufacturer` VARCHAR(32) NULL,
`manufacturer_part_no` VARCHAR(32) NULL,
`cost_price` DECIMAL(10,4) NULL,
`sales_price` DECIMAL(10,4) NULL,
`currency` VARCHAR(16) NULL,
`remark` TEXT NULL,
`spec` TEXT NULL,
`attr1` VARCHAR(32) NULL,
`attr2` VARCHAR(32) NULL,
`attr3` VARCHAR(32) NULL,
`attr4` VARCHAR(32) NULL,
`attr5` VARCHAR(32) NULL,
PRIMARY KEY (`_id`),
UNIQUE KEY `idx_opt_material__oid` (`_oid`),
UNIQUE KEY `idx_opt_material_materialno` (`materialno`)
);
"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP TABLE IF EXISTS `opt_material`;
"""
@@ -1,17 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
-- This migration is redundant as it creates the same tables as the first migration
-- It's kept here for completeness
"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
-- No changes needed for downgrade
"""
+1
View File
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 665 B