Files
sale/scripts/import_products.py
T
admin 3a898e8aa0 fix: 全面修复项目问题
后端修复:
- 验证码存储与校验机制
- 订单创建事务+库存扣减
- GetStats字段名错误
- VerifyEmail改为POST
- 供应商更新字段白名单
- 文件删除安全检查
- 抽奖安全随机数
- 用户管理CRUD
- 订单取消/确认收货
- 工单回复
- Toggle返回新数据
- 移除死代码

前端修复:
- 404兜底路由
- 401软跳转
- API层统一
- 面包屑补充banners
- 国际化完善
- 购物车并行删除
- 退出清理购物车
- 供应商Dashboard数据
- 工单详情页
- 订单取消/确认收货
2026-05-06 09:55:01 +08:00

157 lines
4.7 KiB
Python

import requests
import json
import os
import sys
API_BASE = "http://localhost:8080/api"
ADMIN_TOKEN = None
def login():
global ADMIN_TOKEN
response = requests.post(f"{API_BASE}/auth/login", json={
"email": "admin@viaeon.com",
"password": "admin123"
})
if response.status_code == 200:
data = response.json()
ADMIN_TOKEN = data.get("token")
print(f"登录成功")
return True
else:
print(f"登录失败: {response.text}")
return False
def get_headers():
return {
"Authorization": f"Bearer {ADMIN_TOKEN}",
"Content-Type": "application/json"
}
def create_category(name):
response = requests.post(f"{API_BASE}/admin/categories",
headers=get_headers(),
json={"name": name}
)
if response.status_code == 200:
data = response.json()
return data.get("id")
else:
existing = requests.get(f"{API_BASE}/categories")
if existing.status_code == 200:
cats = existing.json()
if isinstance(cats, list):
for cat in cats:
if isinstance(cat, dict) and cat.get("name") == name:
return cat.get("id")
elif isinstance(cat, str) and cat == name:
return None
return None
def download_image(url, filepath):
try:
response = requests.get(url, timeout=30)
if response.status_code == 200:
with open(filepath, 'wb') as f:
f.write(response.content)
return True
except Exception as e:
print(f"下载图片失败: {e}")
return False
def upload_image(filepath):
try:
with open(filepath, 'rb') as f:
response = requests.post(f"{API_BASE}/upload",
headers={"Authorization": f"Bearer {ADMIN_TOKEN}"},
files={"file": f}
)
if response.status_code == 200:
data = response.json()
return data.get("url")
except Exception as e:
print(f"上传图片失败: {e}")
return None
def create_product(product, category_id, image_url):
price_cny = product.get("price_jpy", 0) * 0.048
price_cny = round(price_cny, 2)
data = {
"name": product.get("name_cn", product.get("name_jp", "未知商品")),
"description": f"{product.get('name_jp', '')}\n{product.get('description', '')}".strip(),
"price": price_cny,
"stock": 100,
"images": image_url,
"category_ids": [category_id] if category_id else [],
"is_active": True
}
response = requests.post(f"{API_BASE}/admin/products",
headers=get_headers(),
json=data
)
if response.status_code in [200, 201]:
return response.json()
else:
result = response.json()
if result.get("data") and result["data"].get("id"):
return result["data"]
print(f"创建商品失败: {response.text}")
return None
def main():
print("开始导入商品数据...")
if not login():
print("请先创建管理员账户")
return
with open('../ribenyan_products.json', 'r', encoding='utf-8') as f:
products = json.load(f)
print(f"读取到 {len(products)} 个商品")
categories = {}
for product in products:
cat_name = product.get("category")
if cat_name not in categories:
cat_id = create_category(cat_name)
if cat_id:
categories[cat_name] = cat_id
print(f"创建分类: {cat_name} (ID: {cat_id})")
os.makedirs("temp_images", exist_ok=True)
success_count = 0
for i, product in enumerate(products):
print(f"\n处理商品 {i+1}/{len(products)}: {product.get('name_cn', 'N/A')}")
image_url = ""
if product.get("image_url"):
temp_path = f"temp_images/{product.get('external_id', i)}.webp"
if download_image(product["image_url"], temp_path):
uploaded_url = upload_image(temp_path)
if uploaded_url:
image_url = uploaded_url
print(f" 图片上传成功: {uploaded_url}")
cat_name = product.get("category")
cat_id = categories.get(cat_name)
result = create_product(product, cat_id, image_url)
if result:
success_count += 1
print(f" 商品创建成功")
else:
print(f" 商品创建失败")
import shutil
shutil.rmtree("temp_images", ignore_errors=True)
print(f"\n导入完成: 成功 {success_count}/{len(products)} 个商品")
if __name__ == "__main__":
main()