From 84abbd63fa039a39358fb8db7526b567422f3406 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 05 十一月 2026 16:38:49 +0800
Subject: [PATCH] fix(hrm): 百度地图不可用时降级为手工填坐标,不再阻塞考勤规则保存
---
src/views/hrm/attendance/rule/modules/location-map-picker.vue | 169 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 139 insertions(+), 30 deletions(-)
diff --git a/src/views/hrm/attendance/rule/modules/location-map-picker.vue b/src/views/hrm/attendance/rule/modules/location-map-picker.vue
index 63014eb..7793ee1 100644
--- a/src/views/hrm/attendance/rule/modules/location-map-picker.vue
+++ b/src/views/hrm/attendance/rule/modules/location-map-picker.vue
@@ -2,7 +2,7 @@
<script lang="ts" setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
-import { Alert, Button, Input, Spin, message } from 'ant-design-vue';
+import { Alert, Button, Input, InputNumber, Spin, message } from 'ant-design-vue';
import { loadBaiduMapSdk } from '#/components/map';
@@ -46,6 +46,20 @@
const loading = ref(false);
const searchKeyword = ref('');
const selectedAddress = ref('');
+
+/**
+ * 鎵嬪伐濉啓妯″紡銆�
+ *
+ * 瑙﹀彂鍦烘櫙锛氱櫨搴﹀湴鍥� SDK 鎷夸笉鍒帮紙浼佷笟缃戠粶鎷︽埅 api.map.baidu.com銆�
+ * 娴忚鍣ㄦ彃浠舵嫤鎴�乤k 鍩熷悕鐧藉悕鍗曟湭鏀惧紑绛夛級銆�
+ * 姝ゅ墠杩欑鎯呭喌浼氱洿鎺ユ姏 "Cannot read properties of null (reading 'Map')" 鎴�
+ * "鐧惧害鍦板浘 SDK 鍔犺浇澶辫触"锛岀敤鎴疯繛鑰冨嫟瑙勫垯閮藉瓨涓嶄簡銆�
+ * 鐜板湪鏀逛负锛氬湴鍥句笉鍙敤鏃惰嚜鍔ㄥ垏鎹㈠埌鎵嬪伐杈撳叆缁忕含搴︼紝淇濊瘉涓氬姟涓嶄腑鏂��
+ */
+const manualMode = ref(false);
+const manualName = ref('');
+const manualLongitude = ref<number>();
+const manualLatitude = ref<number>();
let map: AnyMap;
let marker: AnyMap;
@@ -254,6 +268,57 @@
});
}
+/**
+ * 鍒囨崲鍒版墜宸ュ~鍐欐ā寮忋��
+ *
+ * 鐧惧害鍦板浘渚濊禆绗笁鏂� CDN锛坅pi.map.baidu.com锛夛紝鍦ㄥ唴缃戙�佽闃茬伀澧欐嫤鎴��
+ * 娴忚鍣ㄦ彃浠舵嫤鎴�乤k 鍩熷悕鐧藉悕鍗曟湭鏀惧紑鐨勫満鏅笅閮芥嬁涓嶅埌 SDK銆�
+ * 姝ゆ椂蹇呴』闄嶇骇锛屽惁鍒欑敤鎴疯繛鑰冨嫟瑙勫垯閮藉瓨涓嶄簡锛堝悗绔姹傚畾浣嶅紑鍚椂鍦扮偣鍚嶇О+缁忕含搴﹀繀濉級銆�
+ */
+function switchToManual(reason: string) {
+ if (disposed) {
+ return;
+ }
+ manualMode.value = true;
+ loading.value = false;
+ if (!manualName.value) {
+ manualName.value = selectedAddress.value || '';
+ }
+ if (!Number.isFinite(manualLongitude.value) && Number.isFinite(props.longitude)) {
+ manualLongitude.value = Number(props.longitude);
+ }
+ if (!Number.isFinite(manualLatitude.value) && Number.isFinite(props.latitude)) {
+ manualLatitude.value = Number(props.latitude);
+ }
+ message.warning(`${reason}锛屽凡鍒囨崲涓烘墜宸ュ~鍐欏潗鏍嘸);
+}
+
+/** 鎵嬪伐濉啓鍧愭爣鍚庡洖濉〃鍗� */
+function applyManual() {
+ const longitude = Number(manualLongitude.value);
+ const latitude = Number(manualLatitude.value);
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) {
+ message.warning('璇峰~鍐欑粡搴﹀拰绾害');
+ return;
+ }
+ if (longitude < -180 || longitude > 180) {
+ message.warning('缁忓害搴斿湪 -180 ~ 180 涔嬮棿');
+ return;
+ }
+ if (latitude < -90 || latitude > 90) {
+ message.warning('绾害搴斿湪 -90 ~ 90 涔嬮棿');
+ return;
+ }
+ const name = manualName.value.trim();
+ emit('select', {
+ address: name || undefined,
+ latitude: Number(latitude.toFixed(7)),
+ locationName: name || undefined,
+ longitude: Number(longitude.toFixed(7)),
+ });
+ message.success('鍧愭爣宸插簲鐢�');
+}
+
async function handleSearch() {
const keyword = searchKeyword.value.trim();
if (!keyword || !geocoder) {
@@ -295,7 +360,7 @@
}
// SDK 鍥炶皟瑙﹀彂浣� BMapGL 鏈寕杞斤紙甯歌浜� ak 鏃犳晥 / 鍩熷悕鏈巿鏉� / 琚綉缁滄嫤鎴級
if (!window.BMapGL) {
- message.error('鐧惧害鍦板浘鍔犺浇澶辫触锛岃妫�鏌ュ湴鍥� Key 閰嶇疆鎴栫綉缁�');
+ switchToManual('鍦板浘缁勪欢鏈氨缁紝鍙墜宸ュ~鍐欏潗鏍�');
return;
}
const hasCoordinates =
@@ -329,7 +394,8 @@
selectedAddress.value = location.address ?? '';
}
} catch (error: any) {
- message.error(error?.message || '鍦板浘鍒濆鍖栧け璐�');
+ // 鍦板浘涓嶅彲鐢紙缃戠粶鎷︽埅 / ak 鏈巿鏉� / 瓒呮椂锛夋椂闄嶇骇涓烘墜宸ュ~鍐欙紝涓嶈兘闃诲涓氬姟
+ switchToManual(error?.message || '鍦板浘鍔犺浇澶辫触');
} finally {
loading.value = false;
}
@@ -384,33 +450,76 @@
type="warning"
show-icon
message="鐧惧害鍦板浘灏氭湭閰嶇疆"
- description="璇烽厤缃� VITE_BAIDU_MAP_KEY 鍚庨噸鏂版瀯寤哄墠绔紱鏈厤缃椂鍙墜宸ュ~鍐欑粡绾害銆�"
+ description="鏈厤缃� VITE_BAIDU_MAP_KEY锛岃鎵嬪伐濉啓鎵撳崱鍦扮偣鐨勭粡绾害銆�"
/>
- <Spin v-else :spinning="loading">
- <div v-if="!disabled" class="mb-2 flex gap-2">
- <Input
- v-model:value="searchKeyword"
- allow-clear
- placeholder="杈撳叆鐪併�佸競銆佸尯鍜屽叿浣撳湴鐐癸紝渚嬪锛氫箤椴佹湪榻愬競鍘傚尯"
- @press-enter="handleSearch"
+ <template v-else>
+ <!-- 鍦板浘涓嶅彲鐢ㄦ椂鐨勬墜宸ュ~鍐欐ā寮忥紝淇濊瘉涓氬姟涓嶈绗笁鏂� CDN 鍗′綇 -->
+ <template v-if="manualMode">
+ <Alert
+ type="info"
+ show-icon
+ class="mb-2"
+ message="鍦板浘涓嶅彲鐢紝宸插垏鎹负鎵嬪伐濉啓鍧愭爣"
+ description="濡傞暱鏈熸棤娉曞姞杞藉湴鍥撅紝璇锋鏌ユ湇鍔″櫒/娴忚鍣ㄦ槸鍚﹀厑璁歌闂� api.map.baidu.com锛屾垨鑱旂郴绠$悊鍛樼‘璁ょ櫨搴﹀湴鍥� Key 鐨勫煙鍚嶇櫧鍚嶅崟銆�"
/>
- <Button :loading="loading" @click="handleSearch">鎼滅储鍦板潃</Button>
- </div>
- <div
- ref="mapContainer"
- class="h-[360px] w-full overflow-hidden rounded border border-gray-200"
- ></div>
- <div
- class="mt-2 flex flex-wrap justify-between gap-2 text-xs text-gray-500"
- >
- <span>
- {{
- disabled
- ? '鎵撳崱浣嶇疆鍙婂厑璁歌寖鍥�'
- : '鐐瑰嚮鍦板浘閫夋嫨鎵撳崱涓績鐐癸紱钃濊壊鍦嗗湀琛ㄧず鍏佽鎵撳崱鑼冨洿'
- }}
- </span>
- <span v-if="selectedAddress">{{ selectedAddress }}</span>
- </div>
- </Spin>
+ <div class="grid grid-cols-3 gap-2">
+ <Input
+ v-model:value="manualName"
+ :disabled="disabled"
+ placeholder="鎵撳崱鍦扮偣鍚嶇О锛屽锛氬巶鍖哄ぇ闂�"
+ />
+ <InputNumber
+ v-model:value="manualLongitude"
+ :disabled="disabled"
+ :precision="7"
+ :step="0.0001"
+ class="w-full"
+ placeholder="缁忓害锛屽 87.616848"
+ />
+ <InputNumber
+ v-model:value="manualLatitude"
+ :disabled="disabled"
+ :precision="7"
+ :step="0.0001"
+ class="w-full"
+ placeholder="绾害锛屽 43.825592"
+ />
+ </div>
+ <div class="mt-2 flex items-center justify-between">
+ <span class="text-xs text-gray-500">
+ 鍧愭爣椤讳负 WGS84锛圙PS 鍘熷鍧愭爣锛夛紝鍏佽鑼冨洿 {{ radiusMeters }} 绫�
+ </span>
+ <Button v-if="!disabled" type="primary" @click="applyManual">
+ 搴旂敤鍧愭爣
+ </Button>
+ </div>
+ </template>
+ <Spin v-else :spinning="loading">
+ <div v-if="!disabled" class="mb-2 flex gap-2">
+ <Input
+ v-model:value="searchKeyword"
+ allow-clear
+ placeholder="杈撳叆鐪併�佸競銆佸尯鍜屽叿浣撳湴鐐癸紝渚嬪锛氫箤椴佹湪榻愬競鍘傚尯"
+ @press-enter="handleSearch"
+ />
+ <Button :loading="loading" @click="handleSearch">鎼滅储鍦板潃</Button>
+ </div>
+ <div
+ ref="mapContainer"
+ class="h-[360px] w-full overflow-hidden rounded border border-gray-200"
+ ></div>
+ <div
+ class="mt-2 flex flex-wrap justify-between gap-2 text-xs text-gray-500"
+ >
+ <span>
+ {{
+ disabled
+ ? '鎵撳崱浣嶇疆鍙婂厑璁歌寖鍥�'
+ : '鐐瑰嚮鍦板浘閫夋嫨鎵撳崱涓績鐐癸紱钃濊壊鍦嗗湀琛ㄧず鍏佽鎵撳崱鑼冨洿'
+ }}
+ </span>
+ <span v-if="selectedAddress">{{ selectedAddress }}</span>
+ </div>
+ </Spin>
+ </template>
</template>
--
Gitblit v1.9.3