'commit'
This commit is contained in:
@@ -36,6 +36,25 @@ class XinDianTuService:
|
||||
def get_hash(self, s: str) -> str:
|
||||
return hashlib.md5(s.encode('utf-8')).hexdigest()
|
||||
|
||||
def _to_float(self, value) -> float:
|
||||
"""
|
||||
从字符串中提取浮点数,过滤掉非数字字符
|
||||
"""
|
||||
if value is None:
|
||||
return 0.0
|
||||
if isinstance(value, (int, float)):
|
||||
return float(value)
|
||||
|
||||
import re
|
||||
try:
|
||||
# 提取第一个匹配的数字部分(包含小数点)
|
||||
match = re.search(r"[-+]?\d*\.?\d+", str(value))
|
||||
if match:
|
||||
return float(match.group())
|
||||
return 0.0
|
||||
except:
|
||||
return 0.0
|
||||
|
||||
async def init_db(self):
|
||||
await self.db.init_db()
|
||||
|
||||
@@ -129,12 +148,7 @@ class XinDianTuService:
|
||||
})
|
||||
|
||||
price_str = station.get("price", "")
|
||||
current_price = None
|
||||
try:
|
||||
price_match = re.search(r"\d+\.\d+", str(price_str))
|
||||
if price_match:
|
||||
current_price = float(price_match.group())
|
||||
except: pass
|
||||
current_price = self._to_float(price_str)
|
||||
|
||||
await self.station_status_model.save(
|
||||
session=session,
|
||||
@@ -193,32 +207,47 @@ class XinDianTuService:
|
||||
|
||||
# 2. 保存 Status (解析价格和电桩)
|
||||
status_id = self.generate_id()
|
||||
piles_str = station.get("piles", "0/0")
|
||||
|
||||
# 处理 piles 字段 (由 VL 返回的列表结构)
|
||||
piles_data = station.get("piles")
|
||||
total, free = 0, 0
|
||||
standardized_piles = []
|
||||
|
||||
if "/" in piles_str:
|
||||
if isinstance(piles_data, list):
|
||||
for idx, p in enumerate(piles_data):
|
||||
try:
|
||||
t = int(p.get("total", 0))
|
||||
f = int(p.get("free", 0))
|
||||
total += t
|
||||
free += f
|
||||
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": p.get("type", "未知"),
|
||||
"power": "",
|
||||
"status_text": f"空闲{f}/总{t}",
|
||||
"remark": "列表页VL"
|
||||
})
|
||||
except:
|
||||
pass
|
||||
elif isinstance(piles_data, str) and "/" in piles_data:
|
||||
# 兼容旧格式或意外返回的字符串格式
|
||||
try:
|
||||
parts = piles_str.split("/")
|
||||
free = int(parts[0])
|
||||
total = int(parts[1])
|
||||
parts = piles_data.split("/")
|
||||
free = int(re.search(r"\d+", parts[0]).group())
|
||||
total = int(re.search(r"\d+", parts[1]).group())
|
||||
standardized_piles.append({
|
||||
"pile_no": "G1",
|
||||
"type": "未知",
|
||||
"power": "",
|
||||
"status_text": f"空闲{free}/总{total}",
|
||||
"remark": "列表页VL"
|
||||
"remark": "列表页VL(兼容)"
|
||||
})
|
||||
except:
|
||||
pass
|
||||
|
||||
price_str = station.get("price", "")
|
||||
current_price = None
|
||||
try:
|
||||
price_match = re.search(r"\d+\.\d+", str(price_str))
|
||||
if price_match:
|
||||
current_price = float(price_match.group())
|
||||
except: pass
|
||||
current_price = self._to_float(price_str)
|
||||
|
||||
await self.station_status_model.save(
|
||||
session=session,
|
||||
@@ -299,20 +328,10 @@ class XinDianTuService:
|
||||
continue
|
||||
|
||||
price = station.get("price")
|
||||
current_price = None
|
||||
if price is not None and price != "":
|
||||
try:
|
||||
current_price = float(price)
|
||||
except (ValueError, TypeError):
|
||||
current_price = None
|
||||
current_price = self._to_float(price) if price is not None and price != "" else None
|
||||
|
||||
pro_price_val = station.get("pro_price")
|
||||
pro_price = None
|
||||
if pro_price_val is not None and pro_price_val != "":
|
||||
try:
|
||||
pro_price = float(pro_price_val)
|
||||
except (ValueError, TypeError):
|
||||
pro_price = None
|
||||
pro_price = self._to_float(pro_price_val) if pro_price_val is not None and pro_price_val != "" else None
|
||||
|
||||
await self.station_status_model.save(
|
||||
session=session,
|
||||
@@ -414,44 +433,64 @@ class XinDianTuService:
|
||||
# 2. 保存 Status
|
||||
status_id = self.generate_id()
|
||||
|
||||
# 解析电桩数量 (支持多组,如 "快:2/10 慢:1/5")
|
||||
piles_str = station_info.get("piles", "")
|
||||
# 解析电桩数量 (支持由 VL 返回的列表或字符串)
|
||||
piles_data = station_info.get("piles", [])
|
||||
total, free = 0, 0
|
||||
standardized_piles = []
|
||||
|
||||
# 尝试匹配 "快:2/10" 或 "2/10" 这种格式
|
||||
# 模式 1: 有类型,如 "快:2/10"
|
||||
matches_with_type = re.findall(r"(\w+):(\d+)/(\d+)", piles_str)
|
||||
if matches_with_type:
|
||||
for idx, (p_type, f, t) in enumerate(matches_with_type):
|
||||
f_int, t_int = int(f), int(t)
|
||||
free += f_int
|
||||
total += t_int
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": p_type,
|
||||
"power": "",
|
||||
"status_text": f"空闲{f_int}/总{t_int}",
|
||||
"remark": "列表页VL"
|
||||
})
|
||||
else:
|
||||
# 模式 2: 无类型,仅 "2/10"
|
||||
matches_simple = re.findall(r"(\d+)/(\d+)", piles_str)
|
||||
for idx, (f, t) in enumerate(matches_simple):
|
||||
f_int, t_int = int(f), int(t)
|
||||
free += f_int
|
||||
total += t_int
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": "未知",
|
||||
"power": "",
|
||||
"status_text": f"空闲{f_int}/总{t_int}",
|
||||
"remark": "列表页VL"
|
||||
})
|
||||
if isinstance(piles_data, list):
|
||||
# 模式 1: VL 返回的结构化列表
|
||||
for idx, p in enumerate(piles_data):
|
||||
if isinstance(p, dict):
|
||||
try:
|
||||
t = int(p.get("total", 0))
|
||||
f = int(p.get("free", 0))
|
||||
total += t
|
||||
free += f
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": p.get("type", "未知"),
|
||||
"power": "",
|
||||
"status_text": f"空闲{f}/总{t}",
|
||||
"remark": "列表页VL"
|
||||
})
|
||||
except:
|
||||
pass
|
||||
elif isinstance(piles_data, str):
|
||||
# 模式 2: 字符串格式 (兼容)
|
||||
piles_str = piles_data
|
||||
# 尝试匹配 "快:2/10" 或 "2/10" 这种格式
|
||||
matches_with_type = re.findall(r"(\w+):(\d+)/(\d+)", piles_str)
|
||||
if matches_with_type:
|
||||
for idx, (p_type, f, t) in enumerate(matches_with_type):
|
||||
f_int, t_int = int(f), int(t)
|
||||
free += f_int
|
||||
total += t_int
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": p_type,
|
||||
"power": "",
|
||||
"status_text": f"空闲{f_int}/总{t_int}",
|
||||
"remark": "列表页VL(兼容)"
|
||||
})
|
||||
else:
|
||||
# 模式 3: 无类型,仅 "2/10"
|
||||
matches_simple = re.findall(r"(\d+)/(\d+)", piles_str)
|
||||
for idx, (f, t) in enumerate(matches_simple):
|
||||
f_int, t_int = int(f), int(t)
|
||||
free += f_int
|
||||
total += t_int
|
||||
standardized_piles.append({
|
||||
"pile_no": f"G{idx+1}",
|
||||
"type": "未知",
|
||||
"power": "",
|
||||
"status_text": f"空闲{f_int}/总{t_int}",
|
||||
"remark": "列表页VL(兼容)"
|
||||
})
|
||||
|
||||
if not standardized_piles:
|
||||
if not standardized_piles and isinstance(piles_data, str):
|
||||
# 兜底匹配所有数字
|
||||
nums = re.findall(r"(\d+)", piles_str)
|
||||
nums = re.findall(r"(\d+)", piles_data)
|
||||
if len(nums) >= 2:
|
||||
free = int(nums[0])
|
||||
total = int(nums[1])
|
||||
@@ -463,17 +502,9 @@ class XinDianTuService:
|
||||
"remark": "列表页VL兜底"
|
||||
})
|
||||
|
||||
# 解析价格
|
||||
# 解析价格
|
||||
price_val = station_info.get("price")
|
||||
current_price = None
|
||||
if price_val:
|
||||
try:
|
||||
# 提取数字部分
|
||||
price_match = re.search(r"(\d+(\.\d+)?)", str(price_val))
|
||||
if price_match:
|
||||
current_price = float(price_match.group(1))
|
||||
except:
|
||||
pass
|
||||
current_price = self._to_float(price_val)
|
||||
|
||||
await self.station_status_model.save(
|
||||
session=session,
|
||||
|
||||
Reference in New Issue
Block a user