diff --git a/src/js/pages/basic-info.page.js b/src/js/pages/basic-info.page.js
index e78288f..0d462d7 100644
--- a/src/js/pages/basic-info.page.js
+++ b/src/js/pages/basic-info.page.js
@@ -6,10 +6,12 @@
import { CityPicker, Modal } from '../ui/index.js';
import { Validator, Formatter } from '../utils/index.js';
import { DraftManager, FormIdGenerator, UserCache } from '../core/index.js';
-import { ASSET_CONFIG, BASIC_INFO_CONFIG, PROVINCE_CITY_DATA, CACHE_CONFIG } from '../config/index.js';
+import { ASSET_CONFIG, BASIC_INFO_CONFIG, PROVINCE_CITY_DATA, CACHE_CONFIG, API_CONFIG } from '../config/index.js';
import { showToast } from '../ui/toast.js';
import { AreaService } from '../services/area.service.js';
+import { getLocationService } from '../services/location.service.js';
import { AuthFlowService, AUTH_STATUS } from '../services/index.js';
+import { ApiClient } from '../core/api.js';
export class BasicInfoPage {
constructor() {
@@ -71,6 +73,9 @@ export class BasicInfoPage {
this.renderForm();
this.bindEvents();
this.updateProgress();
+
+ // IP定位自动填充城市
+ this.autoFillCityByLocation();
}
/**
@@ -687,29 +692,27 @@ export class BasicInfoPage {
// 如果没有 h5Urls,显示成功提示
if (!h5Urls || h5Urls.length === 0) {
+ // 有 redirectUrl 跳转到指定地址,否则返回首页
+ const finalUrl = redirectUrl || window.location.href.split('?')[0];
+ const btnText = redirectUrl ? '立即跳转' : '返回首页';
+
authContainer.innerHTML = `
✓
信息提交成功
您的申请已提交成功!
- ${redirectUrl ? `
-
- 5 秒后自动跳转...
-
-
- ` : `
-
- `}
+
+ 5 秒后自动跳转...
+
+
`;
const mainContainer = document.querySelector('.container') || document.body;
mainContainer.insertBefore(authContainer, mainContainer.firstChild);
- // 如果有 redirectUrl,启动倒计时
- if (redirectUrl) {
- this.startFinalCountdown(redirectUrl);
- }
+ // 启动 5 秒倒计时
+ this.startFinalCountdown(finalUrl);
return;
}
@@ -919,6 +922,82 @@ export class BasicInfoPage {
}
}
+ /**
+ * 通过IP定位自动填充城市
+ */
+ async autoFillCityByLocation() {
+ try {
+ // 如果已经有城市值,跳过
+ if (this.basicInfoValues.city) {
+ console.log('[BasicInfoPage] 城市已存在,跳过IP定位填充');
+ return;
+ }
+
+ console.log('[BasicInfoPage] 开始IP定位...');
+ const locationService = getLocationService();
+ const location = await locationService.getLocation();
+
+ if (location) {
+ const { province, city } = location;
+ console.log('[BasicInfoPage] IP定位成功:', province, city);
+
+ // 查找城市代码
+ const cityCode = await this.findCityCode(province, city);
+
+ if (cityCode) {
+ // 自动填充城市
+ this.handleCityConfirm({
+ value: city,
+ province: province,
+ city: city,
+ provinceCode: cityCode.provinceCode,
+ cityCode: cityCode.cityCode
+ });
+
+ console.log('[BasicInfoPage] 城市自动填充成功:', city);
+ } else {
+ console.warn('[BasicInfoPage] 未找到城市代码:', province, city);
+ }
+ } else {
+ console.warn('[BasicInfoPage] IP定位失败: 未获取到位置信息');
+ }
+ } catch (error) {
+ console.error('[BasicInfoPage] IP定位异常:', error);
+ // 静默失败,不影响用户正常使用
+ }
+ }
+
+ /**
+ * 查找城市代码
+ */
+ async findCityCode(provinceName, cityName) {
+ try {
+ // 获取省份数据
+ const provinces = await AreaService.getProvinces();
+ const province = provinces.find(p => p.name === provinceName);
+
+ if (!province) {
+ return null;
+ }
+
+ // 获取城市数据
+ const cities = await AreaService.getCities(province.code);
+ const city = cities.find(c => c.name === cityName && c.code.length === 4);
+
+ if (city) {
+ return {
+ provinceCode: province.code,
+ cityCode: city.code
+ };
+ }
+
+ return null;
+ } catch (error) {
+ console.error('[BasicInfoPage] 查找城市代码失败:', error);
+ return null;
+ }
+ }
+
/**
* 销毁页面
*/
diff --git a/src/js/services/area.service.js b/src/js/services/area.service.js
index 16c9557..9fdbec3 100644
--- a/src/js/services/area.service.js
+++ b/src/js/services/area.service.js
@@ -13,23 +13,50 @@ const CACHE_DURATION = 10 * 60 * 1000; // 10分钟
* 区域服务
*/
export class AreaService {
+ // 正在进行的请求缓存
+ static pendingRequests = new Map();
+
/**
* 获取区域列表
* @param {string} provincecode - 省份代码(可选)
* @returns {Promise} 区域列表 [{code, name}]
*/
static async getAreaList(provincecode) {
- // 检查缓存
const cacheKey = `${CACHE_KEY_PREFIX}${provincecode || 'all'}`;
- const cached = localStorage.getItem(cacheKey);
+ // 检查 localStorage 缓存
+ const cached = localStorage.getItem(cacheKey);
if (cached) {
const { data, timestamp } = JSON.parse(cached);
if (Date.now() - timestamp < CACHE_DURATION) {
+ console.log(`[AreaService] 使用缓存 ${provincecode || 'all'}`);
return data;
}
}
+ // 检查是否有正在进行的请求
+ if (this.pendingRequests.has(cacheKey)) {
+ console.log(`[AreaService] 等待正在进行的请求 ${provincecode || 'all'}`);
+ return this.pendingRequests.get(cacheKey);
+ }
+
+ // 创建新请求
+ const requestPromise = this.doGetAreaList(provincecode, cacheKey);
+ this.pendingRequests.set(cacheKey, requestPromise);
+
+ try {
+ return await requestPromise;
+ } finally {
+ // 请求完成后清除缓存
+ this.pendingRequests.delete(cacheKey);
+ }
+ }
+
+ /**
+ * 执行实际的区域列表请求
+ * @private
+ */
+ static async doGetAreaList(provincecode, cacheKey) {
try {
// 构建请求参数
const params = {};
@@ -37,6 +64,8 @@ export class AreaService {
params.provincecode = provincecode;
}
+ console.log(`[AreaService] 请求区域数据 ${provincecode || 'all'}`);
+
// 使用 ApiClient 发送请求
const result = await ApiClient.get(API_CONFIG.ENDPOINTS.AREA_LIST, params);
@@ -46,7 +75,7 @@ export class AreaService {
const areaList = result.result || [];
- // 保存到缓存
+ // 保存到 localStorage 缓存
localStorage.setItem(cacheKey, JSON.stringify({
data: areaList,
timestamp: Date.now()
diff --git a/src/js/services/location.service.js b/src/js/services/location.service.js
new file mode 100644
index 0000000..e44cef3
--- /dev/null
+++ b/src/js/services/location.service.js
@@ -0,0 +1,124 @@
+/**
+ * 定位服务
+ * 提供全局 IP 定位功能,避免重复请求
+ */
+
+import { API_CONFIG } from '../config/api.config.js';
+import { ApiClient } from '../core/api.js';
+
+/**
+ * 定位服务(单例模式)
+ */
+export class LocationService {
+ static instance = null;
+
+ // 定位缓存
+ locationCache = null;
+
+ // 正在定位的 Promise
+ locatingPromise = null;
+
+ // 缓存有效期(10分钟)
+ CACHE_DURATION = 10 * 60 * 1000;
+
+ /**
+ * 获取单例实例
+ */
+ static getInstance() {
+ if (!this.instance) {
+ this.instance = new LocationService();
+ }
+ return this.instance;
+ }
+
+ /**
+ * 获取当前定位(带缓存)
+ * @returns {Promise