ey-commerce-lib 1.0.14__py3-none-any.whl → 1.0.15__py3-none-any.whl

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.

Potentially problematic release.


This version of ey-commerce-lib might be problematic. Click here for more details.

@@ -1,6 +1,8 @@
1
1
  import asyncio
2
+ import time
2
3
 
3
4
  from httpx import AsyncClient, Timeout
5
+ from playwright.async_api import async_playwright
4
6
 
5
7
  from ey_commerce_lib.dxm.constant.order import DxmOrderRuleType
6
8
  from ey_commerce_lib.dxm.parser.common import get_page_info, get_purchase_pagination_info
@@ -24,7 +26,8 @@ class DxmClient:
24
26
  self.__headers = headers
25
27
  self.__sem = asyncio.Semaphore(sem)
26
28
  timeout = Timeout(connect=5.0, read=20.0, write=10.0, pool=10.0)
27
- self.__async_client = AsyncClient(base_url="https://www.dianxiaomi.com", cookies=cookies, headers=headers,
29
+ self.__base_url = 'https://www.dianxiaomi.com'
30
+ self.__async_client = AsyncClient(base_url=self.__base_url, cookies=cookies, headers=headers,
28
31
  timeout=timeout)
29
32
 
30
33
  async def page_order_base_async(self, query: DxmOrderSearchForm):
@@ -694,6 +697,42 @@ class DxmClient:
694
697
  data=data)
695
698
  return ViewDxmCommodityProductResponse.model_validate(view_dxm_commodity_product_res.json())
696
699
 
700
+ async def update_dxm_commodity_front_sku(self, proid: str, front_sku: str):
701
+ """
702
+ 更新店小秘 仓库-商品详情中的平台sku
703
+ :param proid:
704
+ :param front_sku:
705
+ :return:
706
+ """
707
+ # 打开浏览器
708
+ try:
709
+ async with async_playwright() as p:
710
+ browser = await p.chromium.launch(headless=True)
711
+ context = await browser.new_context()
712
+ # 设置cookie和headers
713
+ await context.add_cookies([
714
+ {
715
+ "name": name, # cookie 名称
716
+ "value": value, # cookie 值
717
+ "domain": ".dianxiaomi.com", # 替换为你的目标域名
718
+ "path": "/", # cookie 路径
719
+ }
720
+ for name, value in self.__cookies.items()
721
+ ])
722
+ page = await context.new_page()
723
+ # 访问
724
+ await page.goto(f'{self.__base_url}/dxmCommodityProduct/openEditModal.htm?id={proid}&editOrCopy=0')
725
+ # 输入sku
726
+ await page.locator('input.variationValue.ui-autocomplete-input').fill(front_sku)
727
+ # 失去焦点
728
+ await page.locator('input.variationValue.ui-autocomplete-input').press('Tab')
729
+ # 休眠两秒
730
+ await asyncio.sleep(2)
731
+ # 点击保存
732
+ await page.locator('.button.btn-orange.m-left10').first.click()
733
+ except Exception as e:
734
+ raise Exception(f'更新店小秘 仓库-商品详情中的平台sku失败-失败原因:{e}')
735
+
697
736
  async def __aenter__(self):
698
737
  return self
699
738
 
@@ -39,7 +39,7 @@ def get_single_order_item_list(order_element: html.HtmlElement):
39
39
  try:
40
40
  float(price.replace(',', ''))
41
41
  except:
42
- raise Exception(f'价格格式错误, sku是{sku}')
42
+ raise Exception(f'价格格式错误, sku是{sku}--价格是{price}')
43
43
  sku_list.append({
44
44
  'sku': sku,
45
45
  'quantity': int(quantity),
@@ -285,7 +285,7 @@ class DxmCommodityProduct(BaseModel):
285
285
  current_sku_count: int = Field(0, alias="currentSkuCount", description="当前SKU计数")
286
286
  reference_by_group: int = Field(0, alias="referenceByGroup", description="按组引用")
287
287
  agent_name: Optional[str] = Field(None, alias="agentName", description="代理商名称")
288
- development_name: str = Field(..., alias="developmentName", description="开发人员名称")
288
+ development_name: Optional[str] = Field(..., alias="developmentName", description="开发人员名称")
289
289
  sales_name: Optional[str] = Field(None, alias="salesName", description="销售人员名称")
290
290
  productuu_id: Optional[str] = Field(None, alias="productuuId", description="商品UUID")
291
291
  auth_id: Optional[str] = Field(None, alias="authId", description="授权ID")
@@ -335,12 +335,12 @@ class ProductDTO(BaseModel):
335
335
  description="DXM商品列表")
336
336
  spu: Optional[str] = Field(None, alias="spu", description="SPU编码")
337
337
  dxm_product_packs: List[Any] = Field(..., alias="dxmProductPacks", description="DXM商品包装列表")
338
- supplier_product_relation_map_list: List[SupplierProductRelation] = Field(...,
338
+ supplier_product_relation_map_list: Optional[List[SupplierProductRelation]] = Field(...,
339
339
  alias="supplierProductRelationMapList",
340
340
  description="供应商商品关系映射列表")
341
- dxm_warehouse_product_list: List[DxmWarehouseProduct] = Field(..., alias="dxmWarehouseProductList",
341
+ dxm_warehouse_product_list: Optional[List[DxmWarehouseProduct]] = Field(..., alias="dxmWarehouseProductList",
342
342
  description="DXM仓库商品列表")
343
- count: int = Field(0, alias="count", description="计数")
343
+ count: Optional[int] = Field(0, alias="count", description="计数")
344
344
 
345
345
  model_config = ConfigDict(populate_by_name=True)
346
346
 
@@ -377,7 +377,7 @@ class EditDxmCommodityProduct(BaseModel):
377
377
  width: int
378
378
  height: int
379
379
  qc_type: int = Field(..., alias="qcType")
380
- product_status: str = Field(..., alias="productStatus")
380
+ product_status: int = Field(..., alias="productStatus")
381
381
  child_ids: str = Field("", alias="childIds")
382
382
  child_nums: str = Field("", alias="childNums")
383
383
  process_fee: int = Field(..., alias="processFee")
@@ -408,8 +408,8 @@ class EditSupplierProductRelationMap(BaseModel):
408
408
 
409
409
 
410
410
  class EditObj(BaseModel):
411
- dxm_commodity_product: DxmCommodityProduct = Field(..., alias="dxmCommodityProduct")
412
- dxm_product_customs: DxmProductCustoms = Field(..., alias="dxmProductCustoms")
411
+ dxm_commodity_product: EditDxmCommodityProduct = Field(..., alias="dxmCommodityProduct")
412
+ dxm_product_customs: EditDxmProductCustoms = Field(..., alias="dxmProductCustoms")
413
413
  warehouse_id_list: str = Field("", alias="warehouseIdList")
414
414
  supplier_product_relation_map_list: List[EditSupplierProductRelationMap] = Field(..., alias="supplierProductRelationMapList")
415
415
  dxm_product_packs: List = Field(..., alias="dxmProductPacks")
@@ -1,4 +1,7 @@
1
+ import json
2
+
1
3
  from ey_commerce_lib.dxm.schemas.dxm_commodity_product import ViewDxmCommodityProductResponse, EditObj
4
+ from ey_commerce_lib.utils.float import truncate_decimal_str
2
5
 
3
6
 
4
7
  def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProductResponse):
@@ -14,7 +17,7 @@ def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProduc
14
17
  name_en = dxm_commodity_product.name_en
15
18
  sku_code = dxm_commodity_product.sku_code
16
19
  sku = dxm_commodity_product.sku
17
- product_variation_str = dxm_commodity_product.product_variation_str
20
+ product_variation_str = ','.join(dxm_commodity_product.product_variation_str_list)
18
21
  sbm_id = dxm_commodity_product.sbm_id
19
22
  agent_id = dxm_commodity_product.agent_id
20
23
  development_id = dxm_commodity_product.development_id
@@ -46,7 +49,7 @@ def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProduc
46
49
  name_cn_bg = dxm_product_customs.name_cn
47
50
  name_en_bg = dxm_product_customs.name_en
48
51
  weight_bg = dxm_product_customs.weight
49
- price_bg = dxm_commodity_product.price_bg
52
+ price_bg = dxm_product_customs.price
50
53
  material_bg = dxm_commodity_product.material_bg
51
54
  purpose_bg = dxm_commodity_product.purpose_bg
52
55
  hgbm_bg = dxm_commodity_product.hgbm_bg
@@ -54,7 +57,7 @@ def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProduc
54
57
 
55
58
  warehouse_id_list = data.product_dto.warehouse_id_list
56
59
 
57
- supplier_product_relation_map_list = data.product_dto.supplier_product_relation_map_list
60
+ supplier_product_relation_map_list = data.product_dto.supplier_product_relation_map_list or []
58
61
  new_supplier_product_relation_map_list = []
59
62
  for supplier_product_relation_map in supplier_product_relation_map_list:
60
63
  supplier_id = supplier_product_relation_map.supplier_id
@@ -65,22 +68,22 @@ def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProduc
65
68
  })
66
69
 
67
70
  dxm_product_packs = data.product_dto.dxm_product_packs
68
-
71
+ # sbmId 必须为字符串
69
72
  return EditObj.model_validate({
70
73
  'dxmCommodityProduct': {
71
- 'productId': product_id,
74
+ 'productId': str(product_id),
72
75
  'name': name,
73
76
  'nameEn': name_en,
74
77
  'skuCode': sku_code,
75
78
  'sku': sku,
76
79
  'productVariationStr': product_variation_str,
77
- 'sbmId': sbm_id,
78
- 'agentId': agent_id,
79
- 'developmentId': development_id,
80
- 'salesId': sales_id,
81
- 'weight': weight,
82
- 'allowWeightError': allow_weight_error,
83
- 'price': price,
80
+ 'sbmId': sbm_id if sbm_id is not None else '',
81
+ 'agentId': str(agent_id),
82
+ 'developmentId': str(development_id),
83
+ 'salesId': str(sales_id),
84
+ 'weight': truncate_decimal_str(weight),
85
+ 'allowWeightError': '',
86
+ 'price': truncate_decimal_str(price),
84
87
  'sourceUrl': source_url,
85
88
  'imgUrl': img_url,
86
89
  'isUsed': is_used,
@@ -90,29 +93,30 @@ def get_edit_commodity_product_by_view_dxm_response(data: ViewDxmCommodityProduc
90
93
  'width': width,
91
94
  'height': height,
92
95
  'qcType': qc_type,
93
- 'productStatus': product_status,
94
- 'childIds': child_ids,
95
- 'childNums': child_nums,
96
+ 'productStatus': 1,
97
+ 'childIds': child_ids if child_ids is not None else '',
98
+ 'childNums': child_nums if child_nums is not None else '',
96
99
  'processFee': process_fee,
97
- 'qcContent': qc_content,
100
+ 'qcContent': qc_content if qc_content is not None else '',
98
101
  'qcImgNum': qc_img_num,
99
- 'groupState': group_state,
100
- 'ncm': ncm,
101
- 'cest': cest,
102
- 'unit': unit,
103
- 'origin': origin
102
+ 'groupState': str(group_state),
103
+ 'ncm': ncm if ncm is not None else '',
104
+ 'cest': cest if cest is not None else '',
105
+ 'unit': unit if unit is not None else '',
106
+ 'origin': origin if origin is not None else '0'
104
107
  },
105
108
  'dxmProductCustoms': {
106
109
  'nameCnBg': name_cn_bg,
107
110
  'nameEnBg': name_en_bg,
108
- 'weightBg': weight_bg,
109
- 'priceBg': price_bg,
110
- 'materialBg': material_bg,
111
- 'purposeBg': purpose_bg,
112
- 'hgbmBg': hgbm_bg,
113
- 'dangerDesBg': danger_des_bg
111
+ 'weightBg': truncate_decimal_str(weight_bg),
112
+ 'priceBg': truncate_decimal_str(price_bg, 4),
113
+ 'materialBg': material_bg if material_bg is not None else '',
114
+ 'purposeBg': purpose_bg if purpose_bg is not None else '',
115
+ 'hgbmBg': hgbm_bg if hgbm_bg is not None else '',
116
+ 'dangerDesBg': danger_des_bg if danger_des_bg is not None else '0'
114
117
  },
115
- 'warehouseIdList': warehouse_id_list,
118
+ 'warehouseIdList': warehouse_id_list if warehouse_id_list is not None else '',
116
119
  'supplierProductRelationMapList': new_supplier_product_relation_map_list,
117
120
  'dxmProductPacks': dxm_product_packs
118
121
  }).model_dump_json(by_alias=True)
122
+
@@ -0,0 +1,30 @@
1
+ from decimal import Decimal, ROUND_DOWN
2
+
3
+
4
+ def truncate_decimal(number, digits=2):
5
+ """
6
+ 截断保留指定位数的小数(不四舍五入),并保留末尾的 0
7
+ :param number: 输入的数字(int/float)
8
+ :param digits: 保留的小数位数(默认2位)
9
+ :return: 返回字符串形式,确保末尾 0 不省略
10
+ """
11
+ if isinstance(number, int):
12
+ return f"{number}.{'0' * digits}"
13
+
14
+ decimal_num = Decimal(str(number))
15
+ truncated = decimal_num.quantize(
16
+ Decimal('0.' + '0' * digits),
17
+ rounding=ROUND_DOWN
18
+ )
19
+ return format(truncated, f".{digits}f") # 强制保留末尾 0
20
+
21
+
22
+ def truncate_decimal_str(number, digits=2):
23
+ """
24
+ 使用decimal模块实现(最精确的方式)
25
+ """
26
+ return str(truncate_decimal(number, digits))
27
+
28
+
29
+ if __name__ == '__main__':
30
+ print(truncate_decimal(200.000, 4))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ey-commerce-lib
3
- Version: 1.0.14
3
+ Version: 1.0.15
4
4
  Summary: eeyoung电商客户端调用封装
5
5
  Author-email: 饶奇奇 <1124393197@qq.com>
6
6
  Requires-Python: >=3.10
@@ -2,7 +2,7 @@ ey_commerce_lib/__init__.py,sha256=QTYqXqSTHFRkM9TEgpDFcHvwLbvqHDqvqfQ9EiXkcAM,2
2
2
  ey_commerce_lib/model.py,sha256=0ZCE68502blzRDsQ38AIswc8kPk7H34Am5x8IiDi2DU,232
3
3
  ey_commerce_lib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  ey_commerce_lib/dxm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- ey_commerce_lib/dxm/main.py,sha256=Hawru6vR4QUn_bK_YsgFTUMjbtoBNzJVkxNdl9_Niis,26995
5
+ ey_commerce_lib/dxm/main.py,sha256=mwbwshZcY-pzIilRDDw_330KHXKHStCASv37T7S-LR4,28787
6
6
  ey_commerce_lib/dxm/order.py,sha256=hMdNm9X5h9tbvMWFnyE5hcSF4butzn7m-akGqLQUD0k,35
7
7
  ey_commerce_lib/dxm/constant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  ey_commerce_lib/dxm/constant/order.py,sha256=U-2NYnkIcqukzMtOFpfqvzIktu_t7jYEms_n9LgKMlY,2213
@@ -12,17 +12,17 @@ ey_commerce_lib/dxm/parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
12
12
  ey_commerce_lib/dxm/parser/common.py,sha256=-xfnaYhMStuvR-XEJTWAgTN2H88xflGtWXIrxDqbq0Q,3037
13
13
  ey_commerce_lib/dxm/parser/count.py,sha256=WOrGeA6DP6_IBtiF1TEZhW528f8kHxlT2cpmg_7FKPM,1561
14
14
  ey_commerce_lib/dxm/parser/ebay_product.py,sha256=Ub6of2YhFnXQwZiFBvZa6wnTIsGbsedAKHW92dbBHIY,589
15
- ey_commerce_lib/dxm/parser/order.py,sha256=wJexOS7oXluJ5ySK7GrLSOexQLIcM8-KVhisCVLcinw,17954
15
+ ey_commerce_lib/dxm/parser/order.py,sha256=vnu5jqea8IoTGk_kFlDcUnrZF5NKuBIQUGAYaxQVSg4,17972
16
16
  ey_commerce_lib/dxm/parser/purchase.py,sha256=lmcC41HtdUqCgGamFASPnzHatUziLFaenTJmazsiMm0,5750
17
17
  ey_commerce_lib/dxm/parser/warehouse.py,sha256=oQVojPX8VKHUphdV1KY5ZK1PCFtOY2zwkyLNUeJ3JT0,3310
18
18
  ey_commerce_lib/dxm/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  ey_commerce_lib/dxm/schemas/common.py,sha256=ihCeYrh4K_-m9_4rVzHm-o8rFNqzcD5XkO0JQd2023g,234
20
- ey_commerce_lib/dxm/schemas/dxm_commodity_product.py,sha256=CGM-wSKvkTBTcoYM631e7v7-A7GQcPy1-jXZjzNWzZw,30827
20
+ ey_commerce_lib/dxm/schemas/dxm_commodity_product.py,sha256=e48ojtOqNfnCaOyPLsBlv4AwfmfkBg62w7J2sA9l1E4,30875
21
21
  ey_commerce_lib/dxm/schemas/ebay_product.py,sha256=k8LqBCz657vYRcLRjjyPJjQYjQOSwSGBivvp2LPWuYc,3696
22
22
  ey_commerce_lib/dxm/schemas/order.py,sha256=6ps9aXFcEiRASLv1CH5uW7wnplaWzD_vTfyzvi5eLE0,7881
23
23
  ey_commerce_lib/dxm/schemas/warehouse.py,sha256=BT9r92DgkGKRI-HPqHPt5FKPdPJr2h-rxjfh25STR2E,5094
24
24
  ey_commerce_lib/dxm/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- ey_commerce_lib/dxm/utils/dxm_commodity_product.py,sha256=tQ7sjHwXb5EY9WW0GtvV3jqXkizXtwp3NU_ZFQPy1dU,4777
25
+ ey_commerce_lib/dxm/utils/dxm_commodity_product.py,sha256=k7ANpQ0M2Tf94QO0xcQUpdBrjZN-pXVL--_s_wrwX5E,5413
26
26
  ey_commerce_lib/dxm/utils/mark.py,sha256=rAmofi3JmdI8gdl3s-U0ZEKcA-cn6vtS3lsXDrVXRLc,4716
27
27
  ey_commerce_lib/four_seller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  ey_commerce_lib/four_seller/main.py,sha256=cqO29DRRVzJHwo_005RFOO3vyGboQcuJUli783nyQjA,13131
@@ -50,8 +50,9 @@ ey_commerce_lib/takesend/main.py,sha256=Omz7Wmo0bBzQvMA-_zVQG1sH-W-RsX5AeetFE2a1
50
50
  ey_commerce_lib/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  ey_commerce_lib/utils/close.py,sha256=-De_H1I-gryytKYhLMsC3HfW67W852XkP1ckK2gLsFs,141
52
52
  ey_commerce_lib/utils/dxm.py,sha256=jVNltK_Pm_yMzXReD0Aw5VW6kzIZ5Bn23RucS0DKBI0,1196
53
+ ey_commerce_lib/utils/float.py,sha256=PiOMf9pRApc1DskKkhKx0LAWHAYTpAPT_G4QRZRd8ZU,905
53
54
  ey_commerce_lib/utils/list_util.py,sha256=R1w7B1m3sEXr38zSHWp-15C3xAs5ykYCCpvwmnRW4xs,545
54
55
  ey_commerce_lib/utils/str.py,sha256=939xE0y8U7KEWjwbEezMlaWJNBsfb2BSb-dBpYbOD8Q,138
55
- ey_commerce_lib-1.0.14.dist-info/METADATA,sha256=2s9TCOT0sndWzFHflvL8-0xw2VN1t6uO2cf6DxI5eZ0,391
56
- ey_commerce_lib-1.0.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
- ey_commerce_lib-1.0.14.dist-info/RECORD,,
56
+ ey_commerce_lib-1.0.15.dist-info/METADATA,sha256=wVymcuISab9JO0cH3UkFtnrdP7iEWrDwHLvcFi6qCeA,391
57
+ ey_commerce_lib-1.0.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
58
+ ey_commerce_lib-1.0.15.dist-info/RECORD,,