重构:统一缓存管理和消除重复代码
This commit is contained in:
103
src/js/core/cache-manager.js
Normal file
103
src/js/core/cache-manager.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* 通用缓存管理器
|
||||||
|
* 提供 localStorage 缓存、请求去重和过期时间管理
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class CacheManager {
|
||||||
|
// 正在进行的请求缓存(静态)
|
||||||
|
static pendingRequests = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存或执行请求
|
||||||
|
* @param {string} cacheKey - 缓存键
|
||||||
|
* @param {Function} fetchFn - 获取数据的异步函数
|
||||||
|
* @param {number} duration - 缓存有效期(毫秒),默认 10 分钟
|
||||||
|
* @returns {Promise<any>} - 缓存的数据或新获取的数据
|
||||||
|
*/
|
||||||
|
static async getCachedOrFetch(cacheKey, fetchFn, duration = 10 * 60 * 1000) {
|
||||||
|
// 检查 localStorage 缓存
|
||||||
|
const cached = this._getFromCache(cacheKey, duration);
|
||||||
|
if (cached !== null) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有正在进行的请求
|
||||||
|
if (this.pendingRequests.has(cacheKey)) {
|
||||||
|
console.log(`[CacheManager] 等待正在进行的请求: ${cacheKey}`);
|
||||||
|
return this.pendingRequests.get(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新请求
|
||||||
|
const requestPromise = this._fetchAndCache(cacheKey, fetchFn, duration);
|
||||||
|
this.pendingRequests.set(cacheKey, requestPromise);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await requestPromise;
|
||||||
|
} finally {
|
||||||
|
// 请求完成后清除缓存
|
||||||
|
this.pendingRequests.delete(cacheKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 localStorage 获取缓存
|
||||||
|
* @private
|
||||||
|
* @param {string} key - 缓存键
|
||||||
|
* @param {number} duration - 有效期(毫秒)
|
||||||
|
* @returns {any|null} - 缓存的数据,如果不存在或已过期则返回 null
|
||||||
|
*/
|
||||||
|
static _getFromCache(key, duration) {
|
||||||
|
const cached = localStorage.getItem(key);
|
||||||
|
if (cached) {
|
||||||
|
try {
|
||||||
|
const { data, timestamp } = JSON.parse(cached);
|
||||||
|
if (Date.now() - timestamp < duration) {
|
||||||
|
console.log(`[CacheManager] 使用缓存: ${key}`);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`[CacheManager] 缓存解析失败: ${key}`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据并缓存
|
||||||
|
* @private
|
||||||
|
* @param {string} key - 缓存键
|
||||||
|
* @param {Function} fetchFn - 获取数据的异步函数
|
||||||
|
* @param {number} duration - 有效期(毫秒)
|
||||||
|
* @returns {Promise<any>} - 获取的数据
|
||||||
|
*/
|
||||||
|
static async _fetchAndCache(key, fetchFn, duration) {
|
||||||
|
const data = await fetchFn();
|
||||||
|
localStorage.setItem(key, JSON.stringify({
|
||||||
|
data,
|
||||||
|
timestamp: Date.now()
|
||||||
|
}));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除指定前缀的所有缓存
|
||||||
|
* @param {string} prefix - 缓存键前缀
|
||||||
|
*/
|
||||||
|
static clearCacheByPrefix(prefix) {
|
||||||
|
Object.keys(localStorage)
|
||||||
|
.filter(key => key.startsWith(prefix))
|
||||||
|
.forEach(key => localStorage.removeItem(key));
|
||||||
|
console.log(`[CacheManager] 清除缓存前缀: ${prefix}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除单个缓存
|
||||||
|
* @param {string} key - 缓存键
|
||||||
|
*/
|
||||||
|
static clearCache(key) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
console.log(`[CacheManager] 清除缓存: ${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CacheManager;
|
||||||
@@ -6,17 +6,13 @@
|
|||||||
import { CACHE_CONFIG } from '../config/index.js';
|
import { CACHE_CONFIG } from '../config/index.js';
|
||||||
|
|
||||||
export class FormIdGenerator {
|
export class FormIdGenerator {
|
||||||
// 防止递归调用检测
|
|
||||||
static _gettingFormId = false;
|
|
||||||
static _lastFormId = '';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机9位数字的表单唯一标识符
|
* 生成随机9位数字的表单唯一标识符
|
||||||
* @returns {number} - 9位随机数字
|
* @returns {number} - 9位随机数字
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _generateRandomId() {
|
static _generateRandomId() {
|
||||||
return Math.floor(Math.random() * 900000000) + 100000000; // 生成100000000-999999999之间的9位数字
|
return Math.floor(Math.random() * 900000000) + 100000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,32 +20,15 @@ export class FormIdGenerator {
|
|||||||
* @returns {string} - 表单ID字符串
|
* @returns {string} - 表单ID字符串
|
||||||
*/
|
*/
|
||||||
static getOrCreate() {
|
static getOrCreate() {
|
||||||
// 防止递归调用检测
|
let formId = localStorage.getItem(CACHE_CONFIG.KEYS.FORM_ID);
|
||||||
if (this._gettingFormId) {
|
|
||||||
console.error('[FormIdGenerator] 检测到递归调用 getOrCreateFormId', new Error().stack);
|
if (!formId) {
|
||||||
return this._lastFormId || '';
|
formId = this._generateRandomId().toString();
|
||||||
|
localStorage.setItem(CACHE_CONFIG.KEYS.FORM_ID, formId);
|
||||||
|
console.log('[FormIdGenerator] 生成新的表单ID:', formId);
|
||||||
}
|
}
|
||||||
this._gettingFormId = true;
|
|
||||||
|
|
||||||
try {
|
return formId;
|
||||||
console.log('[FormIdGenerator] getOrCreate 被调用');
|
|
||||||
let formId = localStorage.getItem(CACHE_CONFIG.KEYS.FORM_ID);
|
|
||||||
console.log('[FormIdGenerator] 从 localStorage 获取的 formId:', formId);
|
|
||||||
|
|
||||||
if (!formId) {
|
|
||||||
formId = this._generateRandomId().toString();
|
|
||||||
localStorage.setItem(CACHE_CONFIG.KEYS.FORM_ID, formId);
|
|
||||||
console.log('[FormIdGenerator] 生成新的表单ID:', formId);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._lastFormId = formId;
|
|
||||||
return formId;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[FormIdGenerator] getOrCreate 出错:', error);
|
|
||||||
return '';
|
|
||||||
} finally {
|
|
||||||
this._gettingFormId = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +36,6 @@ export class FormIdGenerator {
|
|||||||
*/
|
*/
|
||||||
static clear() {
|
static clear() {
|
||||||
localStorage.removeItem(CACHE_CONFIG.KEYS.FORM_ID);
|
localStorage.removeItem(CACHE_CONFIG.KEYS.FORM_ID);
|
||||||
this._lastFormId = '';
|
|
||||||
console.log('[FormIdGenerator] 已清除表单ID');
|
console.log('[FormIdGenerator] 已清除表单ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +57,6 @@ export class FormIdGenerator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
localStorage.setItem(CACHE_CONFIG.KEYS.FORM_ID, formId);
|
localStorage.setItem(CACHE_CONFIG.KEYS.FORM_ID, formId);
|
||||||
this._lastFormId = formId;
|
|
||||||
console.log('[FormIdGenerator] 已设置表单ID:', formId);
|
console.log('[FormIdGenerator] 已设置表单ID:', formId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -910,7 +910,7 @@ export class BasicInfoPage {
|
|||||||
console.log('[BasicInfoPage] IP定位成功:', province, city);
|
console.log('[BasicInfoPage] IP定位成功:', province, city);
|
||||||
|
|
||||||
// 查找城市代码
|
// 查找城市代码
|
||||||
const cityCode = await this.findCityCode(province, city);
|
const cityCode = await AreaService.findCityCode(province, city);
|
||||||
|
|
||||||
if (cityCode) {
|
if (cityCode) {
|
||||||
// 自动填充城市
|
// 自动填充城市
|
||||||
@@ -935,37 +935,6 @@ export class BasicInfoPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找城市代码
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 销毁页面
|
* 销毁页面
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { Picker, Modal, OneClickLoginButton } from '../ui/index.js';
|
import { Picker, Modal, OneClickLoginButton } from '../ui/index.js';
|
||||||
import { Validator, Formatter } from '../utils/index.js';
|
import { Validator, Formatter } from '../utils/index.js';
|
||||||
import { SMSService, AuthService, LoanService } from '../services/index.js';
|
import { SMSService, AuthService, LoanService } from '../services/index.js';
|
||||||
|
import { AuthFlowService } from '../services/auth-flow.service.js';
|
||||||
import { LOAN_CONFIG, PURPOSE_PICKER_CONFIG, TERM_PICKER_CONFIG, ANIMATION_CONFIG } from '../config/index.js';
|
import { LOAN_CONFIG, PURPOSE_PICKER_CONFIG, TERM_PICKER_CONFIG, ANIMATION_CONFIG } from '../config/index.js';
|
||||||
import { UserCache } from '../core/user-cache.js';
|
import { UserCache } from '../core/user-cache.js';
|
||||||
import { showToast } from '../ui/toast.js';
|
import { showToast } from '../ui/toast.js';
|
||||||
@@ -30,8 +31,8 @@ export class IndexPage {
|
|||||||
// 注意:使用一键登录需要在极光控制台配置域名白名单,否则会出现跨域错误
|
// 注意:使用一键登录需要在极光控制台配置域名白名单,否则会出现跨域错误
|
||||||
this.jVerifyAppId = '80570da3ef331d9de547b4f1';
|
this.jVerifyAppId = '80570da3ef331d9de547b4f1';
|
||||||
|
|
||||||
// 倒计时定时器
|
// 倒计时取消函数
|
||||||
this.countdownTimer = null;
|
this.countdownCancel = null;
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -314,24 +315,27 @@ export class IndexPage {
|
|||||||
* @param {HTMLElement} countdownEl - 倒计时元素
|
* @param {HTMLElement} countdownEl - 倒计时元素
|
||||||
*/
|
*/
|
||||||
startCountdown(countdownEl) {
|
startCountdown(countdownEl) {
|
||||||
let time = 59;
|
|
||||||
countdownEl.textContent = `${time}s`;
|
|
||||||
countdownEl.style.color = '#999';
|
countdownEl.style.color = '#999';
|
||||||
countdownEl.style.cursor = 'default';
|
countdownEl.style.cursor = 'default';
|
||||||
countdownEl.onclick = null;
|
countdownEl.onclick = null;
|
||||||
|
|
||||||
this.countdownTimer = setInterval(() => {
|
// 清除之前的倒计时
|
||||||
time--;
|
if (this.countdownCancel) {
|
||||||
if (time > 0) {
|
this.countdownCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.countdownCancel = AuthFlowService.startCountdown(
|
||||||
|
59,
|
||||||
|
(time) => {
|
||||||
countdownEl.textContent = `${time}s`;
|
countdownEl.textContent = `${time}s`;
|
||||||
} else {
|
},
|
||||||
|
() => {
|
||||||
countdownEl.textContent = '重新发送';
|
countdownEl.textContent = '重新发送';
|
||||||
countdownEl.style.color = '#3474fe';
|
countdownEl.style.color = '#3474fe';
|
||||||
countdownEl.style.cursor = 'pointer';
|
countdownEl.style.cursor = 'pointer';
|
||||||
countdownEl.onclick = () => this.resendSMS(countdownEl);
|
countdownEl.onclick = () => this.resendSMS(countdownEl);
|
||||||
clearInterval(this.countdownTimer);
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -534,8 +538,8 @@ export class IndexPage {
|
|||||||
* 销毁页面
|
* 销毁页面
|
||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this.countdownTimer) {
|
if (this.countdownCancel) {
|
||||||
clearInterval(this.countdownTimer);
|
this.countdownCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.purposePicker) {
|
if (this.purposePicker) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import { API_CONFIG } from '../config/api.config.js';
|
import { API_CONFIG } from '../config/api.config.js';
|
||||||
import { ApiClient } from '../core/api.js';
|
import { ApiClient } from '../core/api.js';
|
||||||
|
import { CacheManager } from '../core/cache-manager.js';
|
||||||
|
|
||||||
const CACHE_KEY_PREFIX = 'area_cache_';
|
const CACHE_KEY_PREFIX = 'area_cache_';
|
||||||
const CACHE_DURATION = 10 * 60 * 1000; // 10分钟
|
const CACHE_DURATION = 10 * 60 * 1000; // 10分钟
|
||||||
@@ -13,9 +14,6 @@ const CACHE_DURATION = 10 * 60 * 1000; // 10分钟
|
|||||||
* 区域服务
|
* 区域服务
|
||||||
*/
|
*/
|
||||||
export class AreaService {
|
export class AreaService {
|
||||||
// 正在进行的请求缓存
|
|
||||||
static pendingRequests = new Map();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取区域列表
|
* 获取区域列表
|
||||||
* @param {string} provincecode - 省份代码(可选)
|
* @param {string} provincecode - 省份代码(可选)
|
||||||
@@ -24,68 +22,18 @@ export class AreaService {
|
|||||||
static async getAreaList(provincecode) {
|
static async getAreaList(provincecode) {
|
||||||
const cacheKey = `${CACHE_KEY_PREFIX}${provincecode || 'all'}`;
|
const cacheKey = `${CACHE_KEY_PREFIX}${provincecode || 'all'}`;
|
||||||
|
|
||||||
// 检查 localStorage 缓存
|
return CacheManager.getCachedOrFetch(cacheKey, async () => {
|
||||||
const cached = localStorage.getItem(cacheKey);
|
const params = provincecode ? { provincecode } : {};
|
||||||
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 = {};
|
|
||||||
if (provincecode) {
|
|
||||||
params.provincecode = provincecode;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`[AreaService] 请求区域数据 ${provincecode || 'all'}`);
|
console.log(`[AreaService] 请求区域数据 ${provincecode || 'all'}`);
|
||||||
|
|
||||||
// 使用 ApiClient 发送请求
|
|
||||||
const result = await ApiClient.get(API_CONFIG.ENDPOINTS.AREA_LIST, params);
|
const result = await ApiClient.get(API_CONFIG.ENDPOINTS.AREA_LIST, params);
|
||||||
|
|
||||||
if (result.retcode !== 0) {
|
if (result.retcode !== 0) {
|
||||||
throw new Error(result.retmsg || '获取区域数据失败');
|
throw new Error(result.retmsg || '获取区域数据失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
const areaList = result.result || [];
|
return result.result || [];
|
||||||
|
}, CACHE_DURATION);
|
||||||
// 保存到 localStorage 缓存
|
|
||||||
localStorage.setItem(cacheKey, JSON.stringify({
|
|
||||||
data: areaList,
|
|
||||||
timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
|
|
||||||
return areaList;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[AreaService] 获取区域数据失败:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,13 +56,49 @@ export class AreaService {
|
|||||||
return this.getAreaList(provincecode);
|
return this.getAreaList(provincecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据省市名称查找代码
|
||||||
|
* @param {string} provinceName - 省份名称
|
||||||
|
* @param {string} cityName - 城市名称
|
||||||
|
* @returns {Promise<Object|null>} - {provinceCode, cityCode},如果未找到则返回 null
|
||||||
|
*/
|
||||||
|
static async findCityCode(provinceName, cityName) {
|
||||||
|
if (!provinceName || !cityName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const provinces = await this.getProvinces();
|
||||||
|
const province = provinces.find(p => p.name === provinceName);
|
||||||
|
|
||||||
|
if (!province) {
|
||||||
|
console.warn(`[AreaService] 未找到省份: ${provinceName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const areas = await this.getCities(province.code);
|
||||||
|
const city = areas.find(c => c.name === cityName && c.code.length === 4);
|
||||||
|
|
||||||
|
if (!city) {
|
||||||
|
console.warn(`[AreaService] 未找到城市: ${provinceName}-${cityName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
provinceCode: province.code,
|
||||||
|
cityCode: city.code
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[AreaService] 查找城市代码失败:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除缓存
|
* 清除缓存
|
||||||
*/
|
*/
|
||||||
static clearCache() {
|
static clearCache() {
|
||||||
Object.keys(localStorage)
|
CacheManager.clearCacheByPrefix(CACHE_KEY_PREFIX);
|
||||||
.filter(key => key.startsWith(CACHE_KEY_PREFIX))
|
|
||||||
.forEach(key => localStorage.removeItem(key));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -671,7 +671,7 @@ export class CityPicker {
|
|||||||
console.log('[CityPicker] IP定位成功:', province, city);
|
console.log('[CityPicker] IP定位成功:', province, city);
|
||||||
|
|
||||||
// 查找城市代码
|
// 查找城市代码
|
||||||
const cityCode = await this.findCityCode(province, city);
|
const cityCode = await AreaService.findCityCode(province, city);
|
||||||
|
|
||||||
if (cityCode) {
|
if (cityCode) {
|
||||||
this.currentLocationCity = {
|
this.currentLocationCity = {
|
||||||
@@ -703,40 +703,4 @@ export class CityPicker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找城市代码
|
|
||||||
* @param {string} provinceName - 省份名称
|
|
||||||
* @param {string} cityName - 城市名称
|
|
||||||
* @returns {Promise<Object|null>} - 包含省代码和市代码的对象
|
|
||||||
*/
|
|
||||||
async findCityCode(provinceName, cityName) {
|
|
||||||
try {
|
|
||||||
// 先在省份数据中查找省份代码
|
|
||||||
if (this.provinces.length === 0) {
|
|
||||||
await this.loadProvinces();
|
|
||||||
}
|
|
||||||
|
|
||||||
const province = this.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('[CityPicker] 查找城市代码失败:', error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user