卢春龙
2026-08-17 f525b6c3cc105bd1a997d893937689bebcc9570d
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
 
export const DEFAULT_TEMPERATURE_UNIT = '°C'; // 默认温度单位
 
/**
 * 原始天气类型(接口返回)→ 前端展示文案 的分类表。
 * 依据产品需求文档「原始天气类型(接口返回) / 前端展示文案」对照表逐行整理,
 * 每一项 text 为前端展示文案,types 为归入该文案的原始天气类型集合。
 */
const WEATHER_DESC_CATEGORIES: Array<{ text: string; types: string[] }> = [
  { text: '晴', types: ['晴'] },
  { text: '多云', types: ['少云', '多云', '晴间多云'] },
  { text: '阴', types: ['阴'] },
  { text: '阵雨', types: ['阵雨', '强阵雨'] },
  { text: '雷阵雨', types: ['雷阵雨', '强雷阵雨'] },
  { text: '雷雨冰雹', types: ['雷阵雨并伴有冰雹'] },
  { text: '小雨', types: ['毛毛雨/细雨', '小雨'] },
  { text: '中雨', types: ['中雨'] },
  { text: '大雨', types: ['大雨'] },
  { text: '暴雨', types: ['暴雨', '大暴雨', '特大暴雨', '极端降雨', '大雨-暴雨'] },
  { text: '小到中雨', types: ['小雨-中雨'] },
  { text: '中到大雨', types: ['中雨-大雨'] },
  { text: '小雪', types: ['雪', '小雪'] },
  { text: '中雪', types: ['中雪'] },
  { text: '大雪', types: ['大雪'] },
  { text: '暴雪', types: ['暴雪'] },
  { text: '小到中雪', types: ['小雪-中雪'] },
  { text: '中到大雪', types: ['中雪-大雪'] },
  { text: '雨夹雪', types: ['雨雪天气', '雨夹雪', '阵雨夹雪'] },
  { text: '冻雨', types: ['冻雨'] },
  { text: '大雾', types: ['雾', '轻雾', '大雾'] },
  { text: '浓雾', types: ['浓雾', '强浓雾', '特强浓雾'] },
  { text: '霾', types: ['霾'] },
  { text: '中度霾', types: ['中度霾'] },
  { text: '重度霾', types: ['重度霾', '严重霾'] },
  { text: '微风', types: ['平静', '微风', '和风', '清风', '有风'] },
  { text: '大风', types: ['强风/劲风', '疾风', '大风', '烈风'] },
  { text: '飓风', types: ['风暴', '狂爆风', '热带风暴', '飓风'] },
  { text: '扬沙', types: ['浮尘', '扬沙'] },
  { text: '沙尘暴', types: ['沙尘暴', '强沙尘暴'] },
  { text: '龙卷风', types: ['龙卷风'] },
  { text: '酷热', types: ['热'] },
  { text: '严寒', types: ['冷'] },
  { text: '', types: ['未知'] },
];
 
/**
 * 根据高德天气返回的原始天气类型,转换为前端统一展示文案。
 * @param weatherDesc 高德天气返回的原始天气类型(接口返回值)
 * @returns 前端展示文案;未命中分类表时原样返回入参,空值返回空字符串
 */
export const getWeatherIconByDesc = (weatherDesc: string) => {
  if (!weatherDesc) return '';
  const category = WEATHER_DESC_CATEGORIES.find((item) => item.types.includes(weatherDesc));
  return category ? category.text : weatherDesc;
};
 
/**
 * 统一温度单位配置,兼容后台可能下发的不同文案格式。
 */
export const normalizeTemperatureUnit = (unit?: string) => {
  const safeUnit = String(unit || '').trim().toLowerCase(); // 后台温度单位原始值
  if (!safeUnit) {
    return DEFAULT_TEMPERATURE_UNIT;
  }
  if (safeUnit.includes('f') || safeUnit.includes('℉') || safeUnit.includes('华氏')) {
    return '°F';
  }
  return DEFAULT_TEMPERATURE_UNIT;
};
 
/**
 * 按配置单位转换天气温度,高德天气温度默认按摄氏温度处理。
 */
export const convertTemperatureByUnit = (temperature: string | number | null | undefined, unit: string) => {
  const numericTemperature = Number(temperature); // 原始天气温度
  if (!Number.isFinite(numericTemperature)) {
    return String(temperature || '--');
  }
  if (unit === '°F') {
    const fahrenheitTemperature = (numericTemperature * 9) / 5 + 32; // 摄氏转华氏
    return Number.isInteger(fahrenheitTemperature) ? String(fahrenheitTemperature) : fahrenheitTemperature.toFixed(1).replace(/\.0$/, '');
  }
  return Number.isInteger(numericTemperature) ? String(numericTemperature) : numericTemperature.toFixed(1).replace(/\.0$/, '');
};