wangrong
7 天以前 5ebdf612b8291106370bba5e79996b28a7452e67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import type { LngLat } from 'vue-tianditu2';
import { useCool } from '/@/cool';
 
export const MAP_TK = '51915011aa0997aa2ddd7e38504fa8bc';
export const MAP_LOAD = { v: '4.0', tk: MAP_TK };
export const DEFAULT_CENTER: LngLat = [121.280637, 32.125178];
export const DEFAULT_ZOOM = 16;
export const MAP_ZOOM_KEY = 'map.zoomlevel';
export const MAP_COORD_KEY = 'map.coordinates';
 
function paramText(raw: unknown): string {
    if (raw == null) return '';
    if (typeof raw === 'string' || typeof raw === 'number') return String(raw).trim();
    if (Array.isArray(raw)) return raw.map(e => String(e).trim()).join(',');
    return '';
}
 
export function parseMapZoom(raw: unknown, fallback = DEFAULT_ZOOM) {
    const n = Number(paramText(raw));
    return Number.isFinite(n) && n > 0 ? n : fallback;
}
 
export function parseMapCenter(raw: unknown, fallback: LngLat = DEFAULT_CENTER): LngLat {
    const text = paramText(raw);
    const parts = text.split(/[,,]/).map(s => Number(s.trim()));
    if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {
        return [parts[0], parts[1]];
    }
    return fallback;
}
 
/** 从 base_sys_param 读取学校地图默认视角:map.zoomlevel、map.coordinates(lon,lat) */
export async function loadMapView(service: any): Promise<{ center: LngLat; zoom: number }> {
    const read = async (key: string) => {
        try {
            if (service?.base?.sys?.param?.stringbykey) {
                return await service.base.sys.param.stringbykey({ key });
            }
            return await service.request({
                url: 'admin/base/sys/param/stringbykey',
                params: { key }
            });
        } catch {
            return '';
        }
    };
    const [zoomRaw, coordRaw] = await Promise.all([read(MAP_ZOOM_KEY), read(MAP_COORD_KEY)]);
    return {
        center: parseMapCenter(coordRaw),
        zoom: parseMapZoom(zoomRaw)
    };
}
 
export function pinIcon(color: string) {
    const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="40" viewBox="0 0 28 40"><path fill="${color}" stroke="#fff" stroke-width="1.5" d="M14 1C7.4 1 2 6.4 2 13c0 8.8 12 25 12 25s12-16.2 12-25C26 6.4 20.6 1 14 1z"/><circle cx="14" cy="13" r="5" fill="#fff"/></svg>`;
    return {
        iconUrl: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg),
        iconSize: [28, 40] as [number, number],
        iconAnchor: [14, 40] as [number, number]
    };
}
 
export const SITE_ICONS = {
    收集点: pinIcon('#16a34a'),
    压缩站: pinIcon('#f59e0b'),
    default: pinIcon('#3b82f6')
};
 
export function siteIcon(type: string) {
    if (type === '压缩站') return SITE_ICONS.压缩站;
    if (type === '收集点') return SITE_ICONS.收集点;
    return SITE_ICONS.default;
}
 
export const SORTER_ICON = pinIcon('#2563eb');
export const VEHICLE_ICON = pinIcon('#7c3aed');
export const PLAY_ICON = pinIcon('#ef4444');
 
export function useMapsApi() {
    const { service } = useCool();
 
    function call(name: string, data?: Record<string, any>) {
        const api = (service as any).maps?.live?.[name];
        if (typeof api === 'function') {
            return api.call((service as any).maps.live, data);
        }
        return service.request({
            url: `admin/maps/live/${name}`,
            method: 'POST',
            data
        });
    }
 
    return {
        sites: () => call('sites'),
        siteWeight: (data: { businessId: string; startTime: string; endTime: string }) => call('siteWeight', data),
        sorterOnline: () => call('sorterOnline'),
        sorterTrack: (data: { idCard: string; startTime: string; endTime: string }) => call('sorterTrack', data),
        sorterHealth: (idCard: string) => call('sorterHealth', { idCard }),
        vehicleOnline: () => call('vehicleOnline'),
        vehicleTrack: (data: { vehicleNo: string; startTime: string; endTime: string }) => call('vehicleTrack', data),
        vehicleEvents: (vehicleNo: string) => call('vehicleEvents', { vehicleNo })
    };
}
 
export async function fetchYsToken(service: any) {
    const res = await service.base.sys.param.stringbykey({ key: 'ys7.accessToken' });
    return (res as string) || '';
}
 
export function formatTime(v: any) {
    if (!v) return '-';
    const d = new Date(v);
    if (Number.isNaN(d.getTime())) return String(v);
    const p = (n: number) => String(n).padStart(2, '0');
    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
}
 
export function dayRange(offsetEnd = 0, offsetStart = 0) {
    const end = new Date();
    end.setHours(23, 59, 59, 999);
    if (offsetEnd) end.setTime(end.getTime() + offsetEnd);
    const start = new Date();
    start.setHours(0, 0, 0, 0);
    if (offsetStart) start.setTime(start.getTime() + offsetStart);
    return { start, end };
}
 
export function lastHours(hours = 1) {
    const end = new Date();
    const start = new Date(end.getTime() - hours * 3600 * 1000);
    return { start, end };
}
 
export function toStamp(v: any) {
    const t = new Date(v).getTime();
    return Number.isFinite(t) ? t : 0;
}