ai-plan.wxml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <!-- pages/ai-plan/ai-plan.wxml -->
  2. <view class="ai-plan-page" style="--primary-color:#e54d42">
  3. <!-- 顶部导航 -->
  4. <view class="nav-header">
  5. <text class="nav-title">AI红色旅游规划</text>
  6. </view>
  7. <!-- 进度指示器 -->
  8. <view class="progress-steps">
  9. <view class="step {{currentStep >= 1 ? 'active' : ''}}">
  10. <view class="step-number">1</view>
  11. <text class="step-text">偏好设置</text>
  12. </view>
  13. <view class="step-line {{currentStep >= 2 ? 'active' : ''}}"></view>
  14. <view class="step {{currentStep >= 2 ? 'active' : ''}}">
  15. <view class="step-number">2</view>
  16. <text class="step-text">行程生成</text>
  17. </view>
  18. <view class="step-line {{currentStep >= 3 ? 'active' : ''}}"></view>
  19. <view class="step {{currentStep >= 3 ? 'active' : ''}}">
  20. <view class="step-number">3</view>
  21. <text class="step-text">完成</text>
  22. </view>
  23. </view>
  24. <!-- 步骤1: 偏好设置 -->
  25. <block wx:if="{{currentStep === 1}}">
  26. <view class="step-container">
  27. <!-- 城市选择 -->
  28. <view class="form-section">
  29. <text class="section-title">选择城市</text>
  30. <view class="city-selector">
  31. <view
  32. wx:for="{{cityOptions}}"
  33. wx:key="value"
  34. class="city-option {{selectedCity === item.value ? 'selected' : ''}}"
  35. data-value="{{item.value}}"
  36. bindtap="toggleCity"
  37. >
  38. {{item.label}}
  39. </view>
  40. </view>
  41. </view>
  42. <!-- 天数选择 -->
  43. <view class="form-section">
  44. <text class="section-title">旅行天数</text>
  45. <view class="day-selector">
  46. <view
  47. wx:for="{{dayOptions}}"
  48. wx:key="value"
  49. class="day-option {{selectedDays === item.value ? 'selected' : ''}}"
  50. bindtap="selectDays"
  51. data-value="{{item.value}}"
  52. >
  53. {{item.label}}
  54. </view>
  55. </view>
  56. </view>
  57. <!-- 兴趣偏好 -->
  58. <view class="form-section">
  59. <view class="day-selector">
  60. <view
  61. wx:for="{{interestOptions}}"
  62. wx:key="value"
  63. class="day-option {{selectedInterests.includes(item.value) ? 'selected' : ''}}"
  64. bindtap="toggleInterest"
  65. data-value="{{item.value}}"
  66. >
  67. </view>
  68. </view>
  69. </view>
  70. <!-- 出行方式 -->
  71. <view class="form-section">
  72. <text class="section-title">出行方式</text>
  73. <view class="transport-options">
  74. <view
  75. wx:for="{{transportOptions}}"
  76. wx:key="value"
  77. class="transport-option {{selectedTransport === item.value ? 'selected' : ''}}"
  78. bindtap="selectTransport"
  79. data-value="{{item.value}}"
  80. >
  81. <text>{{item.label}}</text>
  82. </view>
  83. </view>
  84. </view>
  85. <!-- 特殊需求 -->
  86. <view class="form-section">
  87. <text class="section-title">特殊需求</text>
  88. <textarea
  89. class="custom-input"
  90. placeholder="如:需要轮椅通道、希望包含党史讲解等"
  91. value="{{customRequirements}}"
  92. bindinput="updateCustomRequirements"
  93. ></textarea>
  94. </view>
  95. <button class="next-btn" bindtap="goToNextStep">下一步</button>
  96. </view>
  97. </block>
  98. <!-- 步骤2: 行程生成 -->
  99. <block wx:if="{{currentStep === 2}}">
  100. <view class="step-container">
  101. <!-- 加载状态 -->
  102. <view wx:if="{{!planGenerated || isLoading}}" class="generating-container">
  103. <image src="/images/red-loading.png" class="loading-gif" mode="aspectFit"></image>
  104. <text class="generating-text">AI正在为您规划红色教育路线...</text>
  105. <text class="generating-tip">正在筛选革命教育基地和党史学习点</text>
  106. </view>
  107. <!-- 行程结果 -->
  108. <view wx:else class="plan-result">
  109. <!-- 地图总览 -->
  110. <view class="map-section" wx:if="{{mapData.showMap}}">
  111. <view class="section-header">
  112. <image src="/images/icons/map-red.png" class="section-icon"></image>
  113. <text class="section-title">行程地图总览</text>
  114. </view>
  115. <!-- 天数切换标签 -->
  116. <scroll-view scroll-x class="day-tabs">
  117. <view
  118. class="day-tab {{currentMapDay === -1 ? 'active' : ''}}"
  119. bindtap="resetToAllAttractions"
  120. >
  121. 全部
  122. </view>
  123. <view
  124. wx:for="{{planData.days}}"
  125. wx:key="day"
  126. class="day-tab {{currentMapDay === index ? 'active' : ''}}"
  127. bindtap="switchMapDay"
  128. data-day="{{index}}"
  129. style="border-color: {{mapData.dayColors[index]}}; color: {{currentMapDay === index ? '#fff' : mapData.dayColors[index]}}; background-color: {{currentMapDay === index ? mapData.dayColors[index] : 'transparent'}}"
  130. >
  131. 第{{item.day}}天
  132. </view>
  133. </scroll-view>
  134. <!-- 地图容器 -->
  135. <view class="map-container">
  136. <map
  137. id="routeMap"
  138. longitude="{{mapData.longitude}}"
  139. latitude="{{mapData.latitude}}"
  140. scale="{{mapData.scale}}"
  141. markers="{{mapData.markers}}"
  142. polyline="{{mapData.polyline}}"
  143. include-points="{{mapData.includePoints}}"
  144. style="width: 100%; height: 400px;"
  145. bindmarkertap="handleMarkerTap"
  146. bindregionchange="handleRegionChange"
  147. show-location
  148. >
  149. <!-- 地图控制按钮 -->
  150. <cover-view class="map-controls">
  151. <cover-button class="control-btn" bindtap="handleZoomIn">
  152. <image src="/images/icons/zoom-in.png" class="control-icon"></image>
  153. </cover-button>
  154. <cover-button class="control-btn" bindtap="handleZoomOut">
  155. <image src="/images/icons/zoom-out.png" class="control-icon"></image>
  156. </cover-button>
  157. <cover-button class="control-btn" bindtap="resetToAllAttractions">
  158. <image src="/images/icons/location.png" class="control-icon"></image>
  159. </cover-button>
  160. </cover-view>
  161. <!-- 路线图例 -->
  162. <cover-view class="map-legend">
  163. <cover-view wx:for="{{planData.days}}" wx:key="day" class="legend-item">
  164. <cover-view class="legend-color" style="background:{{mapData.dayColors[index]}}"></cover-view>
  165. <cover-text>第{{item.day}}天</cover-text>
  166. </cover-view>
  167. </cover-view>
  168. </map>
  169. </view>
  170. <!-- 地图图例 -->
  171. <view class="map-legend">
  172. <view class="legend-item">
  173. <image src="/images/marker-red-star.png" class="legend-icon"></image>
  174. <text>红色教育基地</text>
  175. </view>
  176. <view class="legend-item">
  177. <image src="/images/map-line-sample.png" class="legend-icon"></image>
  178. <text>行程路线</text>
  179. </view>
  180. </view>
  181. </view>
  182. <!-- 在地图总览下方添加路线规划展示 -->
  183. <view class="route-plan-section" wx:if="{{planGenerated && mapData.showMap}}">
  184. <view class="section-header">
  185. <image src="/images/icons/route-red.png" class="section-icon"></image>
  186. <text class="section-title">AI规划路线详情</text>
  187. </view>
  188. <view class="day-routes">
  189. <view wx:for="{{planData.days}}" wx:key="day" class="day-route">
  190. <view class="route-header">
  191. <view class="route-day-tag" style="background-color: {{['#e54d42','#f37b1d','#1cbbb4','#0081ff','#6739b6','#9c26b0','#e03997'][index%7]}}">
  192. 第{{item.day}}天
  193. </view>
  194. <text class="route-theme">{{item.theme}}</text>
  195. </view>
  196. <view class="route-steps">
  197. <view wx:for="{{item.attractions}}" wx:key="id" class="route-step">
  198. <view class="step-marker" style="background-color: {{['#e54d42','#f37b1d','#1cbbb4','#0081ff','#6739b6','#9c26b0','#e03997'][index%7]}}">
  199. {{index+1}}
  200. </view>
  201. <view class="step-content">
  202. <text class="step-title">{{item.name}}</text>
  203. <view class="step-info">
  204. <text class="step-time">{{item.visit_time}}</text>
  205. <text class="step-duration">{{item.duration}}分钟</text>
  206. </view>
  207. <text class="step-address">{{item.address}}</text>
  208. </view>
  209. </view>
  210. </view>
  211. <view class="route-summary">
  212. <image src="/images/icons/summary-red.png" class="summary-icon"></image>
  213. <text class="summary-text">{{item.summary}}</text>
  214. </view>
  215. </view>
  216. </view>
  217. </view>
  218. <!-- 操作按钮 -->
  219. <view class="action-buttons">
  220. <button class="save-btn" bindtap="savePlan">
  221. <image src="/images/icons/save-red.png" class="btn-icon"></image>
  222. 保存行程
  223. </button>
  224. <button class="regenerate-btn" bindtap="regeneratePlan">
  225. <image src="/images/icons/refresh-red.png" class="btn-icon"></image>
  226. 重新规划
  227. </button>
  228. <button class="share-btn" bindtap="sharePlan">
  229. <image src="/images/icons/share-red.png" class="btn-icon"></image>
  230. 分享行程
  231. </button>
  232. </view>
  233. </view>
  234. </view>
  235. </block>
  236. <!-- 步骤3: 完成 -->
  237. <block wx:if="{{currentStep === 3}}">
  238. <view class="step-container success-container">
  239. <image src="/images/success-red.png" class="success-icon"></image>
  240. <text class="success-title">行程保存成功</text>
  241. <text class="success-subtitle">您的红色教育行程已保存</text>
  242. <view class="success-actions">
  243. <button class="view-plan-btn" bindtap="viewPlan">查看完整行程</button>
  244. <button class="share-plan-btn" bindtap="sharePlan">分享行程</button>
  245. </view>
  246. </view>
  247. </block>
  248. </view>
  249. <!-- 景点弹窗 -->
  250. <view class="attraction-modal" wx:if="{{showAttractionDetail}}">
  251. <!-- 纯色遮罩层 -->
  252. <view class="modal-mask" bindtap="closeAttractionDetail"></view>
  253. <!-- 弹窗内容容器 -->
  254. <view class="modal-container">
  255. <!-- 顶部图片展示 -->
  256. <view class="image-container">
  257. <!-- 景点图片展示 -->
  258. <image
  259. src="{{currentAttraction.image}}"
  260. mode="aspectFill"
  261. class="attraction-image"
  262. binderror="handleImageError"
  263. bindload="handleImageLoad"
  264. data-id="{{currentAttraction.id}}"
  265. data-name="{{currentAttraction.name}}"
  266. data-city="{{selectedCity}}"
  267. />
  268. <!-- 关闭按钮 -->
  269. <view class="close-btn" bindtap="closeAttractionDetail">
  270. <image src="/images/icons/close-circle.png" class="close-icon"></image>
  271. </view>
  272. </view>
  273. <!-- 可滚动内容区域 -->
  274. <scroll-view scroll-y class="modal-body">
  275. <!-- 景点标题和标签 -->
  276. <view class="attraction-header">
  277. <text class="attraction-title">{{currentAttraction.name}}</text>
  278. <view class="attraction-tags">
  279. <text class="tag time-tag">
  280. <image src="/images/icons/clock.png" class="tag-icon"></image>
  281. 开放时间:{{currentAttraction.open_hours || '09:00-17:00'}}
  282. </text>
  283. </view>
  284. </view>
  285. <!-- 景点简介 -->
  286. <view class="section">
  287. <view class="section-header">
  288. <image src="/images/icons/summary-red.png" class="section-icon"></image>
  289. <text class="section-title">景点简介</text>
  290. </view>
  291. <text class="section-content">{{currentAttraction.description || '暂无简介'}}</text>
  292. </view>
  293. <!-- 历史意义 -->
  294. <view class="section" wx:if="{{currentAttraction.is_red_tourism && currentAttraction.history_significance}}">
  295. <view class="section-header">
  296. <image src="/images/icons/history.png" class="section-icon"></image>
  297. <text class="section-title">历史意义</text>
  298. </view>
  299. <text class="section-content">{{currentAttraction.history_significance}}</text>
  300. </view>
  301. <!-- 实用信息 -->
  302. <view class="info-grid">
  303. <view class="info-item">
  304. <image src="/images/icons/location.png" class="info-icon"></image>
  305. <text class="info-text">{{currentAttraction.address || '地址信息待补充'}}</text>
  306. </view>
  307. <view class="info-item">
  308. <image src="/images/icons/ticket-small.png" class="info-icon"></image>
  309. <text class="info-text">{{currentAttraction.ticket_info || '凭身份证免费参观'}}</text>
  310. </view>
  311. </view>
  312. <!-- 参观须知 -->
  313. <view class="section">
  314. <view class="section-header">
  315. <image src="/images/icons/notice.png" class="section-icon"></image>
  316. <text class="section-title">参观须知</text>
  317. </view>
  318. <view class="notice-list">
  319. <view class="notice-item" wx:for="{{currentAttraction.visiting_etiquette || DEFAULT_ETIQUETTE}}" wx:key="*this">
  320. <image src="/images/icons/dot-red.png" class="notice-icon"></image>
  321. <text>{{item}}</text>
  322. </view>
  323. </view>
  324. </view>
  325. </scroll-view>
  326. <!-- 底部操作栏 -->
  327. <view class="modal-footer">
  328. <button class="navigate-btn" bindtap="navigateToAttraction">
  329. <image src="/images/map-arrow.png" class="btn-icon"></image>
  330. 导航前往
  331. </button>
  332. </view>
  333. </view>
  334. </view>