119 lines
3.7 KiB
Python
119 lines
3.7 KiB
Python
# coding=utf-8
|
||
"""管理系统公开接口:拉取基地列表(需 X-API-Key)。"""
|
||
try:
|
||
import requests
|
||
except ImportError:
|
||
requests = None
|
||
|
||
from dao.settings import DISH_MGMT_API_KEY, DISH_MGMT_API_TIMEOUT, DISH_MGMT_API_URL
|
||
|
||
|
||
class MgmtApiError(RuntimeError):
|
||
pass
|
||
|
||
|
||
def fetch_bases(url=None, api_key=None, timeout=None):
|
||
"""
|
||
GET /api/public/bases
|
||
返回 items 列表(原始 dict),失败抛 MgmtApiError。
|
||
"""
|
||
if requests is None:
|
||
raise MgmtApiError('缺少 requests 库,请 pip install requests')
|
||
|
||
url = (url or DISH_MGMT_API_URL or '').strip()
|
||
api_key = (api_key if api_key is not None else DISH_MGMT_API_KEY) or ''
|
||
api_key = str(api_key).strip()
|
||
timeout = float(timeout if timeout is not None else DISH_MGMT_API_TIMEOUT)
|
||
|
||
if not url:
|
||
raise MgmtApiError('未配置 DISH_MGMT_API_URL')
|
||
if not api_key:
|
||
raise MgmtApiError('未配置 DISH_MGMT_API_KEY')
|
||
|
||
headers = {
|
||
'X-API-Key': api_key,
|
||
'Accept': 'application/json',
|
||
}
|
||
try:
|
||
resp = requests.get(url, headers=headers, timeout=timeout)
|
||
except Exception as exc:
|
||
raise MgmtApiError(f'请求管理系统失败: {exc}') from exc
|
||
|
||
if resp.status_code != 200:
|
||
body = (resp.text or '')[:300]
|
||
raise MgmtApiError(f'管理系统 HTTP {resp.status_code}: {body}')
|
||
|
||
try:
|
||
data = resp.json()
|
||
except Exception as exc:
|
||
raise MgmtApiError(f'管理系统返回非 JSON: {exc}') from exc
|
||
|
||
if isinstance(data, list):
|
||
return data
|
||
if isinstance(data, dict):
|
||
items = data.get('items')
|
||
if isinstance(items, list):
|
||
return items
|
||
# 兼容 { data: [...] } / { list: [...] }
|
||
for key in ('data', 'list', 'bases', 'rows'):
|
||
if isinstance(data.get(key), list):
|
||
return data[key]
|
||
raise MgmtApiError(f'无法解析基地列表,响应类型={type(data).__name__}')
|
||
|
||
|
||
def map_remote_base(item):
|
||
"""
|
||
管理系统字段 → 本地 bases 字段。
|
||
不把远程 id 当作本地主键,改存 external_id。
|
||
"""
|
||
if not isinstance(item, dict):
|
||
return None
|
||
|
||
code = (item.get('code') or '').strip()
|
||
name = (item.get('name') or '').strip()
|
||
if not code or not name:
|
||
return None
|
||
|
||
province = (item.get('province') or '').strip() or None
|
||
city = (item.get('city') or '').strip() or None
|
||
district = (item.get('district') or '').strip() or None
|
||
region_parts = [p for p in (province, city, district) if p]
|
||
region = '/'.join(region_parts) if region_parts else None
|
||
|
||
status = item.get('status')
|
||
try:
|
||
is_active = 1 if int(status) == 1 else 0
|
||
except (TypeError, ValueError):
|
||
is_active = 1
|
||
|
||
external_id = item.get('id')
|
||
try:
|
||
external_id = int(external_id) if external_id is not None else None
|
||
except (TypeError, ValueError):
|
||
external_id = None
|
||
|
||
sort_order = item.get('sortOrder', 0)
|
||
try:
|
||
sort_order = int(sort_order)
|
||
except (TypeError, ValueError):
|
||
sort_order = 0
|
||
|
||
return {
|
||
'external_id': external_id,
|
||
'base_code': code[:128],
|
||
'base_name': name[:100],
|
||
'branch_name': ((item.get('branchName') or '').strip() or None),
|
||
'region': region,
|
||
'province': province,
|
||
'city': city,
|
||
'district': district,
|
||
'address': ((item.get('address') or '').strip() or None),
|
||
'contact': ((item.get('contact') or '').strip() or None),
|
||
'phone': ((item.get('phone') or '').strip() or None),
|
||
'description': ((item.get('description') or '').strip() or None),
|
||
'is_active': is_active,
|
||
'sort_order': sort_order,
|
||
'longitude': item.get('longitude'),
|
||
'latitude': item.get('latitude'),
|
||
}
|