181 lines
6.2 KiB
Python
181 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
"""6月测试车辆:用GPS日里程替换仪表盘里程,写入源数据文件"""
|
|
import openpyxl, pymysql, os
|
|
from datetime import datetime, date
|
|
from collections import defaultdict
|
|
|
|
os.chdir('/Users/kkfluous/Downloads')
|
|
|
|
# 1. 读取测试车辆清单
|
|
fp = '/Users/kkfluous/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/wxid_1704407055112_3af8/temp/RWTemp/2026-07/65b41c10aa83cabb7a365b2b8437c1c7/6月测试车辆.xlsx'
|
|
wb = openpyxl.load_workbook(fp, data_only=True)
|
|
ws = wb.active
|
|
rows = list(ws.iter_rows(min_row=1, values_only=True))
|
|
test_plates = set()
|
|
for row in rows[1:]:
|
|
for ci in [0, 3, 6]:
|
|
p = str(row[ci]).strip() if row[ci] else ''
|
|
if p and p != 'None':
|
|
test_plates.add(p)
|
|
wb.close()
|
|
print(f'测试车辆: {len(test_plates)}辆')
|
|
|
|
# 2. 备份
|
|
src = '租赁任务考核_2026年6月.xlsx'
|
|
bak = '租赁任务考核_2026年6月_备份.xlsx'
|
|
if not os.path.exists(bak):
|
|
import shutil
|
|
shutil.copy2(src, bak)
|
|
print(f'已备份: {bak}')
|
|
|
|
# 3. 读源文件
|
|
wb = openpyxl.load_workbook(src)
|
|
ws = wb['业务考核视图']
|
|
h = [c.value for c in next(ws.iter_rows(min_row=1, max_row=1))]
|
|
recs = []
|
|
for row in ws.iter_rows(min_row=2, values_only=True):
|
|
r = dict(zip(h, row))
|
|
r['row_num'] = len(recs) + 2
|
|
recs.append(r)
|
|
|
|
# 测试车辆在源数据中的记录
|
|
test_recs = [r for r in recs if r['车牌号'] in test_plates]
|
|
print(f'测试车辆在6月源数据中的记录: {len(test_recs)}条 ({len(set(r["车牌号"] for r in test_recs))}辆)')
|
|
|
|
# 4. 连数据库取GPS
|
|
conn = pymysql.connect(host='101.133.130.65', port=3306, user='root', password='ln123!@#',
|
|
database='hydrogen_energy', connect_timeout=30)
|
|
cur = conn.cursor()
|
|
|
|
def get_gps_km(plate, start_str, end_str):
|
|
"""按考核起止日期汇总GPS日里程(km)"""
|
|
if not start_str or not end_str:
|
|
return None
|
|
try:
|
|
sd = datetime.strptime(str(start_str)[:10], '%Y-%m-%d').date()
|
|
ed = datetime.strptime(str(end_str)[:10], '%Y-%m-%d').date()
|
|
except:
|
|
return None
|
|
|
|
cur.execute("""
|
|
SELECT dates, total_mileage FROM ln_vehicle_g7_mileage
|
|
WHERE plate_number = %s AND dates >= %s AND dates <= %s
|
|
ORDER BY dates
|
|
""", (plate, sd, ed))
|
|
rows = cur.fetchall()
|
|
if not rows:
|
|
return None
|
|
|
|
# total_mileage is daily cumulative (meters). Get daily delta then sum.
|
|
# Actually check: is it daily km or cumulative? From last time: total_mileage/100000 = km
|
|
# Let's check if values are ascending (cumulative) or fluctuating (daily)
|
|
vals = [r[1] for r in rows]
|
|
is_cumulative = all(vals[i] <= vals[i+1] for i in range(len(vals)-1)) if len(vals) > 1 else False
|
|
|
|
if is_cumulative:
|
|
# Daily delta: today - yesterday
|
|
deltas = []
|
|
prev = None
|
|
for v in vals:
|
|
if prev is not None and v > prev:
|
|
deltas.append(v - prev)
|
|
elif prev is None:
|
|
deltas.append(v) # first day
|
|
prev = v
|
|
total_km = sum(deltas) / 100000
|
|
else:
|
|
total_km = sum(vals) / 100000
|
|
|
|
return round(total_km, 1)
|
|
|
|
# 批量查询: build plate→[(start,end,row_num)] map
|
|
queries = defaultdict(list)
|
|
for r in test_recs:
|
|
plate = r['车牌号']
|
|
start = r.get('考核开始日期')
|
|
end = r.get('考核结束日期')
|
|
queries[plate].append((start, end, r['row_num']))
|
|
|
|
# Process each unique plate
|
|
gps_cache = {}
|
|
replaced = 0
|
|
no_data = 0
|
|
no_data_plates = set()
|
|
|
|
for plate in sorted(queries.keys()):
|
|
# Get all GPS data for this plate in June for caching
|
|
cur.execute("""
|
|
SELECT dates, total_mileage FROM ln_vehicle_g7_mileage
|
|
WHERE plate_number = %s AND dates >= '2026-06-01' AND dates <= '2026-06-30'
|
|
ORDER BY dates
|
|
""", (plate,))
|
|
all_rows = cur.fetchall()
|
|
if not all_rows:
|
|
no_data += len(queries[plate])
|
|
no_data_plates.add(plate)
|
|
continue
|
|
|
|
for start, end, row_num in queries[plate]:
|
|
km = get_gps_km(plate, start, end)
|
|
if km is None:
|
|
no_data += 1
|
|
no_data_plates.add(plate)
|
|
else:
|
|
gps_cache[row_num] = km
|
|
|
|
conn.close()
|
|
|
|
# 5. 更新源文件
|
|
# Need to add '原TBOX里程' and '测试里程' columns if not exist
|
|
# Check existing columns
|
|
last_col_letter = openpyxl.utils.get_column_letter(ws.max_column)
|
|
need_new_cols = '原TBOX里程(km)' not in h and '测试里程(km)' not in h
|
|
|
|
if need_new_cols:
|
|
# Add two new columns
|
|
tbox_col = ws.max_column + 1
|
|
test_col = ws.max_column + 2
|
|
ws.cell(row=1, column=tbox_col, value='原TBOX里程(km)')
|
|
ws.cell(row=1, column=test_col, value='测试里程(km)')
|
|
# Find the actual行驶里程 column index
|
|
actual_idx = h.index('实际行驶里程(km)') + 1 # 1-indexed
|
|
else:
|
|
tbox_idx = h.index('原TBOX里程(km)') + 1 if '原TBOX里程(km)' in h else None
|
|
test_idx = h.index('测试里程(km)') + 1 if '测试里程(km)' in h else None
|
|
|
|
# Apply replacements
|
|
for row_num, gps_km in gps_cache.items():
|
|
# Find column indices in current sheet
|
|
row_data = [c.value for c in ws[row_num]]
|
|
h_current = [c.value for c in ws[1]]
|
|
|
|
actual_col = h_current.index('实际行驶里程(km)') + 1
|
|
old_val = ws.cell(row=row_num, column=actual_col).value
|
|
|
|
if need_new_cols:
|
|
tbox_col = h_current.index('原TBOX里程(km)') + 1 if '原TBOX里程(km)' in h_current else ws.max_column - 1
|
|
test_col = h_current.index('测试里程(km)') + 1 if '测试里程(km)' in h_current else ws.max_column
|
|
else:
|
|
tbox_col = h_current.index('原TBOX里程(km)') + 1
|
|
test_col = h_current.index('测试里程(km)') + 1
|
|
|
|
# Write original TBOX mileage
|
|
ws.cell(row=row_num, column=tbox_col, value=float(old_val) if old_val else 0)
|
|
# Write test mileage (TBOX - GPS)
|
|
tbox_val = float(old_val or 0)
|
|
test_km = round(tbox_val - gps_km, 1)
|
|
ws.cell(row=row_num, column=test_col, value=test_km)
|
|
# Replace actual mileage with GPS
|
|
ws.cell(row=row_num, column=actual_col, value=gps_km)
|
|
replaced += 1
|
|
|
|
wb.save(src)
|
|
wb.close()
|
|
|
|
print(f'\n替换结果:')
|
|
print(f' 成功替换: {replaced}条')
|
|
print(f' 无GPS数据: {no_data}条 ({len(no_data_plates)}辆)')
|
|
if no_data_plates:
|
|
print(f' 无数据车牌: {sorted(no_data_plates)}')
|
|
print(f'\n已保存: {src}')
|