在这里插入图片描述

目录

  1. 概述
  2. 旅游评分基础
  3. 核心评估方法
  4. Kotlin 源代码
  5. JavaScript 编译代码
  6. ArkTS 调用代码
  7. 评分指标详解
  8. 实战应用

概述

旅游已成为现代生活中不可或缺的一部分。无论是周末短途旅行还是长期假期规划,选择合适的旅游景点对于获得最佳旅游体验至关重要。然而,面对众多景点和大量的游客评价,旅游者往往难以做出最优选择。旅游景点评分系统是帮助旅游者了解景点特色、评估景点质量、制定最优旅游计划的重要工具。本文档介绍如何在 Kotlin Multiplatform (KMP) 框架下,结合 OpenHarmony 鸿蒙操作系统,实现一个功能完整的旅游景点评分系统。

旅游景点评分系统是一个综合性的旅游信息平台,它不仅能够对景点进行多维度评分,还能够进行景点对比、生成旅游建议、提供个性化的景点推荐。通过KMP框架的跨端能力,这个工具可以在Android、iOS、Web和OpenHarmony等多个平台上运行,为旅游者提供了一个强大的旅游决策辅助工具。

旅游景点评分的重要性

旅游景点评分在现代旅游中的重要性日益凸显:

  1. 信息参考:科学的评分能够帮助旅游者了解景点的真实情况。
  2. 时间优化:通过评分可以优化旅游时间分配,避免浪费时间在不值得的景点。
  3. 成本控制:合理的景点选择能够控制旅游成本。
  4. 体验提升:选择高评分景点能够显著提升旅游体验。
  5. 决策支持:评分系统为旅游决策提供了科学的支持。

工具的核心价值

旅游景点评分系统提供以下价值:

  • 多维度评分:从景观、设施、服务、价格等多个维度进行评分
  • 综合对比:支持多个景点的对比分析
  • 个性化推荐:根据用户偏好提供个性化的景点推荐
  • 详细信息:提供景点的详细信息和游客评价
  • 旅游建议:根据评分结果提供旅游建议
  • 跨平台支持:一份代码可在多个平台运行,提高开发效率

旅游评分基础

核心概念

景点评分(Attraction Rating):对旅游景点的综合评价,通常用0-100的分数表示。

景观质量(Scenery Quality):景点的自然或人文景观质量。

设施完善度(Facility Completeness):景点的基础设施和便利设施的完善程度。

服务质量(Service Quality):景点提供的服务质量,包括导游、餐饮等。

游客满意度(Tourist Satisfaction):游客对景点的整体满意程度。

性价比(Value for Money):景点的价格与价值的比例。

常见的景点评估维度

自然景观:山水、植被、气候等自然特征。

人文景观:历史、文化、建筑等人文特征。

基础设施:停车场、卫生间、餐饮设施等。

交通便利性:到达景点的便利程度。

游客服务:导游、讲解、安全等服务。

价格合理性:门票价格与景点价值的匹配度。

影响景点评分的关键因素

景观独特性:景点的独特之处是吸引游客的重要因素。

基础设施:完善的基础设施能够提升游客体验。

服务质量:优质的服务能够显著提升游客满意度。

游客数量:适度的游客数量能够提升体验质量。

季节因素:不同季节景点的特色不同。


核心评估方法

1. 景观评估

评估景点的自然和人文景观质量。

2. 设施评估

评估景点的基础设施和便利设施。

3. 服务评估

评估景点提供的各项服务质量。

4. 价格评估

评估景点的价格合理性。

5. 综合评分

综合考虑多个维度,计算总体评分。

6. 个性化推荐

根据用户偏好提供个性化的景点推荐。


Kotlin 源代码

// TouristAttractionRatingSystem.kt
import java.time.LocalDateTime
import kotlin.math.pow

data class Attraction(
    val id: String,
    val name: String,
    val location: String,
    val category: String,
    val ticketPrice: Double,
    val openingHours: String
)

data class AttractionRating(
    val attractionId: String,
    val attractionName: String,
    val sceneryScore: Double,
    val facilityScore: Double,
    val serviceScore: Double,
    val priceScore: Double,
    val overallScore: Double,
    val ratingLevel: String,
    val visitorCount: Int,
    val visitorsPerDay: Double,
    val recommendations: List<String>,
    val timestamp: String
)

data class RatingMetrics(
    val totalAttractions: Long,
    val averageScore: Double,
    val highestRatedAttraction: String,
    val lowestRatedAttraction: String,
    val averageVisitorCount: Double,
    val mostPopularCategory: String
)

data class AttractionComparison(
    val attractions: List<AttractionRating>,
    val bestScenery: String,
    val bestFacility: String,
    val bestService: String,
    val bestValue: String,
    val recommendation: String
)

class TouristAttractionRatingSystem {
    private val attractions = mutableListOf<Attraction>()
    private val ratings = mutableListOf<AttractionRating>()
    private var attractionIdCounter = 0
    
    // 添加景点
    fun addAttraction(
        name: String,
        location: String,
        category: String,
        ticketPrice: Double,
        openingHours: String
    ): Attraction {
        val id = "ATTR${++attractionIdCounter}"
        val attraction = Attraction(id, name, location, category, ticketPrice, openingHours)
        attractions.add(attraction)
        return attraction
    }
    
    // 评分景点
    fun rateAttraction(
        attractionId: String,
        sceneryScore: Double,
        facilityScore: Double,
        serviceScore: Double,
        priceScore: Double,
        visitorCount: Int
    ): AttractionRating {
        val attraction = attractions.find { it.id == attractionId } 
            ?: return AttractionRating("", "", 0.0, 0.0, 0.0, 0.0, 0.0, "", 0, 0.0, emptyList(), "")
        
        // 确保分数在0-100范围内
        val scenery = minOf(maxOf(sceneryScore, 0.0), 100.0)
        val facility = minOf(maxOf(facilityScore, 0.0), 100.0)
        val service = minOf(maxOf(serviceScore, 0.0), 100.0)
        val price = minOf(maxOf(priceScore, 0.0), 100.0)
        
        // 计算综合评分(加权平均)
        val overallScore = scenery * 0.35 + facility * 0.25 + service * 0.25 + price * 0.15
        
        // 判断评分等级
        val ratingLevel = when {
            overallScore >= 90 -> "5星"
            overallScore >= 80 -> "4星"
            overallScore >= 70 -> "3星"
            overallScore >= 60 -> "2星"
            else -> "1星"
        }
        
        // 计算日均游客数
        val visitorsPerDay = visitorCount / 365.0
        
        // 生成建议
        val recommendations = generateRecommendations(
            scenery, facility, service, price, visitorCount, attraction.category
        )
        
        val rating = AttractionRating(
            attractionId, attraction.name, scenery, facility, service, price,
            overallScore, ratingLevel, visitorCount, visitorsPerDay,
            recommendations, LocalDateTime.now().toString()
        )
        
        ratings.add(rating)
        return rating
    }
    
    // 生成建议
    private fun generateRecommendations(
        scenery: Double,
        facility: Double,
        service: Double,
        price: Double,
        visitorCount: Int,
        category: String
    ): List<String> {
        val recommendations = mutableListOf<String>()
        
        if (scenery >= 85) {
            recommendations.add("🏞️ 景观优美,强烈推荐游览")
        } else if (scenery < 60) {
            recommendations.add("🏞️ 景观一般,可作为备选景点")
        }
        
        if (facility >= 80) {
            recommendations.add("🏢 设施完善,游客体验佳")
        } else if (facility < 60) {
            recommendations.add("🏢 设施不完善,建议提前做好准备")
        }
        
        if (service >= 80) {
            recommendations.add("👥 服务质量高,值得体验")
        } else if (service < 60) {
            recommendations.add("👥 服务有待改进,可能影响体验")
        }
        
        if (price >= 75) {
            recommendations.add("💰 性价比高,物有所值")
        } else if (price < 50) {
            recommendations.add("💰 价格较高,需谨慎考虑")
        }
        
        if (visitorCount > 1000000) {
            recommendations.add("👫 游客众多,建议错峰游览")
        } else if (visitorCount < 100000) {
            recommendations.add("👫 游客较少,可能冷门景点")
        }
        
        if (category == "自然景观" && scenery >= 80) {
            recommendations.add("🌿 自然风光秀美,适合摄影爱好者")
        } else if (category == "人文景观" && service >= 80) {
            recommendations.add("🏛️ 文化底蕴深厚,值得深入了解")
        }
        
        return recommendations
    }
    
    // 获取评分指标
    fun getRatingMetrics(): RatingMetrics {
        if (ratings.isEmpty()) {
            return RatingMetrics(0, 0.0, "", "", 0.0, "")
        }
        
        val totalAttractions = attractions.size.toLong()
        val averageScore = ratings.map { it.overallScore }.average()
        val highestRated = ratings.maxByOrNull { it.overallScore }?.attractionName ?: ""
        val lowestRated = ratings.minByOrNull { it.overallScore }?.attractionName ?: ""
        val averageVisitors = ratings.map { it.visitorCount }.average()
        
        val mostPopularCategory = attractions.groupBy { it.category }
            .maxByOrNull { it.value.size }?.key ?: ""
        
        return RatingMetrics(
            totalAttractions, averageScore, highestRated, lowestRated,
            averageVisitors, mostPopularCategory
        )
    }
    
    // 获取所有评分
    fun getAllRatings(): List<AttractionRating> {
        return ratings.toList()
    }
    
    // 景点对比
    fun compareAttractions(attractionIds: List<String>): AttractionComparison {
        val comparisonRatings = ratings.filter { it.attractionId in attractionIds }
        
        val bestScenery = comparisonRatings.maxByOrNull { it.sceneryScore }?.attractionName ?: ""
        val bestFacility = comparisonRatings.maxByOrNull { it.facilityScore }?.attractionName ?: ""
        val bestService = comparisonRatings.maxByOrNull { it.serviceScore }?.attractionName ?: ""
        val bestValue = comparisonRatings.maxByOrNull { it.priceScore }?.attractionName ?: ""
        
        val avgScore = comparisonRatings.map { it.overallScore }.average()
        val recommendation = when {
            avgScore >= 85 -> "这些景点整体评分很高,都值得游览"
            avgScore >= 75 -> "这些景点评分良好,可根据偏好选择"
            else -> "这些景点评分一般,建议选择评分最高的"
        }
        
        return AttractionComparison(
            comparisonRatings, bestScenery, bestFacility, bestService, bestValue, recommendation
        )
    }
    
    // 生成旅游报告
    fun generateTouristReport(): Map<String, Any> {
        val metrics = getRatingMetrics()
        
        return mapOf(
            "timestamp" to LocalDateTime.now().toString(),
            "metrics" to metrics,
            "ratings" to ratings.toList(),
            "topAttractions" to ratings.sortedByDescending { it.overallScore }.take(5),
            "recommendations" to generateGeneralRecommendations(metrics)
        )
    }
    
    // 生成通用建议
    private fun generateGeneralRecommendations(metrics: RatingMetrics): List<String> {
        val recommendations = mutableListOf<String>()
        
        if (metrics.averageScore >= 80) {
            recommendations.add("📊 整体景点质量高,旅游选择丰富")
        } else if (metrics.averageScore < 70) {
            recommendations.add("📊 整体景点质量一般,建议选择高评分景点")
        }
        
        if (metrics.averageVisitorCount > 500000) {
            recommendations.add("👫 热门景点众多,建议提前规划行程")
        }
        
        recommendations.add("✅ 根据个人偏好选择景点,制定最优旅游计划")
        
        return recommendations
    }
    
    // 清空数据
    fun clearData() {
        attractions.clear()
        ratings.clear()
    }
}

fun main() {
    val system = TouristAttractionRatingSystem()
    
    // 添加景点
    system.addAttraction("黄山", "安徽省", "自然景观", 190.0, "06:00-18:00")
    system.addAttraction("故宫", "北京市", "人文景观", 60.0, "08:30-17:00")
    system.addAttraction("西湖", "浙江省", "自然景观", 0.0, "全天开放")
    
    // 评分景点
    val rating1 = system.rateAttraction("ATTR1", 95.0, 85.0, 90.0, 80.0, 2000000)
    val rating2 = system.rateAttraction("ATTR2", 90.0, 88.0, 85.0, 85.0, 3000000)
    val rating3 = system.rateAttraction("ATTR3", 92.0, 80.0, 88.0, 90.0, 2500000)
    
    println("景点评分结果:")
    println("${rating1.attractionName}: ${String.format("%.2f", rating1.overallScore)} (${rating1.ratingLevel})")
    println("${rating2.attractionName}: ${String.format("%.2f", rating2.overallScore)} (${rating2.ratingLevel})")
    println("${rating3.attractionName}: ${String.format("%.2f", rating3.overallScore)} (${rating3.ratingLevel})")
    
    // 生成报告
    val report = system.generateTouristReport()
    println("\n旅游报告已生成")
}

Kotlin代码说明:这个Kotlin实现提供了完整的旅游景点评分功能。TouristAttractionRatingSystem 类能够管理景点信息、进行景点评分、进行景点对比、生成旅游报告。通过使用数据类和科学的计算方法,代码既简洁又准确。系统支持多维度的景点分析,从单个景点的详细评分到整个景点库的趋势分析,为旅游者提供了全面的旅游决策支持。


JavaScript 编译代码

// TouristAttractionRatingSystem.js
class Attraction {
    constructor(id, name, location, category, ticketPrice, openingHours) {
        this.id = id;
        this.name = name;
        this.location = location;
        this.category = category;
        this.ticketPrice = ticketPrice;
        this.openingHours = openingHours;
    }
}

class AttractionRating {
    constructor(attractionId, attractionName, sceneryScore, facilityScore, serviceScore, priceScore, overallScore, ratingLevel, visitorCount, visitorsPerDay, recommendations, timestamp) {
        this.attractionId = attractionId;
        this.attractionName = attractionName;
        this.sceneryScore = sceneryScore;
        this.facilityScore = facilityScore;
        this.serviceScore = serviceScore;
        this.priceScore = priceScore;
        this.overallScore = overallScore;
        this.ratingLevel = ratingLevel;
        this.visitorCount = visitorCount;
        this.visitorsPerDay = visitorsPerDay;
        this.recommendations = recommendations;
        this.timestamp = timestamp;
    }
}

class RatingMetrics {
    constructor(totalAttractions, averageScore, highestRatedAttraction, lowestRatedAttraction, averageVisitorCount, mostPopularCategory) {
        this.totalAttractions = totalAttractions;
        this.averageScore = averageScore;
        this.highestRatedAttraction = highestRatedAttraction;
        this.lowestRatedAttraction = lowestRatedAttraction;
        this.averageVisitorCount = averageVisitorCount;
        this.mostPopularCategory = mostPopularCategory;
    }
}

class TouristAttractionRatingSystem {
    constructor() {
        this.attractions = [];
        this.ratings = [];
        this.attractionIdCounter = 0;
    }
    
    addAttraction(name, location, category, ticketPrice, openingHours) {
        const id = `ATTR${++this.attractionIdCounter}`;
        const attraction = new Attraction(id, name, location, category, ticketPrice, openingHours);
        this.attractions.push(attraction);
        return attraction;
    }
    
    rateAttraction(attractionId, sceneryScore, facilityScore, serviceScore, priceScore, visitorCount) {
        const attraction = this.attractions.find(a => a.id === attractionId);
        if (!attraction) return null;
        
        const scenery = Math.min(Math.max(sceneryScore, 0), 100);
        const facility = Math.min(Math.max(facilityScore, 0), 100);
        const service = Math.min(Math.max(serviceScore, 0), 100);
        const price = Math.min(Math.max(priceScore, 0), 100);
        
        const overallScore = scenery * 0.35 + facility * 0.25 + service * 0.25 + price * 0.15;
        
        let ratingLevel;
        if (overallScore >= 90) ratingLevel = "5星";
        else if (overallScore >= 80) ratingLevel = "4星";
        else if (overallScore >= 70) ratingLevel = "3星";
        else if (overallScore >= 60) ratingLevel = "2星";
        else ratingLevel = "1星";
        
        const visitorsPerDay = visitorCount / 365;
        
        const recommendations = this.generateRecommendations(scenery, facility, service, price, visitorCount, attraction.category);
        
        const rating = new AttractionRating(attractionId, attraction.name, scenery, facility, service, price, overallScore, ratingLevel, visitorCount, visitorsPerDay, recommendations, new Date().toISOString());
        
        this.ratings.push(rating);
        return rating;
    }
    
    generateRecommendations(scenery, facility, service, price, visitorCount, category) {
        const recommendations = [];
        
        if (scenery >= 85) {
            recommendations.push("🏞️ 景观优美,强烈推荐游览");
        } else if (scenery < 60) {
            recommendations.push("🏞️ 景观一般,可作为备选景点");
        }
        
        if (facility >= 80) {
            recommendations.push("🏢 设施完善,游客体验佳");
        } else if (facility < 60) {
            recommendations.push("🏢 设施不完善,建议提前做好准备");
        }
        
        if (service >= 80) {
            recommendations.push("👥 服务质量高,值得体验");
        } else if (service < 60) {
            recommendations.push("👥 服务有待改进,可能影响体验");
        }
        
        if (price >= 75) {
            recommendations.push("💰 性价比高,物有所值");
        } else if (price < 50) {
            recommendations.push("💰 价格较高,需谨慎考虑");
        }
        
        if (visitorCount > 1000000) {
            recommendations.push("👫 游客众多,建议错峰游览");
        } else if (visitorCount < 100000) {
            recommendations.push("👫 游客较少,可能冷门景点");
        }
        
        if (category === "自然景观" && scenery >= 80) {
            recommendations.push("🌿 自然风光秀美,适合摄影爱好者");
        } else if (category === "人文景观" && service >= 80) {
            recommendations.push("🏛️ 文化底蕴深厚,值得深入了解");
        }
        
        return recommendations;
    }
    
    getRatingMetrics() {
        if (this.ratings.length === 0) {
            return new RatingMetrics(0, 0, "", "", 0, "");
        }
        
        const totalAttractions = this.attractions.length;
        const averageScore = this.ratings.reduce((sum, r) => sum + r.overallScore, 0) / this.ratings.length;
        const highestRated = this.ratings.reduce((max, r) => r.overallScore > max.overallScore ? r : max).attractionName;
        const lowestRated = this.ratings.reduce((min, r) => r.overallScore < min.overallScore ? r : min).attractionName;
        const averageVisitors = this.ratings.reduce((sum, r) => sum + r.visitorCount, 0) / this.ratings.length;
        
        const categoryCount = {};
        for (const attraction of this.attractions) {
            categoryCount[attraction.category] = (categoryCount[attraction.category] || 0) + 1;
        }
        const mostPopularCategory = Object.keys(categoryCount).reduce((a, b) => categoryCount[a] > categoryCount[b] ? a : b, "");
        
        return new RatingMetrics(totalAttractions, averageScore, highestRated, lowestRated, averageVisitors, mostPopularCategory);
    }
    
    getAllRatings() {
        return this.ratings;
    }
    
    compareAttractions(attractionIds) {
        const comparisonRatings = this.ratings.filter(r => attractionIds.includes(r.attractionId));
        
        const bestScenery = comparisonRatings.reduce((max, r) => r.sceneryScore > max.sceneryScore ? r : max).attractionName;
        const bestFacility = comparisonRatings.reduce((max, r) => r.facilityScore > max.facilityScore ? r : max).attractionName;
        const bestService = comparisonRatings.reduce((max, r) => r.serviceScore > max.serviceScore ? r : max).attractionName;
        const bestValue = comparisonRatings.reduce((max, r) => r.priceScore > max.priceScore ? r : max).attractionName;
        
        const avgScore = comparisonRatings.reduce((sum, r) => sum + r.overallScore, 0) / comparisonRatings.length;
        let recommendation;
        if (avgScore >= 85) recommendation = "这些景点整体评分很高,都值得游览";
        else if (avgScore >= 75) recommendation = "这些景点评分良好,可根据偏好选择";
        else recommendation = "这些景点评分一般,建议选择评分最高的";
        
        return {
            attractions: comparisonRatings,
            bestScenery: bestScenery,
            bestFacility: bestFacility,
            bestService: bestService,
            bestValue: bestValue,
            recommendation: recommendation
        };
    }
    
    generateTouristReport() {
        const metrics = this.getRatingMetrics();
        
        return {
            timestamp: new Date().toISOString(),
            metrics: metrics,
            ratings: this.ratings,
            topAttractions: this.ratings.sort((a, b) => b.overallScore - a.overallScore).slice(0, 5),
            recommendations: this.generateGeneralRecommendations(metrics)
        };
    }
    
    generateGeneralRecommendations(metrics) {
        const recommendations = [];
        
        if (metrics.averageScore >= 80) {
            recommendations.push("📊 整体景点质量高,旅游选择丰富");
        } else if (metrics.averageScore < 70) {
            recommendations.push("📊 整体景点质量一般,建议选择高评分景点");
        }
        
        if (metrics.averageVisitorCount > 500000) {
            recommendations.push("👫 热门景点众多,建议提前规划行程");
        }
        
        recommendations.push("✅ 根据个人偏好选择景点,制定最优旅游计划");
        
        return recommendations;
    }
    
    clearData() {
        this.attractions = [];
        this.ratings = [];
    }
}

// 使用示例
const system = new TouristAttractionRatingSystem();

system.addAttraction("黄山", "安徽省", "自然景观", 190, "06:00-18:00");
system.addAttraction("故宫", "北京市", "人文景观", 60, "08:30-17:00");
system.addAttraction("西湖", "浙江省", "自然景观", 0, "全天开放");

const rating1 = system.rateAttraction("ATTR1", 95, 85, 90, 80, 2000000);
const rating2 = system.rateAttraction("ATTR2", 90, 88, 85, 85, 3000000);
const rating3 = system.rateAttraction("ATTR3", 92, 80, 88, 90, 2500000);

console.log("景点评分结果:");
console.log(`${rating1.attractionName}: ${rating1.overallScore.toFixed(2)} (${rating1.ratingLevel})`);
console.log(`${rating2.attractionName}: ${rating2.overallScore.toFixed(2)} (${rating2.ratingLevel})`);
console.log(`${rating3.attractionName}: ${rating3.overallScore.toFixed(2)} (${rating3.ratingLevel})`);

const report = system.generateTouristReport();
console.log("\n旅游报告已生成");

JavaScript代码说明:JavaScript版本是Kotlin代码的直接转译。我们使用ES6的class语法定义各个类,使用数学函数进行计算。整体逻辑和算法与Kotlin版本保持一致,确保跨平台的一致性。JavaScript的灵活性使得代码更加简洁,同时保持了清晰的结构和完整的功能。


ArkTS 调用代码

// TouristAttractionPage.ets
import { TouristAttractionRatingSystem } from './TouristAttractionRatingSystem';

@Entry
@Component
struct TouristAttractionPage {
    @State attractionName: string = '黄山';
    @State location: string = '安徽省';
    @State category: string = '自然景观';
    @State ticketPrice: number = 190;
    @State sceneryScore: number = 95;
    @State facilityScore: number = 85;
    @State serviceScore: number = 90;
    @State priceScore: number = 80;
    @State visitorCount: number = 2000000;
    @State selectedTab: number = 0;
    @State ratings: Array<any> = [];
    @State metrics: any = null;
    @State isLoading: boolean = false;
    @State errorMessage: string = '';
    @State report: any = null;
    
    private system: TouristAttractionRatingSystem = new TouristAttractionRatingSystem();
    private categories = ['自然景观', '人文景观', '主题公园', '宗教景点', '城市景观'];
    
    addAndRateAttraction() {
        if (!this.attractionName.trim() || !this.location.trim()) {
            this.errorMessage = '请输入景点名称和位置';
            return;
        }
        
        this.isLoading = true;
        this.errorMessage = '';
        
        try {
            this.system.addAttraction(
                this.attractionName,
                this.location,
                this.category,
                this.ticketPrice,
                "全天开放"
            );
            
            const attractionId = `ATTR${this.ratings.length + 1}`;
            this.system.rateAttraction(
                attractionId,
                this.sceneryScore,
                this.facilityScore,
                this.serviceScore,
                this.priceScore,
                this.visitorCount
            );
            
            this.ratings = this.system.getAllRatings();
            this.metrics = this.system.getRatingMetrics();
            
            AlertDialog.show({ message: '景点已添加并评分' });
            
            // 重置表单
            this.attractionName = '';
            this.location = '';
            this.sceneryScore = 80;
            this.facilityScore = 80;
            this.serviceScore = 80;
            this.priceScore = 80;
        } catch (error) {
            this.errorMessage = '操作失败: ' + error.message;
        } finally {
            this.isLoading = false;
        }
    }
    
    generateReport() {
        this.isLoading = true;
        
        try {
            this.report = this.system.generateTouristReport();
        } catch (error) {
            this.errorMessage = '生成报告失败: ' + error.message;
        } finally {
            this.isLoading = false;
        }
    }
    
    getRatingLevelColor(level: string): string {
        switch (level) {
            case '5星': return '#FFD700';
            case '4星': return '#4CAF50';
            case '3星': return '#FF9800';
            case '2星': return '#F44336';
            case '1星': return '#D32F2F';
            default: return '#999999';
        }
    }
    
    build() {
        Column() {
            Text('旅游景点评分系统')
                .fontSize(24)
                .fontWeight(FontWeight.Bold)
                .margin({ top: 20, bottom: 20 })
            
            Tabs({ barPosition: BarPosition.Start }) {
                TabContent() {
                    Column() {
                        Text('添加景点').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                        
                        Text('景点名称:').fontSize(12).margin({ bottom: 5 })
                        TextInput({ placeholder: '黄山' })
                            .value(this.attractionName)
                            .onChange((value: string) => { this.attractionName = value; })
                            .height(40).padding(10).border({ width: 1, color: '#cccccc' }).margin({ bottom: 15 })
                        
                        Row() {
                            Column() {
                                Text('位置:').fontSize(12).margin({ bottom: 5 })
                                TextInput({ placeholder: '安徽省' })
                                    .value(this.location)
                                    .onChange((value: string) => { this.location = value; })
                                    .height(40).padding(10).border({ width: 1, color: '#cccccc' })
                            }
                            .flex(1)
                            
                            Column() {
                                Text('门票价格:').fontSize(12).margin({ bottom: 5 })
                                TextInput({ placeholder: '190' })
                                    .type(InputType.Number)
                                    .value(this.ticketPrice.toString())
                                    .onChange((value: string) => { this.ticketPrice = parseFloat(value) || 0; })
                                    .height(40).padding(10).border({ width: 1, color: '#cccccc' })
                            }
                            .flex(1)
                            .margin({ left: 10 })
                        }
                        .margin({ bottom: 15 })
                        
                        Text('景点类别:').fontSize(12).margin({ bottom: 5 })
                        Select(this.categories.map(c => ({ value: c })))
                            .value(this.category)
                            .onSelect((index: number, value?: string) => {
                                this.category = value || '自然景观';
                            })
                            .margin({ bottom: 15 })
                        
                        Text('景观评分:').fontSize(12).margin({ bottom: 5 })
                        Slider({ value: this.sceneryScore, min: 0, max: 100, step: 5 })
                            .onChange((value: number) => { this.sceneryScore = value; })
                            .margin({ bottom: 15 })
                        
                        Row() {
                            Column() {
                                Text('设施评分:').fontSize(12).margin({ bottom: 5 })
                                Slider({ value: this.facilityScore, min: 0, max: 100, step: 5 })
                                    .onChange((value: number) => { this.facilityScore = value; })
                            }
                            .flex(1)
                            
                            Column() {
                                Text('服务评分:').fontSize(12).margin({ bottom: 5 })
                                Slider({ value: this.serviceScore, min: 0, max: 100, step: 5 })
                                    .onChange((value: number) => { this.serviceScore = value; })
                            }
                            .flex(1)
                            .margin({ left: 10 })
                        }
                        .margin({ bottom: 15 })
                        
                        Text('价格评分:').fontSize(12).margin({ bottom: 5 })
                        Slider({ value: this.priceScore, min: 0, max: 100, step: 5 })
                            .onChange((value: number) => { this.priceScore = value; })
                            .margin({ bottom: 15 })
                        
                        Text('年游客数:').fontSize(12).margin({ bottom: 5 })
                        TextInput({ placeholder: '2000000' })
                            .type(InputType.Number)
                            .value(this.visitorCount.toString())
                            .onChange((value: string) => { this.visitorCount = parseInt(value) || 0; })
                            .height(40).padding(10).border({ width: 1, color: '#cccccc' }).margin({ bottom: 15 })
                        
                        Button('添加并评分').width('100%').height(40).margin({ bottom: 15 })
                            .onClick(() => { this.addAndRateAttraction(); }).enabled(!this.isLoading)
                        
                        if (this.errorMessage) {
                            Text(this.errorMessage).fontSize(12).fontColor('#F44336').margin({ bottom: 15 })
                        }
                    }
                    .padding(15)
                }
                .tabBar('➕ 添加景点')
                
                TabContent() {
                    Column() {
                        if (this.ratings.length > 0) {
                            Text('景点评分').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            List() {
                                ForEach(this.ratings, (rating: any) => {
                                    ListItem() {
                                        Column() {
                                            Row() {
                                                Text(rating.attractionName).fontSize(14).fontWeight(FontWeight.Bold).flex(1)
                                                Text(rating.ratingLevel).fontSize(12).fontColor(this.getRatingLevelColor(rating.ratingLevel))
                                                    .fontWeight(FontWeight.Bold)
                                            }
                                            .margin({ bottom: 10 })
                                            
                                            Row() {
                                                Text('综合评分:').fontSize(11)
                                                Text(rating.overallScore.toFixed(1)).fontSize(11).fontWeight(FontWeight.Bold)
                                                    .fontColor('#2196F3')
                                            }
                                            .margin({ bottom: 5 })
                                            
                                            Row() {
                                                Column() {
                                                    Text('景观:').fontSize(10).fontColor('#999999')
                                                    Text(rating.sceneryScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
                                                }
                                                .flex(1)
                                                
                                                Column() {
                                                    Text('设施:').fontSize(10).fontColor('#999999')
                                                    Text(rating.facilityScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
                                                }
                                                .flex(1)
                                                
                                                Column() {
                                                    Text('服务:').fontSize(10).fontColor('#999999')
                                                    Text(rating.serviceScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
                                                }
                                                .flex(1)
                                                
                                                Column() {
                                                    Text('价格:').fontSize(10).fontColor('#999999')
                                                    Text(rating.priceScore.toFixed(0)).fontSize(10).fontWeight(FontWeight.Bold)
                                                }
                                                .flex(1)
                                            }
                                        }
                                        .padding(10).border({ width: 1, color: '#eeeeee' }).borderRadius(5)
                                    }
                                }, (rating: any) => rating.attractionId)
                            }
                        } else {
                            Text('请先添加景点').fontSize(12).fontColor('#999999')
                        }
                    }
                    .padding(15)
                }
                .tabBar('⭐ 评分列表')
                
                TabContent() {
                    Column() {
                        if (this.metrics) {
                            Text('评分指标').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            Row() {
                                Column() {
                                    Text('平均评分').fontSize(11).fontColor('#999999')
                                    Text(this.metrics.averageScore.toFixed(1)).fontSize(18)
                                        .fontWeight(FontWeight.Bold).fontColor('#2196F3').margin({ top: 5 })
                                }
                                .flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
                                
                                Column() {
                                    Text('景点总数').fontSize(11).fontColor('#999999')
                                    Text(this.metrics.totalAttractions.toString()).fontSize(18)
                                        .fontWeight(FontWeight.Bold).fontColor('#4CAF50').margin({ top: 5 })
                                }
                                .flex(1).alignItems(HorizontalAlign.Center).padding(15).backgroundColor('#F5F5F5').borderRadius(5)
                                .margin({ left: 10 })
                            }
                            .margin({ bottom: 15 })
                            
                            Column() {
                                Row() {
                                    Text('最高评分:').fontSize(12)
                                    Text(this.metrics.highestRatedAttraction).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                                .margin({ bottom: 10 })
                                
                                Row() {
                                    Text('最低评分:').fontSize(12)
                                    Text(this.metrics.lowestRatedAttraction).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                                .margin({ bottom: 10 })
                                
                                Row() {
                                    Text('热门类别:').fontSize(12)
                                    Text(this.metrics.mostPopularCategory).fontSize(12).fontWeight(FontWeight.Bold)
                                }
                            }
                            .padding(10).backgroundColor('#F5F5F5').borderRadius(5)
                        } else {
                            Text('请先添加景点').fontSize(12).fontColor('#999999')
                        }
                    }
                    .padding(15)
                }
                .tabBar('📊 指标')
                
                TabContent() {
                    Column() {
                        Button('生成报告').width('100%').height(40).margin({ bottom: 15 })
                            .onClick(() => { this.generateReport(); })
                        
                        if (this.report) {
                            Text('旅游报告').fontSize(16).fontWeight(FontWeight.Bold).margin({ bottom: 15 })
                            
                            if (this.report.recommendations && this.report.recommendations.length > 0) {
                                Text('建议:').fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 10 })
                                
                                Column() {
                                    ForEach(this.report.recommendations, (rec: string, index: number) => {
                                        Row() {
                                            Text('•').fontSize(14).fontWeight(FontWeight.Bold).margin({ right: 10 })
                                            Text(rec).fontSize(11).flex(1)
                                        }
                                        .padding(10).margin({ bottom: 8 }).backgroundColor('#E3F2FD').borderRadius(5)
                                    }, (rec: string, index: number) => index.toString())
                                }
                            }
                        }
                    }
                    .padding(15)
                }
                .tabBar('📈 报告')
            }
            .width('100%')
            .flex(1)
        }
        .padding(10)
        .width('100%')
        .height('100%')
    }
}

ArkTS代码说明:这个ArkTS实现展示了如何在OpenHarmony应用中集成旅游景点评分系统。通过使用标签页组件,用户可以在添加景点、查看评分列表、查看评分指标和生成报告之间切换。UI设计直观,提供了良好的用户体验。每个标签页都有不同的功能,用户可以全面地进行景点评分和旅游规划。


评分指标详解

景点评分维度

景观评分:景点的自然或人文景观质量,范围0-100。

设施评分:景点的基础设施和便利设施完善程度,范围0-100。

服务评分:景点提供的服务质量,范围0-100。

价格评分:景点价格的合理性,范围0-100。

综合评分:四个维度的加权平均,权重分别为35%、25%、25%、15%。

评分等级

5星:综合评分90-100分,景点质量优秀。

4星:综合评分80-89分,景点质量良好。

3星:综合评分70-79分,景点质量一般。

2星:综合评分60-69分,景点质量较差。

1星:综合评分0-59分,景点质量很差。


实战应用

应用场景1:旅游规划

旅游者可以使用这个系统评估不同景点,制定最优的旅游计划。

应用场景2:景点管理

景点管理部门可以使用这个系统了解游客评价,改进景点管理。

应用场景3:旅游推荐

旅游平台可以集成这个系统,为用户提供个性化的景点推荐。

应用场景4:旅游研究

旅游研究机构可以使用这个系统进行景点评估和旅游市场分析。


总结

旅游景点评分系统是现代旅游中的重要工具。通过KMP框架和OpenHarmony操作系统的结合,我们可以实现一个功能完整、高效可靠的景点评分系统。

这个工具不仅能够对景点进行多维度评分,还能够进行景点对比、生成旅游建议、提供个性化的景点推荐。通过本文介绍的Kotlin实现、JavaScript编译和ArkTS调用,旅游者可以快速构建自己的旅游决策系统。

在实际应用中,景点评分的价值远不止于此。从提升旅游体验到优化旅游资源配置,从支持旅游决策到促进旅游产业发展,景点评分都发挥着重要的作用。通过持续改进和优化,可以构建更加科学和高效的旅游评估体系。

掌握好景点评分的方法和工具,对于提升旅游体验和实现旅游目标都有重要的帮助。通过这个系统的学习和使用,希望能够帮助旅游者更好地了解景点特色,制定科学的旅游计划,享受美好的旅游体验。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐