anlingyi / xechat-idea

让你能够在IDEA里实现聊天、下棋、斗地主!
https://xeblog.cn/?tag=xechat-idea
Apache License 2.0
742 stars 149 forks source link

查询天气时获取城市时关于匹配规则的若干疑问? #76

Closed smilesnake closed 2 years ago

smilesnake commented 2 years ago

WeatherActionHandler#

@Override
    public void handle(ChannelHandlerContext ctx, WeatherDTO body) {
        User user = ChannelAction.getUser(ctx);
        if (user == null) {
            return;
        }

        // 构建天气服务,单例
        WeatherService weatherService = Singleton.get(HeFengWeatherServiceImpl.class);
        // 构建城市服务,单例
        CityService cityService = Singleton.get(HeFengCityServiceImpl.class);

        // 地区ID 或 经度纬度坐标
        final String location = body.getLocation();
        // 天气类型
        final WeatherType type = body.getType();

        // 获取相关城市
        CityInfo cityInfo = cityService.getOne(location);
        List<FutureWeather> futureWeatherList = null;
        CurrentWeather weatherNow = null;

        try {
            if (WeatherType.WEATHER_3D == type) {
                // 未来3天
                futureWeatherList = weatherService.getWeather3d(cityInfo.getLocationId());
            } else if (WeatherType.WEATHER_7D == type) {
                // 未来7天
                futureWeatherList = weatherService.getWeather7d(cityInfo.getLocationId());
            } else {
                // 当前
                weatherNow = weatherService.getWeatherNow(cityInfo.getLocationId());
            }
        } catch (Exception e) {
            log.error("出现异常:", e);
            user.send(ResponseBuilder.build(null, "天气查询异常,请联系管理员!", MessageType.SYSTEM));
            return;
        }

        ConsoleTable consoleTable = new ConsoleTable();
        consoleTable.setSBCMode(Boolean.FALSE);
        if (null != weatherNow) {
            consoleTable.addHeader("日期", "天气", "当前温度", "体感温度");
            consoleTable.addBody(DateUtil.today(), weatherNow.getText(), weatherNow.getTemp() + "℃", weatherNow.getFeelsLike() + "℃");
        }

        if (CollUtil.isNotEmpty(futureWeatherList)) {
            consoleTable.addHeader("日期", "天气", "温度");
            futureWeatherList.forEach(weather -> {
                String textWeather = weather.getTextDay() + "转" + weather.getTextNight();
                if (StrUtil.equals(weather.getTextDay(), weather.getTextNight())) {
                    textWeather = weather.getTextDay();
                }
                consoleTable.addBody(weather.getFxDate(), textWeather,
                        weather.getTempMin() + "℃ ~ " + weather.getTempMax() + "℃");
            });
        }

        final String msg = StrUtil.CRLF + cityInfo.getLocationName() + " 天气预报" + StrUtil.CRLF + consoleTable;
        user.send(ResponseBuilder.build(null, msg, MessageType.SYSTEM));
    }

HeFengCityServiceImpl#

    @Override
    public List<CityInfo> getList(String keyword) {
        // 从市/区县、省、市/自治州匹配关键字
        return CITY_INFO_LIST.parallelStream().filter(
                cityInfo -> StrUtil.contains(cityInfo.getLocationName(), keyword) ||
                        StrUtil.contains(cityInfo.getAdmName1(), keyword) ||
                        StrUtil.contains(cityInfo.getAdmName2(), keyword)
        ).collect(Collectors.toList());
    }

    @Override
    public CityInfo getOne(String keyword) {
        // 从市/区县、省、市/自治州匹配关键字,取列表第一个
        List<CityInfo> list = getList(keyword);
        if (CollUtil.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

在HeFengCityServiceImpl#getOne方法中,获取单个城市信息时,查询是模糊匹配的。 1.匹配查询条件的结果是否是随机的? 2.是否需要按照相关性来排序,然后最相关性最高的城市? 3.如果不按照相关性,是否需要按照直辖,地级,省,市,镇,村等级别来排序?

现在问题是,当我输入"#weather 西"时,居然返回是是北京市西城区,陕西省省会城市-西安市居然还没一个区的权重大. 看源码出现这个结果是China-City-List-latest.json文件中,西城在文档最前面,但我感觉这个结果应该是有问题的,有点困惑。望采纳