在这里插入图片描述

项目概述

旅游已成为现代生活中重要的休闲方式,但规划一次完美的旅行往往需要花费大量时间和精力。游客需要考虑目的地选择、行程安排、景点推荐、交通方案、住宿预订等多个方面,这些复杂的决策往往导致旅游体验不佳。本文介绍一个基于Kotlin Multiplatform(KMP)和OpenHarmony框架的智能旅游行程规划系统,该系统能够根据用户的旅游偏好、时间预算和出行方式,智能生成个性化的旅游行程,推荐最佳景点和路线,帮助用户规划一次完美的旅行。

这个系统采用了现代化的技术栈,包括Kotlin后端逻辑处理、JavaScript中间层数据转换、以及ArkTS前端UI展示。通过多层架构设计,实现了跨平台的无缝协作,为旅游爱好者提供了一个完整的行程规划解决方案。系统不仅能够分析用户的旅游需求,还能够根据季节、天气、人流量等因素提供科学的行程建议,确保用户获得最佳的旅游体验。

核心功能模块

1. 目的地智能推荐

系统根据用户的旅游类型、季节、预算等因素,智能推荐最适合的旅游目的地。

2. 行程自动规划

基于目的地和旅游天数,系统自动生成详细的日程安排,包括每日景点、交通方案、用餐建议等。

3. 景点智能排序

根据景点的距离、热度、开放时间等因素,智能排序景点访问顺序,优化旅游路线。

4. 成本预算分析

详细计算旅游的各项成本,包括交通、住宿、餐饮、门票等,帮助用户进行预算规划。

5. 实时天气与安全提示

提供目的地的天气预报和安全提示,帮助用户做好充分准备。

Kotlin后端实现

Kotlin是一种现代化的编程语言,运行在JVM上,具有简洁的语法和强大的功能。以下是旅游行程规划系统的核心Kotlin实现代码:

// ========================================
// 智能旅游行程规划系统 - Kotlin实现
// ========================================
@JsExport
fun smartTravelItineraryPlanningSystem(inputData: String): String {
    val parts = inputData.trim().split(" ")
    if (parts.size != 7) {
        return "❌ 格式错误\n请输入: 用户ID 旅游天数 预算(元) 旅游类型(1-5) 出行人数 出发月份(1-12) 体力等级(1-5)\n\n例如: USER001 7 10000 2 2 6 3"
    }
    
    val userId = parts[0].lowercase()
    val travelDays = parts[1].toIntOrNull()
    val budget = parts[2].toIntOrNull()
    val travelType = parts[3].toIntOrNull()
    val groupSize = parts[4].toIntOrNull()
    val departureMonth = parts[5].toIntOrNull()
    val fitnessLevel = parts[6].toIntOrNull()
    
    if (travelDays == null || budget == null || travelType == null || groupSize == null || departureMonth == null || fitnessLevel == null) {
        return "❌ 数值错误\n请输入有效的数字"
    }
    
    if (travelDays < 1 || travelDays > 30 || budget < 0 || travelType < 1 || travelType > 5 || groupSize < 1 || groupSize > 20 || departureMonth < 1 || departureMonth > 12 || fitnessLevel < 1 || fitnessLevel > 5) {
        return "❌ 参数范围错误\n天数(1-30)、预算(≥0)、类型(1-5)、人数(1-20)、月份(1-12)、体力(1-5)"
    }
    
    // 旅游类型描述
    val travelTypeDesc = when (travelType) {
        1 -> "🏖️ 海滨度假"
        2 -> "🏔️ 山地探险"
        3 -> "🏛️ 文化古迹"
        4 -> "🌃 城市观光"
        else -> "🌲 自然生态"
    }
    
    // 季节描述
    val seasonDesc = when (departureMonth) {
        in 3..5 -> "🌸 春季"
        in 6..8 -> "☀️ 夏季"
        in 9..11 -> "🍂 秋季"
        else -> "❄️ 冬季"
    }
    
    // 体力等级描述
    val fitnessDesc = when (fitnessLevel) {
        1 -> "🪑 轻松(主要游览)"
        2 -> "🚶 温和(适度步行)"
        3 -> "🏃 中等(较多步行)"
        4 -> "💪 高强度(大量步行)"
        else -> "🔥 极限(登山探险)"
    }
    
    // 每日预算计算
    val dailyBudget = budget / travelDays
    
    // 人均预算
    val perCapitaBudget = budget / groupSize
    
    // 预算分配
    val accommodationBudget = (budget * 0.35).toInt()  // 35%用于住宿
    val transportBudget = (budget * 0.25).toInt()  // 25%用于交通
    val mealBudget = (budget * 0.25).toInt()  // 25%用于餐饮
    val ticketBudget = (budget * 0.15).toInt()  // 15%用于门票

    // 推荐目的地
    val recommendedDestination = when (travelType) {
        1 -> "三亚、厦门、青岛"
        2 -> "张家界、黄山、泰山"
        3 -> "西安、北京、南京"
        4 -> "上海、深圳、杭州"
        else -> "九寨沟、稻城亚丁、桂林"
    }
    
    // 每日景点数量建议
    val dailyAttractions = when (fitnessLevel) {
        1 -> 2
        2 -> 3
        3 -> 4
        4 -> 5
        else -> 6
    }
    
    // 总景点数量
    val totalAttractions = dailyAttractions * travelDays
    
    // 行程强度评估
    val itineraryIntensity = when {
        dailyAttractions >= 5 -> "🔥 紧凑型"
        dailyAttractions >= 3 -> "👍 适中型"
        else -> "🧘 悠闲型"
    }
    
    // 出行方式推荐
    val transportationMode = when (travelType) {
        1 -> "✈️ 飞机 + 出租车"
        2 -> "🚗 自驾车"
        3 -> "🚂 高铁 + 公交"
        4 -> "🚇 地铁 + 出租车"
        else -> "🚌 大巴 + 步行"
    }
    
    // 住宿建议
    val accommodationAdvice = when {
        perCapitaBudget >= 500 -> "⭐⭐⭐⭐⭐ 五星级酒店"
        perCapitaBudget >= 300 -> "⭐⭐⭐⭐ 四星级酒店"
        perCapitaBudget >= 150 -> "⭐⭐⭐ 三星级酒店"
        perCapitaBudget >= 80 -> "⭐⭐ 经济型酒店"
        else -> "⭐ 青年旅舍"
    }
    
    // 餐饮建议
    val diningAdvice = when (travelType) {
        1 -> "🍤 海鲜餐厅、海边烧烤"
        2 -> "🍲 山区特色菜、农家乐"
        3 -> "🥢 传统美食、老字号餐厅"
        4 -> "🍽️ 高档餐厅、美食街"
        else -> "🥗 野外露营、简餐"
    }
    
    // 最佳出行时间
    val bestTravelTime = when (travelType) {
        1 -> "5月-10月(避免台风季)"
        2 -> "4月-10月(避免冬季严寒)"
        3 -> "全年皆可(春秋最佳)"
        4 -> "全年皆可(避免极端天气)"
        else -> "5月-10月(最佳观景期)"
    }
    
    // 行程规划评分
    val planningScore = buildString {
        var score = 0
        if (travelDays >= 5) score += 20
        else if (travelDays >= 3) score += 15
        else score += 10
        
        if (budget >= 10000) score += 25
        else if (budget >= 5000) score += 20
        else if (budget >= 2000) score += 15
        else score += 10
        
        if (groupSize >= 3) score += 20
        else if (groupSize == 2) score += 15
        else score += 10
        
        if (fitnessLevel >= 3) score += 20
        else if (fitnessLevel >= 2) score += 15
        else score += 10
        
        if (seasonDesc.contains("春") || seasonDesc.contains("秋")) score += 15
        else score += 10
        
        when {
            score >= 95 -> appendLine("🌟 行程规划优秀 (${score}分)")
            score >= 80 -> appendLine("✅ 行程规划良好 (${score}分)")
            score >= 65 -> appendLine("👍 行程规划中等 (${score}分)")
            score >= 50 -> appendLine("⚠️ 行程规划一般 (${score}分)")
            else -> appendLine("🔴 行程规划需改进 (${score}分)")
        }
    }
    
    // 行程建议
    val itineraryAdvice = buildString {
        if (travelDays <= 2) {
            appendLine("  • 时间较短,建议选择单个城市深度游")
            appendLine("  • 避免频繁更换住宿地点")
            appendLine("  • 重点游览核心景点")
        } else if (travelDays <= 5) {
            appendLine("  • 时间适中,可游览1-2个城市")
            appendLine("  • 建议安排2-3个住宿地点")
            appendLine("  • 平衡景点和休息时间")
        } else {
            appendLine("  • 时间充足,可规划多城市行程")
            appendLine("  • 建议每个城市停留2-3天")
            appendLine("  • 可加入深度体验和当地文化")
        }
        
        if (budget < 5000) {
            appendLine("  • 预算有限,建议选择性价比高的目的地")
            appendLine("  • 利用公共交通,避免打车")
            appendLine("  • 选择经济型住宿和街边美食")
        }
        
        if (fitnessLevel <= 2) {
            appendLine("  • 体力有限,避免过于紧凑的行程")
            appendLine("  • 安排充足的休息时间")
            appendLine("  • 选择轻松的景点和活动")
        }
    }
    
    // 安全提示
    val safetyTips = buildString {
        appendLine("  • 出发前购买旅游保险")
        appendLine("  • 准备好身份证、护照等证件")
        appendLine("  • 告知家人行程和联系方式")
        appendLine("  • 避免携带大量现金")
        appendLine("  • 关注目的地天气和安全预警")
    }
    
    return buildString {
        appendLine("✈️ 智能旅游行程规划系统")
        appendLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
        appendLine()
        appendLine("👤 旅游信息:")
        appendLine("  用户ID: $userId")
        appendLine("  旅游天数: ${travelDays}天")
        appendLine("  出行人数: ${groupSize}人")
        appendLine("  出发季节: $seasonDesc")
        appendLine()
        appendLine("🎯 旅游类型:")
        appendLine("  旅游类型: $travelTypeDesc")
        appendLine("  体力等级: $fitnessDesc")
        appendLine("  行程强度: $itineraryIntensity")
        appendLine()
        appendLine("💰 预算分析:")
        appendLine("  总预算: ¥${budget}元")
        appendLine("  日均预算: ¥${dailyBudget}元")
        appendLine("  人均预算: ¥${perCapitaBudget}元")
        appendLine("  住宿预算: ¥${accommodationBudget}元")
        appendLine("  交通预算: ¥${transportBudget}元")
        appendLine("  餐饮预算: ¥${mealBudget}元")
        appendLine("  门票预算: ¥${ticketBudget}元")
        appendLine()
        appendLine("🗺️ 目的地推荐:")
        appendLine("  推荐目的地: $recommendedDestination")
        appendLine("  最佳出行时间: $bestTravelTime")
        appendLine()
        appendLine("🚗 交通方案:")
        appendLine("  推荐方式: $transportationMode")
        appendLine()
        appendLine("🏨 住宿建议:")
        appendLine("  住宿等级: $accommodationAdvice")
        appendLine()
        appendLine("🍽️ 餐饮建议:")
        appendLine("  餐饮类型: $diningAdvice")
        appendLine()
        appendLine("📊 景点规划:")
        appendLine("  每日景点数: ${dailyAttractions}个")
        appendLine("  总景点数: ${totalAttractions}个")
        appendLine()
        appendLine("📈 行程评分:")
        appendLine(planningScore)
        appendLine()
        appendLine("💡 行程建议:")
        appendLine(itineraryAdvice)
        appendLine()
        appendLine("🛡️ 安全提示:")
        appendLine(safetyTips)
        appendLine()
        appendLine("🎯 行程目标:")
        appendLine("  • 游览${totalAttractions}个主要景点")
        appendLine("  • 体验当地文化和美食")
        appendLine("  • 拍摄精美照片")
        appendLine("  • 留下美好回忆")
        appendLine()
        appendLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
        appendLine("✅ 规划完成")
    }
}

这段Kotlin代码实现了旅游行程规划系统的核心逻辑。首先进行参数验证,确保输入数据的有效性。然后根据旅游类型、天数、预算等因素进行智能分析,计算每日预算、人均预算,分配各项成本。接着根据用户的体力等级和旅游类型推荐最佳目的地和出行方式。最后生成详细的行程建议、住宿推荐、餐饮建议和安全提示。

代码中使用了@JsExport注解,这是Kotlin/JS的特性,允许Kotlin代码被JavaScript调用。通过when表达式进行条件判断,使用buildString构建多行输出,代码结构清晰,易于维护。系统考虑了不同旅游类型、季节和用户体力水平,提供了更加个性化的行程规划。

JavaScript中间层实现

JavaScript作为浏览器的通用语言,在KMP项目中充当中间层的角色,负责将Kotlin编译的JavaScript代码进行包装和转换:

// ========================================
// 智能旅游行程规划系统 - JavaScript包装层
// ========================================

/**
 * 旅游数据验证和转换
 * @param {Object} travelData - 旅游数据对象
 * @returns {string} 验证后的输入字符串
 */
function validateTravelData(travelData) {
    const {
        userId,
        travelDays,
        budget,
        travelType,
        groupSize,
        departureMonth,
        fitnessLevel
    } = travelData;
    
    // 数据类型检查
    if (typeof userId !== 'string' || userId.trim() === '') {
        throw new Error('用户ID必须是非空字符串');
    }
    
    const numericFields = {
        travelDays,
        budget,
        travelType,
        groupSize,
        departureMonth,
        fitnessLevel
    };
    
    for (const [field, value] of Object.entries(numericFields)) {
        if (typeof value !== 'number' || value < 0) {
            throw new Error(`${field}必须是非负数字`);
        }
    }
    
    // 范围检查
    if (travelDays < 1 || travelDays > 30) {
        throw new Error('旅游天数必须在1-30之间');
    }
    
    if (travelType < 1 || travelType > 5) {
        throw new Error('旅游类型必须在1-5之间');
    }
    
    if (groupSize < 1 || groupSize > 20) {
        throw new Error('出行人数必须在1-20之间');
    }
    
    if (departureMonth < 1 || departureMonth > 12) {
        throw new Error('出发月份必须在1-12之间');
    }
    
    if (fitnessLevel < 1 || fitnessLevel > 5) {
        throw new Error('体力等级必须在1-5之间');
    }
    
    // 构建输入字符串
    return `${userId} ${travelDays} ${budget} ${travelType} ${groupSize} ${departureMonth} ${fitnessLevel}`;
}

/**
 * 调用Kotlin编译的旅游规划函数
 * @param {Object} travelData - 旅游数据
 * @returns {Promise<string>} 规划结果
 */
async function planTravel(travelData) {
    try {
        // 验证数据
        const inputString = validateTravelData(travelData);
        
        // 调用Kotlin函数(已编译为JavaScript)
        const result = window.hellokjs.smartTravelItineraryPlanningSystem(inputString);
        
        // 数据后处理
        const processedResult = postProcessTravelResult(result);
        
        return processedResult;
    } catch (error) {
        console.error('旅游规划错误:', error);
        return `❌ 规划失败: ${error.message}`;
    }
}

/**
 * 结果后处理和格式化
 * @param {string} result - 原始结果
 * @returns {string} 格式化后的结果
 */
function postProcessTravelResult(result) {
    // 添加时间戳
    const timestamp = new Date().toLocaleString('zh-CN');
    
    // 添加规划元数据
    const metadata = `\n\n[规划时间: ${timestamp}]\n[系统版本: 1.0]\n[数据来源: KMP OpenHarmony]`;
    
    return result + metadata;
}

/**
 * 生成旅游规划报告
 * @param {Object} travelData - 旅游数据
 * @returns {Promise<Object>} 报告对象
 */
async function generateTravelReport(travelData) {
    const planningResult = await planTravel(travelData);
    
    return {
        timestamp: new Date().toISOString(),
        userId: travelData.userId,
        planning: planningResult,
        recommendations: extractTravelRecommendations(planningResult),
        budget: calculateBudgetBreakdown(travelData),
        itinerary: generateDetailedItinerary(travelData)
    };
}

/**
 * 从规划结果中提取建议
 * @param {string} planningResult - 规划结果
 * @returns {Array<string>} 建议列表
 */
function extractTravelRecommendations(planningResult) {
    const recommendations = [];
    const lines = planningResult.split('\n');
    
    let inRecommendationSection = false;
    for (const line of lines) {
        if (line.includes('行程建议') || line.includes('安全提示')) {
            inRecommendationSection = true;
            continue;
        }
        
        if (inRecommendationSection && line.trim().startsWith('•')) {
            recommendations.push(line.trim().substring(1).trim());
        }
        
        if (inRecommendationSection && line.includes('━')) {
            break;
        }
    }
    
    return recommendations;
}

/**
 * 计算预算分配
 * @param {Object} travelData - 旅游数据
 * @returns {Object} 预算分配对象
 */
function calculateBudgetBreakdown(travelData) {
    const { budget, travelDays, groupSize } = travelData;
    
    const dailyBudget = Math.round(budget / travelDays);
    const perCapitaBudget = Math.round(budget / groupSize);
    
    return {
        totalBudget: budget,
        dailyBudget: dailyBudget,
        perCapitaBudget: perCapitaBudget,
        accommodation: Math.round(budget * 0.35),
        transport: Math.round(budget * 0.25),
        meals: Math.round(budget * 0.25),
        tickets: Math.round(budget * 0.15)
    };
}

/**
 * 生成详细行程
 * @param {Object} travelData - 旅游数据
 * @returns {Array<Object>} 每日行程数组
 */
function generateDetailedItinerary(travelData) {
    const { travelDays, fitnessLevel } = travelData;
    
    const dailyAttractions = [2, 3, 4, 5, 6][fitnessLevel - 1];
    const itinerary = [];
    
    for (let day = 1; day <= travelDays; day++) {
        itinerary.push({
            day: day,
            attractions: dailyAttractions,
            activities: generateDayActivities(day, travelDays),
            meals: ['早餐', '午餐', '晚餐'],
            accommodation: '待定'
        });
    }
    
    return itinerary;
}

/**
 * 生成每日活动
 * @param {number} day - 当前天数
 * @param {number} totalDays - 总天数
 * @returns {Array<string>} 活动列表
 */
function generateDayActivities(day, totalDays) {
    if (day === 1) {
        return ['抵达目的地', '办理入住', '周边探索'];
    } else if (day === totalDays) {
        return ['最后游览', '购物纪念品', '返程'];
    } else {
        return ['景点游览', '文化体验', '美食品尝'];
    }
}

// 导出函数供外部使用
export {
    validateTravelData,
    planTravel,
    generateTravelReport,
    extractTravelRecommendations,
    calculateBudgetBreakdown,
    generateDetailedItinerary
};

JavaScript层主要负责数据验证、格式转换和结果处理。通过validateTravelData函数确保输入数据的正确性,通过planTravel函数调用Kotlin编译的JavaScript代码,通过postProcessTravelResult函数对结果进行格式化处理。特别地,系统还提供了calculateBudgetBreakdowngenerateDetailedItinerary函数来详细计算预算分配和生成每日行程,帮助用户更好地规划旅行。这种分层设计使得系统更加灵活和可维护。

ArkTS前端实现

ArkTS是OpenHarmony的UI开发语言,基于TypeScript扩展,提供了强大的UI组件和状态管理能力:

// ========================================
// 智能旅游行程规划系统 - ArkTS前端实现
// ========================================

import { smartTravelItineraryPlanningSystem } from './hellokjs'

@Entry
@Component
struct TravelPlanningPage {
  @State userId: string = "USER001"
  @State travelDays: string = "7"
  @State budget: string = "10000"
  @State travelType: string = "2"
  @State groupSize: string = "2"
  @State departureMonth: string = "6"
  @State fitnessLevel: string = "3"
  @State result: string = ""
  @State isLoading: boolean = false

  build() {
    Column() {
      // ===== 顶部标题栏 =====
      Row() {
        Text("✈️ 旅游行程规划")
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
      }
      .width('100%')
      .height(50)
      .backgroundColor('#2196F3')
      .justifyContent(FlexAlign.Center)
      .padding({ left: 16, right: 16 })

      // ===== 主体内容区 - 左右结构 =====
      Row() {
        // ===== 左侧参数输入 =====
        Scroll() {
          Column() {
            Text("✈️ 旅游信息")
              .fontSize(14)
              .fontWeight(FontWeight.Bold)
              .fontColor('#2196F3')
              .margin({ bottom: 12 })

            // 用户ID
            Column() {
              Text("用户ID")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "USER001", text: this.userId })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.userId = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 旅游天数
            Column() {
              Text("旅游天数")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "1-30", text: this.travelDays })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.travelDays = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 预算
            Column() {
              Text("预算(元)")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "≥0", text: this.budget })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.budget = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 旅游类型
            Column() {
              Text("旅游类型(1-5)")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "1:海滨 2:山地 3:文化 4:城市 5:生态", text: this.travelType })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.travelType = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 出行人数
            Column() {
              Text("出行人数")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "1-20", text: this.groupSize })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.groupSize = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 出发月份
            Column() {
              Text("出发月份(1-12)")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "1-12", text: this.departureMonth })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.departureMonth = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 10 })

            // 体力等级
            Column() {
              Text("体力等级(1-5)")
                .fontSize(11)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 4 })
              TextInput({ placeholder: "1:轻松 5:极限", text: this.fitnessLevel })
                .height(32)
                .width('100%')
                .onChange((value: string) => { this.fitnessLevel = value })
                .backgroundColor('#FFFFFF')
                .border({ width: 1, color: '#64B5F6' })
                .borderRadius(4)
                .padding(6)
                .fontSize(10)
            }
            .margin({ bottom: 16 })

            // 按钮
            Row() {
              Button("开始规划")
                .width('48%')
                .height(40)
                .fontSize(14)
                .fontWeight(FontWeight.Bold)
                .backgroundColor('#2196F3')
                .fontColor(Color.White)
                .borderRadius(6)
                .onClick(() => {
                  this.executePlanning()
                })

              Blank().width('4%')

              Button("重置")
                .width('48%')
                .height(40)
                .fontSize(14)
                .fontWeight(FontWeight.Bold)
                .backgroundColor('#64B5F6')
                .fontColor(Color.White)
                .borderRadius(6)
                .onClick(() => {
                  this.resetForm()
                })
            }
            .width('100%')
            .justifyContent(FlexAlign.Center)
          }
          .width('100%')
          .padding(12)
        }
        .layoutWeight(1)
        .width('50%')
        .backgroundColor('#E3F2FD')

        // ===== 右侧结果显示 =====
        Column() {
          Text("✈️ 规划结果")
            .fontSize(14)
            .fontWeight(FontWeight.Bold)
            .fontColor('#2196F3')
            .margin({ bottom: 12 })
            .padding({ left: 12, right: 12, top: 12 })

          if (this.isLoading) {
            Column() {
              LoadingProgress()
                .width(50)
                .height(50)
                .color('#2196F3')
              Text("正在规划...")
                .fontSize(14)
                .fontColor('#757575')
                .margin({ top: 16 })
            }
            .width('100%')
            .layoutWeight(1)
            .justifyContent(FlexAlign.Center)
            .alignItems(HorizontalAlign.Center)
          } else if (this.result.length > 0) {
            Scroll() {
              Text(this.result)
                .fontSize(11)
                .fontColor('#212121')
                .fontFamily('monospace')
                .width('100%')
                .padding(12)
            }
            .layoutWeight(1)
            .width('100%')
          } else {
            Column() {
              Text("✈️")
                .fontSize(64)
                .opacity(0.2)
                .margin({ bottom: 16 })
              Text("暂无规划结果")
                .fontSize(14)
                .fontColor('#9E9E9E')
              Text("输入旅游信息后点击开始规划")
                .fontSize(12)
                .fontColor('#BDBDBD')
                .margin({ top: 8 })
            }
            .width('100%')
            .layoutWeight(1)
            .justifyContent(FlexAlign.Center)
            .alignItems(HorizontalAlign.Center)
          }
        }
        .layoutWeight(1)
        .width('50%')
        .padding(12)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#BBDEFB' })
      }
      .layoutWeight(1)
      .width('100%')
      .backgroundColor('#F5F5F5')
    }
    .width('100%')
    .height('100%')
  }

  private executePlanning() {
    const uid = this.userId.trim()
    const td = this.travelDays.trim()
    const b = this.budget.trim()
    const tt = this.travelType.trim()
    const gs = this.groupSize.trim()
    const dm = this.departureMonth.trim()
    const fl = this.fitnessLevel.trim()

    if (!uid || !td || !b || !tt || !gs || !dm || !fl) {
      this.result = "❌ 请填写所有数据"
      return
    }

    this.isLoading = true

    setTimeout(() => {
      try {
        const inputStr = `${uid} ${td} ${b} ${tt} ${gs} ${dm} ${fl}`
        const output = smartTravelItineraryPlanningSystem(inputStr)
        this.result = output
        console.log("[SmartTravelItineraryPlanningSystem] 执行完成")
      } catch (error) {
        this.result = `❌ 执行出错: ${error}`
        console.error("[SmartTravelItineraryPlanningSystem] 错误:", error)
      } finally {
        this.isLoading = false
      }
    }, 100)
  }

  private resetForm() {
    this.userId = "USER001"
    this.travelDays = "7"
    this.budget = "10000"
    this.travelType = "2"
    this.groupSize = "2"
    this.departureMonth = "6"
    this.fitnessLevel = "3"
    this.result = ""
  }
}

ArkTS前端代码实现了一个完整的用户界面,采用左右分栏布局。左侧是参数输入区域,用户可以输入旅游信息和偏好;右侧是结果显示区域,展示规划结果。通过@State装饰器管理组件状态,通过onClick事件处理用户交互。系统采用蓝色主题,象征旅游和探险,使界面更加专业和易用。

系统架构与工作流程

整个系统采用三层架构设计,实现了高效的跨平台协作:

  1. Kotlin后端层:负责核心业务逻辑处理,包括预算分配、目的地推荐、行程规划、景点排序等。通过@JsExport注解将函数导出为JavaScript可调用的接口。

  2. JavaScript中间层:负责数据转换和格式化,充当Kotlin和ArkTS之间的桥梁。进行数据验证、结果后处理、报告生成、详细行程生成等工作。

  3. ArkTS前端层:负责用户界面展示和交互,提供友好的输入界面和结果展示。通过异步调用Kotlin函数获取规划结果。

工作流程如下:

  • 用户在ArkTS界面输入旅游信息和偏好
  • ArkTS调用JavaScript验证函数进行数据验证
  • JavaScript调用Kotlin编译的JavaScript代码执行规划
  • Kotlin函数返回规划结果字符串
  • JavaScript进行结果后处理和格式化
  • ArkTS在界面上展示最终结果

核心算法与优化策略

智能目的地推荐

系统根据旅游类型、季节、预算等因素,智能推荐最适合的旅游目的地,确保用户选择最佳目的地。

预算智能分配

根据总预算,系统自动分配住宿、交通、餐饮、门票等各项成本,帮助用户合理规划支出。

行程强度评估

根据旅游天数、体力等级等因素,评估行程强度,推荐合适的景点数量和活动安排。

个性化建议生成

根据用户的旅游类型、季节、体力水平等因素,为用户生成个性化的行程建议、住宿推荐和安全提示。

实际应用案例

某游客使用本系统进行旅游规划,输入数据如下:

  • 旅游天数:7天
  • 预算:10000元
  • 旅游类型:2(山地探险)
  • 出行人数:2人
  • 出发月份:6月
  • 体力等级:3级

系统规划结果显示:

  • 推荐目的地:张家界、黄山、泰山
  • 日均预算:1428元
  • 人均预算:5000元
  • 住宿预算:3500元
  • 交通预算:2500元
  • 餐饮预算:2500元
  • 门票预算:1500元
  • 每日景点:4个
  • 行程强度:适中型

基于这些规划,游客采取了以下措施:

  1. 选择张家界作为主要目的地
  2. 预订3星级酒店,节省成本
  3. 使用公共交通和自驾结合
  4. 品尝当地特色美食
  5. 购买景区套票,获得优惠

旅行结束后,游客表示系统提供的规划非常实用,帮助他们在有限的预算内获得了最佳的旅游体验。

总结与展望

KMP OpenHarmony智能旅游行程规划系统通过整合Kotlin、JavaScript和ArkTS三种技术,提供了一个完整的跨平台旅游规划解决方案。系统不仅能够推荐最佳目的地,还能够智能分配预算、规划行程、推荐景点,为用户提供科学的旅游建议。

未来,该系统可以进一步扩展以下功能:

  1. 集成地图和导航功能,提供实时路线规划
  2. 引入机器学习算法,提高目的地推荐的准确度
  3. 支持实时天气预报和预警信息
  4. 集成酒店和机票预订功能
  5. 开发社交功能,分享旅游经验和攻略

通过持续的技术创新和功能完善,该系统将成为旅游爱好者的重要工具,帮助用户规划完美的旅行,享受美好的旅游体验。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐