flight-helper 0.0.3__tar.gz → 0.3.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {flight_helper-0.0.3 → flight_helper-0.3.6}/PKG-INFO +1 -1
  2. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/dto/booking.py +34 -28
  3. flight_helper-0.3.6/flight_helper/models/dto/http_schema.py +31 -0
  4. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/dto/itinerary.py +4 -6
  5. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/dto/passenger.py +10 -6
  6. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/dto/payment.py +64 -27
  7. flight_helper-0.3.6/flight_helper/models/dto/procurement.py +56 -0
  8. flight_helper-0.3.6/flight_helper/utils/__init__.py +11 -0
  9. flight_helper-0.3.6/flight_helper/utils/exception_utils.py +138 -0
  10. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper.egg-info/PKG-INFO +1 -1
  11. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper.egg-info/SOURCES.txt +3 -0
  12. {flight_helper-0.0.3 → flight_helper-0.3.6}/pyproject.toml +1 -1
  13. flight_helper-0.0.3/flight_helper/models/dto/procurement.py +0 -30
  14. {flight_helper-0.0.3 → flight_helper-0.3.6}/LICENSE +0 -0
  15. {flight_helper-0.0.3 → flight_helper-0.3.6}/README.md +0 -0
  16. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/__init__.py +0 -0
  17. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/__init__.py +0 -0
  18. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/models/dto/__init__.py +0 -0
  19. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/validator/__init__.py +0 -0
  20. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper/validator/type_validator.py +0 -0
  21. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper.egg-info/dependency_links.txt +0 -0
  22. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper.egg-info/requires.txt +0 -0
  23. {flight_helper-0.0.3 → flight_helper-0.3.6}/flight_helper.egg-info/top_level.txt +0 -0
  24. {flight_helper-0.0.3 → flight_helper-0.3.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flight_helper
3
- Version: 0.0.3
3
+ Version: 0.3.6
4
4
  Summary: flight helper python package
5
5
  Author-email: ckf10000 <ckf10000@sina.com>
6
6
  License: Apache License
@@ -11,17 +11,42 @@
11
11
  """
12
12
  from typing import Optional
13
13
  from flight_helper.validator.type_validator import parse_to_date_str
14
- from pydantic import BaseModel, model_validator, PositiveInt, PositiveFloat, NonNegativeFloat, Field, field_validator
14
+ from pydantic import BaseModel, model_validator, PositiveInt, NonNegativeFloat, Field, field_validator
15
15
 
16
16
 
17
- class OneWayBookingDTO(BaseModel):
17
+ class BookingInputDTO(BaseModel):
18
18
  # 平台信息
19
- book_domain: Optional[str] = Field(default=None, description="预订平台域名,例如:www.ceair.com")
20
- book_protocol: Optional[str] = Field(default=None, description="预订平台协议,例如:https")
19
+ book_domain: str = Field(..., description="预订平台域名,例如:www.ceair.com")
20
+ book_protocol: str = Field(..., description="预订平台协议,例如:https")
21
+
22
+ book_login_user: str = Field(..., description="预订平台登录用户")
23
+ book_password: str = Field(..., description="预订平台登录密码")
24
+
25
+ # 产品
26
+ product_type: str = Field(..., description="产品类型,如:经济舱、超级经济舱等")
27
+ product_name: Optional[str] = Field(default=None, description="产品名称,如:C919特惠,老年特惠")
28
+
29
+ sale_increase_threshold: NonNegativeFloat = Field(
30
+ default=0.0, description="涨价上限(相对于 sale_price 的绝对值或百分比?按业务定)"
31
+ )
32
+ sale_reduction_threshold: NonNegativeFloat = Field(
33
+ default=0.0, description="降价上限(相对于 sale_price 的绝对值或百分比?按业务定)"
34
+ )
35
+ standard_increase_threshold: NonNegativeFloat = Field(
36
+ default=0.0, description="涨价上限(相对于 standard_price 的绝对值或百分比?按业务定)"
37
+ )
38
+ standard_reduction_threshold: NonNegativeFloat = Field(
39
+ default=0.0, description="降价上限(相对于 standard_price 的绝对值或百分比?按业务定)"
40
+ )
21
41
 
22
- book_login_user: Optional[str] = Field(default=None, description="预订平台登录用户")
23
- book_password: Optional[str] = Field(default=None, description="预订平台登录密码")
42
+ # 服务联系人
43
+ specialist_name: Optional[str] = Field(default=None, description="退改联系人姓名")
44
+ specialist_mobile: Optional[str] = Field(default=None, description="电话")
45
+ specialist_email: Optional[str] = Field(default=None, description="邮箱")
24
46
 
47
+
48
+ class OneWayBookingDTO(BaseModel):
49
+ order_no: PositiveInt = Field(..., description="报表平台的订单号")
25
50
  # 航班信息
26
51
  dep_city: str = Field(..., description="起飞城市(中文)")
27
52
  arr_city: str = Field(..., description="抵达城市(中文)")
@@ -37,28 +62,9 @@ class OneWayBookingDTO(BaseModel):
37
62
  children: Optional[PositiveInt] = Field(default=None, description="儿童数量(如提供,必须 ≥1;未提供则视为无儿童)")
38
63
  infant: Optional[PositiveInt] = Field(default=None, description="婴儿数量(如提供,必须 ≥1;未提供则视为无婴儿)")
39
64
 
40
- # 产品与价格
41
- product_type: str = Field(..., description="产品类型,如:经济舱、超级经济舱等")
42
- product_name: Optional[str] = Field(default=None, description="产品名称,如:C919特惠,老年特惠")
43
- sale_price: Optional[PositiveFloat] = Field(default=None, description="预期销售价")
44
- standard_price: PositiveFloat = Field(..., description="预期票面价(应 ≥ sale_price)")
45
- sale_increase_threshold: Optional[NonNegativeFloat] = Field(
46
- default=0.00, description="涨价上限(相对于 sale_price 的绝对值或百分比?按业务定)"
47
- )
48
- sale_reduction_threshold: Optional[NonNegativeFloat] = Field(
49
- default=0.00, description="降价上限(相对于 sale_price 的绝对值或百分比?按业务定)"
50
- )
51
- standard_increase_threshold: Optional[NonNegativeFloat] = Field(
52
- default=0.00, description="涨价上限(相对于 standard_price 的绝对值或百分比?按业务定)"
53
- )
54
- standard_reduction_threshold: Optional[NonNegativeFloat] = Field(
55
- default=0.00, description="降价上限(相对于 standard_price 的绝对值或百分比?按业务定)"
56
- )
57
-
58
- # 服务联系人
59
- specialist_name: Optional[str] = Field(default=None, description="退改联系人姓名")
60
- specialist_mobile: Optional[str] = Field(default=None, description="电话")
61
- specialist_email: Optional[str] = Field(default=None, description="邮箱")
65
+ # 价格
66
+ sale_price: NonNegativeFloat = Field(default=0.0, description="预期销售价")
67
+ standard_price: NonNegativeFloat = Field(default=0.0, description="预期票面价(应 ≥ sale_price)")
62
68
 
63
69
  @field_validator("dep_date")
64
70
  @classmethod
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ # ---------------------------------------------------------------------------------------------------------
4
+ # ProjectName: python-flight-helper
5
+ # FileName: http_schema.py
6
+ # Description: http请求参数基础模型
7
+ # Author: ASUS
8
+ # CreateDate: 2026/01/13
9
+ # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
+ # ---------------------------------------------------------------------------------------------------------
11
+ """
12
+ from typing import Optional, Dict, Any
13
+ from pydantic import BaseModel, Field, PositiveInt, NonNegativeInt
14
+
15
+
16
+ class HTTPRequestDTO(BaseModel):
17
+ # 平台信息
18
+ http_domain: Optional[str] = Field(default=None, description="平台域名,例如:www.ceair.com")
19
+ http_protocol: Optional[str] = Field(default=None, description="平台协议,例如:https")
20
+ storage_state: Optional[Dict[str, Any]] = Field(
21
+ default=None, description="playwright 爬取的用户登录状态没礼貌包含了cookie和origin"
22
+ )
23
+ timeout: Optional[PositiveInt] = Field(default=60, description="请求超时时间")
24
+ retry: Optional[NonNegativeInt] = Field(default=0, description="重试次数")
25
+ enable_log: Optional[bool] = Field(default=True, description="是否打印日志")
26
+ token: Optional[str] = Field(default=None, description="token值")
27
+ json_data: Optional[Dict[str, Any]] = Field(default=None, description="json参数")
28
+ params_data: Optional[Dict[str, Any]] = Field(default=None, description="params参数")
29
+ data: Optional[Dict[str, Any]] = Field(default=None, description="data参数")
30
+ proxy: Optional[Dict[str, Any]] = Field(default=None, description="http的代理配置")
31
+ headers: Optional[Dict[str, Any]] = Field(default=None, description="自定义的http headers")
@@ -9,9 +9,8 @@
9
9
  # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
10
  # ---------------------------------------------------------------------------------------------------------
11
11
  """
12
- from aiohttp import CookieJar
13
12
  from typing import Optional, List, Dict, Any
14
- from pydantic import BaseModel, NonNegativeFloat, Field, field_validator
13
+ from pydantic import BaseModel, NonNegativeFloat, Field, field_validator, PositiveInt
15
14
 
16
15
 
17
16
  class ItineraryInfoDTO(BaseModel):
@@ -23,16 +22,16 @@ class ItineraryInfoDTO(BaseModel):
23
22
 
24
23
 
25
24
  class QueryItineraryResponseDTO(BaseModel):
26
- order_no: Optional[str] = Field(default=None, description="业务平台订单号")
25
+ order_no: Optional[PositiveInt] = Field(default=None, description="业务平台订单号")
27
26
  pre_order_no: str = Field(..., description="采购平台订单号")
28
27
  order_status: Optional[str] = Field(default=None, description="采购平台订单状态")
29
- order_amount: Optional[NonNegativeFloat] = Field(default=None, description="采购平台订单金额")
28
+ order_amount: NonNegativeFloat = Field(default=0.0, description="采购平台订单金额")
30
29
  cash_unit: Optional[str] = Field(default=None, description="采购金额的币种")
31
30
  itinerary_info: List[ItineraryInfoDTO] = Field(..., description="乘客行程单信息")
32
31
 
33
32
  @field_validator("itinerary_info")
34
33
  @classmethod
35
- def validate_non_empty(cls, info, v: List[ItineraryInfoDTO]):
34
+ def validate_non_empty(cls, v: List[ItineraryInfoDTO], info):
36
35
  if len(v) == 0:
37
36
  raise ValueError("至少需要一个乘客行程")
38
37
  # 获取外层的 pre_order_no
@@ -55,4 +54,3 @@ class QueryItineraryRequestDTO(BaseModel):
55
54
  user_id: Optional[str] = Field(default=None, description="采购平台登录用户的ID")
56
55
  proxy: Optional[Dict[str, Any]] = Field(default=None, description="http的代理配置")
57
56
  headers: Optional[Dict[str, Any]] = Field(default=None, description="自定义的http headers")
58
- cookie_jar: Optional[CookieJar] = Field(default=None, description="自定义的CookieJar对象")
@@ -10,10 +10,11 @@
10
10
  # ---------------------------------------------------------------------------------------------------------
11
11
  """
12
12
  from typing import Optional, Literal
13
- from pydantic import BaseModel, Field
13
+ from pydantic import BaseModel, Field, PositiveInt
14
14
 
15
15
 
16
16
  class PassengerDTO(BaseModel):
17
+ segment_index: PositiveInt = Field(..., description="航段索引")
17
18
  # 乘客基本信息
18
19
  passenger_type: Literal["成人", "儿童", "婴儿"] = Field(
19
20
  ..., description="乘客类型,必须是:成人、儿童 或 婴儿"
@@ -21,14 +22,17 @@ class PassengerDTO(BaseModel):
21
22
  passenger_name: str = Field(
22
23
  ..., description="乘客法定姓名(按证件填写),如:Zhang San 或 张三"
23
24
  )
24
- passenger_alias: Optional[str] = Field(
25
- default=None,
26
- description="乘客中文常用名(仅外国人使用),如:汤姆(对应 Tom)"
27
- )
28
-
29
25
  # 性别与证件
30
26
  gender: Literal["男", "女"] = Field(..., description='性别,只能是"男"或"女"')
31
27
  id_type: Literal["身份证", "港澳通行证", "护照", "军官证", "回乡证"] = Field(
32
28
  ..., description='证件类型'
33
29
  )
34
30
  id_number: str = Field(..., description="证件号码(按证件如实填写)")
31
+
32
+ passenger_id: Optional[str] = Field(default=None, description="乘客ID")
33
+ flight_id: Optional[str] = Field(default=None, description="乘客航段ID")
34
+ table_id: Optional[str] = Field(default=None, description="乘客制表ID")
35
+ passenger_alias: Optional[str] = Field(
36
+ default=None,
37
+ description="乘客中文常用名(仅外国人使用),如:汤姆(对应 Tom)"
38
+ )
@@ -10,28 +10,31 @@
10
10
  # ---------------------------------------------------------------------------------------------------------
11
11
  """
12
12
  from typing import Literal, Optional, Union, Annotated
13
- from pydantic import BaseModel, Field, TypeAdapter, NonNegativeFloat
13
+ from pydantic import BaseModel, Field, TypeAdapter, NonNegativeFloat, PositiveInt
14
14
 
15
- SupportedChannels = Literal["微信", "支付宝", "汇付天下", "易宝支付"]
15
+ SupportedChannels = Literal["微信", "支付宝", "汇付天下", "易宝支付", "空中云汇", "快钱"]
16
16
 
17
17
 
18
18
  class __BasePaymentDTO(BaseModel):
19
- pay_domain: Optional[str] = Field(default=None, description="支付在线收银台域名,例如:www.ceair.com")
20
- pay_protocol: Optional[str] = Field(default=None, description="支付在线收银台协议,例如:https")
21
-
22
- channel_name: SupportedChannels = Field(
23
- ..., description=f'支付渠道,只能是其中之一:{SupportedChannels}'
24
- )
19
+ channel_name: SupportedChannels = Field(..., description=f'支付渠道,只能是其中之一:{SupportedChannels}')
25
20
  payment_type: str = Field(..., description="支付方式")
26
- order_no: str = Field(..., description="报表平台订单号")
27
- pre_order_no: Optional[str] = Field(default=None, description="采购平台订单号")
28
21
  account: Optional[str] = Field(default=None, description="支付账号")
29
22
  password: Optional[str] = Field(default=None, description="账号密码")
23
+
24
+
25
+ class PaymentResultDTO(__BasePaymentDTO):
26
+ order_no: PositiveInt = Field(..., description="报表平台订单号")
27
+ pre_order_no: Optional[str] = Field(default=None, description="采购平台订单号")
30
28
  pay_transaction: Optional[str] = Field(default=None, description="支付流水")
31
- pay_amount: Optional[NonNegativeFloat] = Field(default=None, description="支付金额")
29
+ pay_amount: NonNegativeFloat = Field(default=0.0, description="支付金额")
32
30
 
33
31
 
34
- class YBAccountPaymentDTO(__BasePaymentDTO):
32
+ class __BasePaymentInputDTO(__BasePaymentDTO):
33
+ pay_domain: Optional[str] = Field(default=None, description="支付在线收银台域名,例如:www.ceair.com")
34
+ pay_protocol: Optional[str] = Field(default=None, description="支付在线收银台协议,例如:https")
35
+
36
+
37
+ class YBAccountPaymentInputDTO(__BasePaymentInputDTO):
35
38
  """易宝支付-账号支付"""
36
39
  channel_name: Literal["易宝支付"] = Field(..., description="支付渠道")
37
40
  payment_type: Literal["账户支付"] = Field(..., description="支付方式")
@@ -39,17 +42,17 @@ class YBAccountPaymentDTO(__BasePaymentDTO):
39
42
  password: str = Field(..., description="账号密码")
40
43
 
41
44
 
42
- class WeChatPaymentDTO(__BasePaymentDTO):
45
+ class WeChatPaymentInputDTO(__BasePaymentInputDTO):
43
46
  channel_name: Literal["微信"] = Field(..., description="支付渠道")
44
47
  payment_type: Literal["二维码识别"] = Field(..., description="支付方式")
45
48
 
46
49
 
47
- class AlipayPaymentDTO(__BasePaymentDTO):
50
+ class AlipayPaymentInputDTO(__BasePaymentInputDTO):
48
51
  channel_name: Literal["支付宝"] = Field(..., description="支付渠道")
49
52
  payment_type: Literal["二维码识别"] = Field(..., description="支付方式")
50
53
 
51
54
 
52
- class HFPaidAccountPaymentDTO(__BasePaymentDTO):
55
+ class HFPaidAccountPaymentInputDTO(__BasePaymentInputDTO):
53
56
  """汇付天下-付款账户支付"""
54
57
  channel_name: Literal["汇付天下"] = Field(..., description="支付渠道")
55
58
  payment_type: Literal["付款账户支付"] = Field(..., description="支付方式")
@@ -57,13 +60,48 @@ class HFPaidAccountPaymentDTO(__BasePaymentDTO):
57
60
  password: str = Field(..., description="操作员交易密码")
58
61
 
59
62
 
63
+ class AirwallexVCCPaymentInputDTO(__BasePaymentInputDTO):
64
+ """空中云汇-VCC支付"""
65
+ channel_name: Literal["空中云汇"] = Field(..., description="支付渠道")
66
+ payment_type: Literal["VCC"] = Field(..., description="支付方式")
67
+
68
+
69
+ class Bill99AccountPaymentInputDTO(__BasePaymentInputDTO):
70
+ """快钱-快钱账户支付"""
71
+ channel_name: Literal["快钱"] = Field(..., description="支付渠道")
72
+ payment_type: Literal["快钱账户"] = Field(..., description="支付方式")
73
+ account: str = Field(..., description="快钱账户")
74
+
75
+
76
+ class AirwallexVCCPaymentInfoDTO(AirwallexVCCPaymentInputDTO):
77
+ first_name: str = Field(..., description="名字")
78
+ last_name: str = Field(..., description="姓氏")
79
+ id_number: str = Field(..., description="证件号码")
80
+ email: str = Field(..., description="电子邮箱")
81
+ mobile: str = Field(..., description="手机号码")
82
+ id_type: str = Field(..., description="证件类型")
83
+ country: str = Field(..., description="国家/地区")
84
+ state: str = Field(..., description="省/州")
85
+ city: str = Field(..., description="城市")
86
+ street: str = Field(..., description="街道名称")
87
+ house_number: str = Field(..., description="门牌号码")
88
+ postal_code: str = Field(..., description="邮编")
89
+ card_number: Optional[str] = Field(default=None, description="卡号")
90
+ expiry_year: Optional[PositiveInt] = Field(default=None, description="有效年份")
91
+ expiry_month: Optional[PositiveInt] = Field(default=None, description="有效月份")
92
+ card_id: Optional[str] = Field(..., description="虚拟卡ID")
93
+ cvv: Optional[str] = Field(..., description="cvv")
94
+
95
+
60
96
  # 3. 创建联合类型,并指定 discriminator
61
- PaymentRuestDTO = Annotated[
97
+ PaymentInputDTO = Annotated[
62
98
  Union[
63
- YBAccountPaymentDTO,
64
- WeChatPaymentDTO,
65
- AlipayPaymentDTO,
66
- HFPaidAccountPaymentDTO,
99
+ YBAccountPaymentInputDTO,
100
+ WeChatPaymentInputDTO,
101
+ AlipayPaymentInputDTO,
102
+ HFPaidAccountPaymentInputDTO,
103
+ AirwallexVCCPaymentInputDTO,
104
+ Bill99AccountPaymentInputDTO
67
105
  # TODO ... 其他支付方式
68
106
  ],
69
107
  Field(discriminator='channel_name') # 或者用 'payment_type',看业务
@@ -71,27 +109,26 @@ PaymentRuestDTO = Annotated[
71
109
 
72
110
  if __name__ == '__main__':
73
111
  # 创建适配器
74
- adapter = TypeAdapter(PaymentRuestDTO)
112
+ adapter = TypeAdapter(PaymentInputDTO)
75
113
 
76
114
  # 测试 1: 易宝支付
77
115
  yb_data = {
78
- "order_no": "1312312",
116
+ "order_no": 1312312,
79
117
  "channel_name": "易宝支付",
80
118
  "payment_type": "账户支付",
81
119
  "account": "yb123",
82
- "password": "pass123"
120
+ "password": "pass123",
121
+ "pay_amount": 0.00
83
122
  }
84
- yb = YBAccountPaymentDTO(**yb_data)
85
- yb.pay_transaction = "112312"
123
+ yb = PaymentResultDTO(**yb_data)
86
124
  print(yb)
87
125
  yb_payment = adapter.validate_python(yb_data)
88
- yb_payment.pay_transaction = "123123123"
89
126
  print(yb_payment)
90
127
  print(type(yb_payment)) # <class '__main__.YBAccountPayment'>
91
128
 
92
129
  # 测试 2: 微信支付
93
130
  wx_data = {
94
- "order_no": "1312312",
131
+ "order_no": 1312312,
95
132
  "channel_name": "微信",
96
133
  "payment_type": "二维码识别",
97
134
  # account/password 可省略(Optional)
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ # ---------------------------------------------------------------------------------------------------------
4
+ # ProjectName: python-flight-helper
5
+ # FileName: procurement.py
6
+ # Description: 采购信息数据转换对象
7
+ # Author: ASUS
8
+ # CreateDate: 2026/01/08
9
+ # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
+ # ---------------------------------------------------------------------------------------------------------
11
+ """
12
+ from typing import Optional, List, Literal
13
+ from pydantic import BaseModel, PositiveInt, NonNegativeFloat, Field
14
+
15
+
16
+ class ProcurementInputDTO(BaseModel):
17
+ # 平台信息
18
+ pl_domain: str = Field(..., description="平台域名,例如:www.ceair.com")
19
+ pl_protocol: str = Field(..., description="平台协议,例如:https")
20
+ out_ticket_platform_type: str = Field(..., description="出票平台类型")
21
+ out_ticket_platform: str = Field(..., description="出票平台")
22
+ account_number: str = Field(..., description="出票账号")
23
+ type_name: str = Field(..., description="采购账号类型")
24
+ purchase_account: str = Field(..., description="采购账号")
25
+ pl_login_user: str = Field(..., description="采购平台登录账号")
26
+ pl_login_password: str = Field(..., description="采购平台登录密码")
27
+ remark: str = Field(..., description="备注,一般是由采购平台登录账号 + 采购平台登录密码拼接而成")
28
+
29
+ out_ticket_account: Optional[str] = Field(default=None, description="账号")
30
+ out_ticket_account_id: Optional[int] = Field(default=None, description="账号ID")
31
+ out_ticket_account_password: Optional[str] = Field(default=None, description="密码")
32
+ purchase_account_id: Optional[int] = Field(default=None, description="采购账号ID")
33
+ out_ticket_platform_type_id: Optional[int] = Field(default=None, description="出票平台类型ID")
34
+ out_ticket_mobile: Optional[str] = Field(default=None, description="出票手机,退改业务需要根据此手机号码来进行操作")
35
+
36
+
37
+ class ProcurementReusltDTO(BaseModel):
38
+ # 平台信息
39
+ order_no: PositiveInt = Field(..., description="报表平台的订单号")
40
+ air_co_order_id: str = Field(..., description="官网订单号")
41
+ transaction_amount: NonNegativeFloat = Field(..., description="采购金额")
42
+ passenger_type: Literal["成人", "儿童", "婴儿"] = Field(
43
+ ..., description="乘客类型,必须是:成人、儿童 或 婴儿"
44
+ )
45
+
46
+ passenger_names: Optional[List[str]] = Field(default=None, description="采购乘客")
47
+ segment_index: Optional[PositiveInt] = Field(default=None, description="航段索引")
48
+ flight_ids: Optional[str] = Field(default=None, description="乘客航段ID")
49
+ passenger_ids: Optional[List[str]] = Field(default=None, description="乘客ID列表")
50
+ pay_transaction: Optional[str] = Field(default=None, description="对账标识")
51
+
52
+
53
+ class FillProcurementInputDTO(ProcurementInputDTO, ProcurementReusltDTO):
54
+ order_no: Optional[PositiveInt] = Field(default=None, description="报表平台的订单号")
55
+ transaction_amount: Optional[NonNegativeFloat] = Field(default=None, description="采购金额")
56
+ air_co_order_id: Optional[str] = Field(default=None, description="官网订单号")
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ # ---------------------------------------------------------------------------------------------------------
4
+ # ProjectName: python-flight-helper
5
+ # FileName: __init__.py
6
+ # Description: 工具包
7
+ # Author: ASUS
8
+ # CreateDate: 2026/01/11
9
+ # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
+ # ---------------------------------------------------------------------------------------------------------
11
+ """
@@ -0,0 +1,138 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ # ---------------------------------------------------------------------------------------------------------
4
+ # ProjectName: python-flight-helper
5
+ # FileName: exception_utils.py
6
+ # Description: 异常类工具模块
7
+ # Author: ASUS
8
+ # CreateDate: 2026/01/11
9
+ # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
+ # ---------------------------------------------------------------------------------------------------------
11
+ """
12
+ from typing import Literal
13
+
14
+
15
+ class DuplicatePaymentError(Exception):
16
+ def __init__(self, order_no: int):
17
+ self.order_no = order_no
18
+ super().__init__(f"订单<{order_no}>重复支付")
19
+
20
+
21
+ class DuplicateBookingError(Exception):
22
+ def __init__(self, message):
23
+ super().__init__(message)
24
+
25
+
26
+ class NotEnoughTicketsError(Exception):
27
+ def __init__(self, flight_no: str, seats_status: int, passengers: int):
28
+ self.flight_no = flight_no
29
+ self.seats_status = seats_status
30
+ self.passengers = passengers
31
+ super().__init__(f"采购平台显示航班<{flight_no}>的余票<{seats_status}>少于乘客人数<{passengers}>")
32
+
33
+
34
+ class ExcessiveProfitdError(Exception):
35
+ def __init__(
36
+ self, flight_no: str, query_price: float, order_price: float, reduction_threshold: float,
37
+ asset: Literal["票面价", "销售价"] = "票面价"
38
+ ):
39
+ self.flight_no = flight_no
40
+ self.query_price = query_price
41
+ self.order_price = order_price
42
+ self.reduction_threshold = reduction_threshold
43
+ self.asset = asset
44
+ super().__init__(
45
+ f"航班<{flight_no}>采购平台价:{query_price} 低于:订单{asset}[{order_price}] - 下降阈值[{reduction_threshold}],收益过高"
46
+ )
47
+
48
+
49
+ class ExcessiveLossesError(Exception):
50
+ def __init__(
51
+ self, flight_no: str, query_price: float, order_price: float, increase_threshold: float,
52
+ asset: Literal["票面价", "销售价"] = "票面价"
53
+ ):
54
+ self.flight_no = flight_no
55
+ self.query_price = query_price
56
+ self.order_price = order_price
57
+ self.increase_threshold = increase_threshold
58
+ self.asset = asset
59
+ super().__init__(
60
+ f"航班<{flight_no}>官网价:{query_price} 高于:订单{asset}[{order_price}] + 上浮阈值[{increase_threshold}],亏损太多"
61
+ )
62
+
63
+
64
+ class PaymentChannelError(Exception):
65
+ def __init__(self, channel_name: str):
66
+ self.channel_name = channel_name
67
+ super().__init__(f"支付渠道<{channel_name}>暂不支持")
68
+
69
+
70
+ class PaymentChannelMissError(Exception):
71
+ def __init__(self):
72
+ super().__init__(f"支付渠道参数丢失")
73
+
74
+
75
+ class PaymentTypeError(Exception):
76
+ def __init__(self, payment_type: str):
77
+ self.payment_type = payment_type
78
+ super().__init__(f"付款方式<{payment_type}>暂不支持")
79
+
80
+
81
+ class PassengerTypeError(Exception):
82
+ def __init__(self, passenger_type: str):
83
+ self.passenger_type = passenger_type
84
+ super().__init__(f"乘客类型<{passenger_type}>暂不支持")
85
+
86
+
87
+ class ProductTypeError(Exception):
88
+ def __init__(self, product_type: str):
89
+ self.product_type = product_type
90
+ super().__init__(f"产品类型<{product_type}>暂不支持")
91
+
92
+
93
+ class HFPaymentTypeError(Exception):
94
+ def __init__(self, payment_type: str):
95
+ self.payment_type = payment_type
96
+ super().__init__(f"汇付天下的付款方式<{payment_type}>暂不支持")
97
+
98
+
99
+ class PaymentFailedError(Exception):
100
+ def __init__(self, pre_order_no: str, order_status: str):
101
+ self.pre_order_no = pre_order_no
102
+ self.order_status = order_status
103
+ super().__init__(f"采购平台订单<{pre_order_no}>支付失败,支付结束后的状态<{order_status}>")
104
+
105
+
106
+ class PaymentFailError(Exception):
107
+ def __init__(self, message: str):
108
+ self.message = message
109
+ super().__init__(message)
110
+
111
+
112
+ class IPBlockError(Exception):
113
+
114
+ def __init__(self, message: str):
115
+ self.message = message
116
+ super().__init__(message)
117
+
118
+
119
+ class RelationOrderConflictError(Exception):
120
+
121
+ def __init__(self, message: str):
122
+ super().__init__(message)
123
+
124
+ class LockedOrderFailedError(Exception):
125
+
126
+ def __init__(self, message: str):
127
+ super().__init__(message)
128
+
129
+
130
+ class OrderLimitError(Exception):
131
+ def __init__(self, user_id: str, message: str):
132
+ self.user_id = user_id
133
+ super().__init__(f"用户<{user_id}>已受限,{message}")
134
+
135
+ class UserNotLoginError(Exception):
136
+
137
+ def __init__(self, message: str):
138
+ super().__init__(message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flight_helper
3
- Version: 0.0.3
3
+ Version: 0.3.6
4
4
  Summary: flight helper python package
5
5
  Author-email: ckf10000 <ckf10000@sina.com>
6
6
  License: Apache License
@@ -10,9 +10,12 @@ flight_helper.egg-info/top_level.txt
10
10
  flight_helper/models/__init__.py
11
11
  flight_helper/models/dto/__init__.py
12
12
  flight_helper/models/dto/booking.py
13
+ flight_helper/models/dto/http_schema.py
13
14
  flight_helper/models/dto/itinerary.py
14
15
  flight_helper/models/dto/passenger.py
15
16
  flight_helper/models/dto/payment.py
16
17
  flight_helper/models/dto/procurement.py
18
+ flight_helper/utils/__init__.py
19
+ flight_helper/utils/exception_utils.py
17
20
  flight_helper/validator/__init__.py
18
21
  flight_helper/validator/type_validator.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flight_helper" # pip包名(不要大写)
7
- version = "0.0.3" # 版本号
7
+ version = "0.3.6" # 版本号
8
8
  description = "flight helper python package"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12" # Python 版本要求
@@ -1,30 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- # ---------------------------------------------------------------------------------------------------------
4
- # ProjectName: python-flight-helper
5
- # FileName: procurement.py
6
- # Description: 采购信息数据转换对象
7
- # Author: ASUS
8
- # CreateDate: 2026/01/08
9
- # Copyright ©2011-2026. Hunan xxxxxxx Company limited. All rights reserved.
10
- # ---------------------------------------------------------------------------------------------------------
11
- """
12
- from typing import Optional
13
- from pydantic import BaseModel, PositiveInt, NegativeFloat, Field
14
-
15
-
16
- class ProcurementDTO(BaseModel):
17
- # 平台信息
18
- pl_domain: Optional[str] = Field(default=None, description="平台域名,例如:www.ceair.com")
19
- pl_protocol: Optional[str] = Field(default=None, description="平台协议,例如:https")
20
- order_no: PositiveInt = Field(..., description="订单号")
21
- out_ticket_platform_type: str = Field(..., description="出票平台类型")
22
- out_ticket_platform: str = Field(..., description="出票平台")
23
- out_ticket_account: str = Field(..., description="出票账号")
24
- purchase_account_type: str = Field(..., description="采购账号类型")
25
- purchase_account: str = Field(..., description="采购账号")
26
- purchase_amount: NegativeFloat = Field(..., description="采购金额")
27
- remark: str = Field(..., description="备注,一般是由采购平台账号 + 账号密码拼接而成")
28
- out_ticket_mobile: str = Field(..., description="出票手机,退改业务需要根据此手机号码来进行操作")
29
- pay_transaction: str = Field(..., description="支付流水")
30
- pre_order_no: str = Field(..., description="采购平台订单号")
File without changes
File without changes
File without changes