detail.uvue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. <template>
  2. <cl-page>
  3. <cl-sticky>
  4. <cl-topbar fixed safe-area-top :height="isMp() ? null : 100">
  5. <view class="flex flex-row items-center w-full pl-[72rpx] pr-3">
  6. <cl-avatar
  7. rounded
  8. :size="60"
  9. src="https://unix.cool-js.com/images/demo/avatar.jpg"
  10. ></cl-avatar>
  11. <cl-text :pt="{ className: 'mx-3' }">神仙都没用</cl-text>
  12. <cl-button
  13. text
  14. border
  15. size="small"
  16. rounded
  17. :pt="{ className: parseClass(['!px-3', [!isMp(), 'ml-auto']]) }"
  18. >立即关注</cl-button
  19. >
  20. </view>
  21. </cl-topbar>
  22. </cl-sticky>
  23. <view class="banner">
  24. <cl-banner
  25. height="1000rpx"
  26. :list="bannerList"
  27. :pt="{
  28. className: '!rounded-none',
  29. image: {
  30. className: '!rounded-none'
  31. }
  32. }"
  33. ></cl-banner>
  34. </view>
  35. <view class="bg-white dark:bg-surface-800 mb-3">
  36. <view
  37. class="p-4 border border-solid border-b-surface-200 dark:border-b-surface-600 border-t-0 border-l-0 border-r-0"
  38. >
  39. <cl-text bold :pt="{ className: 'mb-2 text-lg' }">❄️ 雪地旅行商务团价格表</cl-text>
  40. <cl-text :pt="{ className: 'mb-3' }">
  41. 对于不想做攻略的小伙伴来说定制团真的是最佳选择。雪地自驾没有经验的真心不建议。费用清晰明了。预算很准确,收费很合理。</cl-text
  42. >
  43. <view class="flex-row mb-4">
  44. <view
  45. class="flex-row items-center border border-solid border-surface-300 dark:border-surface-600 rounded-lg px-3 py-1 pl-2"
  46. >
  47. <cl-icon name="map-pin-2-line" :size="30"></cl-icon>
  48. <cl-text :pt="{ className: 'text-sm ml-1' }"
  49. >哈尔滨 · 圣 · 索菲亚教堂</cl-text
  50. >
  51. </view>
  52. </view>
  53. <cl-text :pt="{ className: 'text-sm' }" color="info">编辑于 2天前</cl-text>
  54. </view>
  55. <!-- 评论 -->
  56. <view class="p-4">
  57. <cl-text :pt="{ className: 'mb-4 text-sm' }">共 10 条评论</cl-text>
  58. <!-- 评论输入框 -->
  59. <view class="flex-row reply items-center mb-5" @tap="openReply()">
  60. <cl-avatar
  61. :size="68"
  62. rounded
  63. :pt="{ className: 'mr-2' }"
  64. src="https://unix.cool-js.com/images/demo/avatar.jpg"
  65. ></cl-avatar>
  66. <view
  67. class="h-[69rpx] flex-1 flex-row items-center bg-surface-100 dark:bg-surface-700 rounded-full px-4"
  68. >
  69. <cl-text color="info" :pt="{ className: 'text-sm flex-1' }"
  70. >说点什么...</cl-text
  71. >
  72. <cl-icon name="user-smile-line" :size="40"></cl-icon>
  73. <cl-icon
  74. name="image-circle-line"
  75. :pt="{ className: 'ml-2' }"
  76. :size="40"
  77. ></cl-icon>
  78. </view>
  79. </view>
  80. <view class="list">
  81. <view class="flex-row mb-6" v-for="item in commentList" :key="item.id">
  82. <cl-avatar :size="68" rounded :src="item.avatar"></cl-avatar>
  83. <view class="ml-3 flex-1">
  84. <!-- 评论者信息 -->
  85. <view class="flex-row items-center mb-1">
  86. <cl-text :pt="{ className: 'text-sm' }" color="info">{{
  87. item.name
  88. }}</cl-text>
  89. <cl-tag
  90. plain
  91. rounded
  92. :pt="{
  93. className: '!px-1 !py-[2rpx] ml-2',
  94. text: { className: '!text-xs' }
  95. }"
  96. v-if="item.isAuthor"
  97. >作者</cl-tag
  98. >
  99. </view>
  100. <!-- 评论内容 -->
  101. <cl-text :pt="{ className: 'mb-1' }">{{ item.content }}</cl-text>
  102. <view class="flex-row items-center">
  103. <!-- 评论时间 -->
  104. <cl-text :pt="{ className: 'text-sm' }" color="info">
  105. {{ item.time }}
  106. </cl-text>
  107. <cl-text
  108. color="info"
  109. :pt="{ className: 'text-sm ml-3' }"
  110. @tap="openReply()"
  111. >回复</cl-text
  112. >
  113. </view>
  114. <!-- 回复列表 -->
  115. <view class="flex-row mt-3" v-for="reply in item.reply" :key="reply.id">
  116. <cl-avatar :size="50" rounded :src="reply.avatar"> </cl-avatar>
  117. <view class="ml-3 flex-1">
  118. <view class="flex-row items-center mb-1">
  119. <cl-text :pt="{ className: 'text-sm' }" color="info">{{
  120. reply.name
  121. }}</cl-text>
  122. <cl-tag
  123. plain
  124. rounded
  125. :pt="{
  126. className: '!px-1 !py-[2rpx] ml-2',
  127. text: { className: '!text-xs' }
  128. }"
  129. v-if="reply.isAuthor"
  130. >作者</cl-tag
  131. >
  132. </view>
  133. <cl-text :pt="{ className: 'mb-1' }">{{
  134. reply.content
  135. }}</cl-text>
  136. <view class="flex-row items-center mb-1">
  137. <cl-text :pt="{ className: 'text-sm' }" color="info">
  138. {{ reply.time }}
  139. </cl-text>
  140. <cl-text
  141. color="info"
  142. :pt="{ className: 'text-sm ml-3' }"
  143. @tap="openReply()"
  144. >回复</cl-text
  145. >
  146. </view>
  147. <cl-text color="info" :pt="{ className: 'text-sm' }"
  148. >展开 1 条回复</cl-text
  149. >
  150. </view>
  151. </view>
  152. </view>
  153. </view>
  154. </view>
  155. </view>
  156. </view>
  157. <cl-footer>
  158. <view class="flex-row">
  159. <view
  160. class="flex-row items-center bg-surface-100 dark:bg-surface-700 rounded-full px-3 py-2 mr-6 w-[260rpx] h-[68rpx]"
  161. @tap="openReply"
  162. >
  163. <cl-icon name="edit-line" color="info" :size="32"></cl-icon>
  164. <cl-text color="info" :pt="{ className: 'text-sm ml-2' }">说点什么...</cl-text>
  165. </view>
  166. <view class="flex flex-row flex-1 justify-end">
  167. <view class="flex-row justify-center items-center mr-6">
  168. <cl-icon name="heart-line" :size="40"></cl-icon>
  169. <cl-text :pt="{ className: 'ml-2 text-sm' }">700</cl-text>
  170. </view>
  171. <view class="flex-row justify-center items-center">
  172. <cl-icon name="chat-3-line" :size="40"></cl-icon>
  173. <cl-text :pt="{ className: 'ml-2 text-sm' }">59</cl-text>
  174. </view>
  175. </view>
  176. </view>
  177. </cl-footer>
  178. <!-- 回复弹窗 -->
  179. <cl-popup v-model="replyVisible" direction="bottom" ref="replyPopupRef">
  180. <view class="p-4 pt-0">
  181. <view class="bg-surface-100 dark:bg-surface-800 rounded-2xl p-[8rpx] h-[168rpx]">
  182. <cl-textarea
  183. placeholder="说点什么..."
  184. :border="false"
  185. :pt="{
  186. className: parseClass(['!bg-transparent'])
  187. }"
  188. autofocus
  189. v-if="isApp() ? true : replyPopupRef?.isOpened == true"
  190. ></cl-textarea>
  191. </view>
  192. <view class="flex-row items-center mt-3 pl-2">
  193. <cl-icon
  194. name="image-circle-line"
  195. :pt="{ className: 'mr-4' }"
  196. :size="44"
  197. ></cl-icon>
  198. <cl-icon
  199. name="user-smile-line"
  200. :pt="{ className: 'mr-4' }"
  201. :size="44"
  202. ></cl-icon>
  203. <cl-button :pt="{ className: 'ml-auto !px-4' }" rounded>发送</cl-button>
  204. </view>
  205. </view>
  206. </cl-popup>
  207. </cl-page>
  208. </template>
  209. <script lang="ts" setup>
  210. import { isApp, isMp, parseClass } from "@/cool";
  211. import { ref } from "vue";
  212. const bannerList = ref<string[]>([
  213. "https://uni-docs.cool-js.com/demo/pages/demo/static/bg1.png",
  214. "https://uni-docs.cool-js.com/demo/pages/demo/static/bg2.png",
  215. "https://uni-docs.cool-js.com/demo/pages/demo/static/bg3.png"
  216. ]);
  217. type Comment = {
  218. id: number;
  219. avatar: string;
  220. name: string;
  221. content: string;
  222. time: string;
  223. isAuthor: boolean;
  224. order: number;
  225. reply: Comment[];
  226. };
  227. const commentList = ref<Comment[]>([
  228. {
  229. id: 1,
  230. avatar: "https://unix.cool-js.com/images/demo/avatar-1.jpg",
  231. name: "李明",
  232. content: "导游讲解很专业,风景绝美,是一次难忘的旅行体验!",
  233. time: "2024-06-20 10:15",
  234. isAuthor: false,
  235. order: 1,
  236. reply: []
  237. },
  238. {
  239. id: 2,
  240. avatar: "https://unix.cool-js.com/images/demo/avatar-2.jpg",
  241. name: "小芳",
  242. content: "酒店干净卫生,位置也很方便,强烈推荐给大家!",
  243. time: "2024-06-20 11:08",
  244. isAuthor: false,
  245. order: 2,
  246. reply: [
  247. {
  248. id: 201,
  249. avatar: "https://unix.cool-js.com/images/demo/avatar.jpg",
  250. name: "神仙都没用",
  251. content: "感谢您的推荐,欢迎再次光临哦~",
  252. time: "2024-06-20 12:00",
  253. isAuthor: true,
  254. order: 1,
  255. reply: []
  256. }
  257. ]
  258. },
  259. {
  260. id: 3,
  261. avatar: "https://unix.cool-js.com/images/demo/avatar-3.jpg",
  262. name: "王科",
  263. content: "行程安排合理,吃住都很满意,导游态度超级好。",
  264. time: "2024-06-19 09:22",
  265. isAuthor: false,
  266. order: 3,
  267. reply: []
  268. },
  269. {
  270. id: 4,
  271. avatar: "https://unix.cool-js.com/images/demo/avatar-4.jpg",
  272. name: "艳艳",
  273. content: "第一次带父母出游,家人都开心,下次还会选择这里~",
  274. time: "2024-06-18 15:40",
  275. isAuthor: false,
  276. order: 4,
  277. reply: []
  278. },
  279. {
  280. id: 5,
  281. avatar: "https://unix.cool-js.com/images/demo/avatar-5.jpg",
  282. name: "孙强",
  283. content: "车程舒适,时间安排紧凑但不赶,非常不错,非常棒!",
  284. time: "2024-06-17 17:05",
  285. isAuthor: false,
  286. order: 5,
  287. reply: [
  288. {
  289. id: 501,
  290. avatar: "https://unix.cool-js.com/images/demo/avatar.jpg",
  291. name: "神仙都没用",
  292. content: "您的好评就是我们最大的动力,谢谢支持~",
  293. time: "2024-06-17 17:45",
  294. isAuthor: true,
  295. order: 1,
  296. reply: []
  297. }
  298. ]
  299. },
  300. {
  301. id: 6,
  302. avatar: "https://unix.cool-js.com/images/demo/avatar-6.jpg",
  303. name: "导游小陈",
  304. content: "很高兴大家玩的开心,有问题随时联系我们。",
  305. time: "2024-06-17 18:20",
  306. isAuthor: false,
  307. order: 6,
  308. reply: []
  309. },
  310. {
  311. id: 7,
  312. avatar: "https://unix.cool-js.com/images/demo/avatar-7.jpg",
  313. name: "Grace",
  314. content: "风景如画,照片拍了一堆,朋友都夸赞说好美!",
  315. time: "2024-06-16 14:10",
  316. isAuthor: false,
  317. order: 7,
  318. reply: []
  319. },
  320. {
  321. id: 8,
  322. avatar: "https://unix.cool-js.com/images/demo/avatar-8.jpg",
  323. name: "阿伟",
  324. content: "活动内容丰富,小朋友特别喜欢,下次会再来~",
  325. time: "2024-06-15 19:28",
  326. isAuthor: false,
  327. order: 8,
  328. reply: []
  329. },
  330. {
  331. id: 9,
  332. avatar: "https://unix.cool-js.com/images/demo/avatar-9.jpg",
  333. name: "小虎",
  334. content: "天气晴朗,安排贴心,吃到了很多特色美食,值了!",
  335. time: "2024-06-14 13:52",
  336. isAuthor: false,
  337. order: 9,
  338. reply: []
  339. },
  340. {
  341. id: 10,
  342. avatar: "https://unix.cool-js.com/images/demo/avatar-10.jpg",
  343. name: "Julia",
  344. content: "贴心的讲解和服务,体验很棒,感谢本次旅行团队!",
  345. time: "2024-06-13 16:34",
  346. isAuthor: false,
  347. order: 10,
  348. reply: []
  349. }
  350. ]);
  351. const replyPopupRef = ref<ClPopupComponentPublicInstance | null>(null);
  352. const replyVisible = ref(false);
  353. function openReply() {
  354. replyVisible.value = true;
  355. }
  356. function closeReply() {
  357. replyVisible.value = false;
  358. }
  359. </script>
  360. <style lang="scss" scoped></style>