Skip to content

Commit 28d62df

Browse files
committed
请求行程轨迹点并发加入进度提示,地图模式保持
1 parent 51b889b commit 28d62df

2 files changed

Lines changed: 116 additions & 28 deletions

File tree

‎custom_components/tailg/const.py‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,25 +109,25 @@
109109
"icon": "mdi:car",
110110
"value_map": {
111111
0: "0",
112-
1: "脚撑收起",
113-
2: "更新状态",
112+
1: "1-脚撑收起",
113+
2: "2-更新状态",
114114
3: "3",
115-
4: "通电",
116-
5: "断电",
117-
6: "手动设防",
118-
7: "手动撤防",
119-
8: "防盗静音",
120-
9: "防盗声音",
115+
4: "4-通电",
116+
5: "5-断电",
117+
6: "6-手动设防",
118+
7: "7-手动撤防",
119+
8: "8-防盗静音",
120+
9: "9-防盗声音",
121121
32: "32",
122-
33: "33",
122+
33: "33-睡眠",
123123
255: "255"
124124
},
125125
"source": SOURCE_MQTT,
126126
},
127127
{
128128
"key": "regeo",
129129
"name": "位置",
130-
"entity_key": "location",
130+
"entity_key": "address",
131131
"unit": None,
132132
"icon": "mdi:map-marker",
133133
"source": SOURCE_HTTP,

‎custom_components/tailg/www/tailg-map-card.js‎

Lines changed: 106 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ const AMAP = {
8787
};
8888
const AMAP_SUBS = ['1','2','3','4'];
8989

90+
/* 车辆图标 SVG(默认卡片与历史轨迹共用) */
91+
const CAR_SVG =
92+
'<svg viewBox="0 0 64 64" width="16" height="16" fill="none" ' +
93+
'stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round">' +
94+
'<circle cx="32" cy="24" r="6" />' +
95+
'<path d="M14 24 L27 24" /><path d="M37 24 L50 24" />' +
96+
'<path d="M22 36 Q22 30 28 30 H36 Q42 30 42 36 V50 Q42 56 36 56 H28 Q22 56 22 50 Z" />' +
97+
'<rect x="26" y="50" width="12" height="14" rx="6" />' +
98+
'</svg>';
99+
90100
/* ============================================================
91101
* iframe 内部 HTML 生成
92102
* ============================================================ */
@@ -255,6 +265,7 @@ function buildHistoryIframeHtml(mode, tracks, currentPos) {
255265
document.querySelectorAll('.basemap-switch button').forEach(function(b) {
256266
b.classList.toggle('active', b.dataset.mode === mode);
257267
});
268+
try { parent.postMessage({ type: 'tailg-basemap', mode: mode }, '*'); } catch (e) {}
258269
setTimeout(function() { map.invalidateSize(); }, 50);
259270
}
260271
@@ -415,16 +426,6 @@ function buildHistoryIframeHtml(mode, tracks, currentPos) {
415426
`, mode);
416427
}
417428

418-
/* 车辆图标 SVG(复用于默认卡片与历史轨迹) */
419-
const CAR_SVG =
420-
'<svg viewBox="0 0 64 64" width="16" height="16" fill="none" ' +
421-
'stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round">' +
422-
'<circle cx="32" cy="24" r="6" />' +
423-
'<path d="M14 24 L27 24" /><path d="M37 24 L50 24" />' +
424-
'<path d="M22 36 Q22 30 28 30 H36 Q42 30 42 36 V50 Q42 56 36 56 H28 Q22 56 22 50 Z" />' +
425-
'<rect x="26" y="50" width="12" height="14" rx="6" />' +
426-
'</svg>';
427-
428429
/* ============================================================
429430
* iframe 通用外壳
430431
* ============================================================ */
@@ -682,6 +683,9 @@ class TailgHistoryDialog extends LitElement {
682683
_loading: { type: Boolean },
683684
_baseMode: { type: String },
684685
_iframeSrcdoc: { type: String },
686+
_trackLoading: { type: Boolean },
687+
_trackLoaded: { type: Number },
688+
_trackTotal: { type: Number },
685689
};
686690
}
687691

@@ -725,6 +729,42 @@ class TailgHistoryDialog extends LitElement {
725729
}
726730
.map-wrap iframe { width: 100%; height: 100%; border: none; display: block; }
727731
732+
.track-loading {
733+
position: absolute; inset: 0;
734+
z-index: 500;
735+
display: flex; flex-direction: column;
736+
align-items: center; justify-content: center;
737+
gap: 10px;
738+
background: rgba(15,23,42,.55);
739+
backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
740+
color: #f1f5f9;
741+
pointer-events: none;
742+
}
743+
.track-loading .spinner {
744+
width: 32px; height: 32px;
745+
border: 3px solid rgba(255,255,255,.25);
746+
border-top-color: #3b82f6;
747+
border-radius: 50%;
748+
animation: tlSpin .8s linear infinite;
749+
}
750+
.track-loading .label {
751+
font-size: 13px; font-weight: 600;
752+
font-variant-numeric: tabular-nums;
753+
text-shadow: 0 1px 3px rgba(0,0,0,.6);
754+
}
755+
.track-loading .bar {
756+
width: 160px; height: 4px;
757+
background: rgba(255,255,255,.2);
758+
border-radius: 2px; overflow: hidden;
759+
}
760+
.track-loading .bar > i {
761+
display: block; height: 100%;
762+
background: #3b82f6;
763+
border-radius: 2px;
764+
transition: width .2s;
765+
}
766+
@keyframes tlSpin { to { transform: rotate(360deg); } }
767+
728768
.list-wrap {
729769
flex: 1 1 auto; min-height: 0;
730770
display: flex; flex-direction: column;
@@ -882,6 +922,10 @@ class TailgHistoryDialog extends LitElement {
882922
this._currentTracks = [];
883923
this._historyPushed = false;
884924
this._onPopState = null;
925+
this._onBasemapMsg = null;
926+
this._trackLoading = false;
927+
this._trackLoaded = 0;
928+
this._trackTotal = 0;
885929
}
886930

887931
connectedCallback() {
@@ -890,13 +934,22 @@ class TailgHistoryDialog extends LitElement {
890934
history.pushState({ tailgDialog: true }, '');
891935
this._historyPushed = true;
892936
} catch (e) { console.warn('[tailg-history] pushState 失败', e); }
937+
893938
this._onPopState = () => {
894939
if (this._historyPushed) {
895940
this._historyPushed = false;
896941
this._closeInternal();
897942
}
898943
};
899944
window.addEventListener('popstate', this._onPopState);
945+
946+
// 同步 iframe 内的底图模式切换
947+
this._onBasemapMsg = (e) => {
948+
if (e.data && e.data.type === 'tailg-basemap' && e.data.mode) {
949+
this._baseMode = e.data.mode;
950+
}
951+
};
952+
window.addEventListener('message', this._onBasemapMsg);
900953
}
901954

902955
disconnectedCallback() {
@@ -905,6 +958,10 @@ class TailgHistoryDialog extends LitElement {
905958
window.removeEventListener('popstate', this._onPopState);
906959
this._onPopState = null;
907960
}
961+
if (this._onBasemapMsg) {
962+
window.removeEventListener('message', this._onBasemapMsg);
963+
this._onBasemapMsg = null;
964+
}
908965
}
909966

910967
_closeInternal() {
@@ -1019,23 +1076,39 @@ class TailgHistoryDialog extends LitElement {
10191076

10201077
async _loadDayTracks(day) {
10211078
const tripsReversed = day.trips.slice().reverse();
1022-
const allTracks = [];
1023-
1024-
for (let i = 0; i < tripsReversed.length; i++) {
1025-
const t = tripsReversed[i];
1079+
const total = tripsReversed.length;
1080+
1081+
// 开始加载:先重置为「仅当前位置」+ 显示进度浮层
1082+
this._trackLoading = true;
1083+
this._trackLoaded = 0;
1084+
this._trackTotal = total;
1085+
this._activeTrip = -1;
1086+
1087+
this._currentTracks = [];
1088+
this._iframeSrcdoc = buildHistoryIframeHtml(this._baseMode, [], this._getCurrentPosition());
1089+
this.requestUpdate();
1090+
await this.updateComplete;
1091+
1092+
// 并发拉取所有轨迹段
1093+
const results = await Promise.all(tripsReversed.map(async (t, i) => {
10261094
let points = [];
10271095
try {
10281096
const resp = await this.hass.callApi("GET", `tailg/day?id=${encodeURIComponent(t.id)}`);
10291097
points = resp.data || [];
10301098
} catch (err) {
10311099
console.warn("[tailg-history] 拉取轨迹失败", t.id, err);
1032-
continue;
10331100
}
1034-
if (points.length) allTracks.push({ color: colorOf(i), index: i, points });
1035-
}
1036-
1101+
this._trackLoaded++;
1102+
this.requestUpdate();
1103+
return points.length ? { color: colorOf(i), index: i, points } : null;
1104+
}));
1105+
1106+
const allTracks = results.filter(Boolean);
1107+
10371108
this._currentTracks = allTracks;
10381109
this._iframeSrcdoc = buildHistoryIframeHtml(this._baseMode, allTracks, this._getCurrentPosition());
1110+
this._trackLoading = false;
1111+
this.requestUpdate();
10391112
}
10401113

10411114
_onTripClick(newIndex, e) {
@@ -1062,6 +1135,10 @@ class TailgHistoryDialog extends LitElement {
10621135

10631136
render() {
10641137
const m = this._monthSummary();
1138+
const pct = this._trackTotal > 0
1139+
? Math.round(this._trackLoaded / this._trackTotal * 100)
1140+
: 0;
1141+
10651142
return html`
10661143
<div class="dialog">
10671144
<div class="head">
@@ -1075,6 +1152,17 @@ class TailgHistoryDialog extends LitElement {
10751152
${this._iframeSrcdoc
10761153
? html`<iframe .srcdoc=${this._iframeSrcdoc} scrolling="no"></iframe>`
10771154
: html`<div style="display:flex;align-items:center;justify-content:center;height:100%;color:#94a3b8">加载中…</div>`}
1155+
${this._trackLoading ? html`
1156+
<div class="track-loading">
1157+
<div class="spinner"></div>
1158+
<div class="label">
1159+
${this._trackTotal > 0
1160+
? `加载轨迹 ${this._trackLoaded}/${this._trackTotal}`
1161+
: '加载轨迹…'}
1162+
</div>
1163+
${this._trackTotal > 0 ? html`
1164+
<div class="bar"><i style="width:${pct}%"></i></div>` : ''}
1165+
</div>` : ''}
10781166
</div>
10791167
10801168
<div class="list-wrap">

0 commit comments

Comments
 (0)