猫妈狗爸伴宠师小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

443 lines
10 KiB

  1. <template>
  2. <up-list @scrolltolower="scrolltolower">
  3. <template v-for="(item, index) in orderList" :key="index">
  4. <view class="date-label">
  5. <view class="date-box">{{ item.date }}</view>
  6. <view class="order-tag">
  7. <template v-if="item.orders[0].status === 'completed'">已完成{{ item.orders.length }}</template>
  8. <template v-else>待上门{{ item.orders.length }}</template>
  9. </view>
  10. </view>
  11. <view class="timeline-container">
  12. <view class="timeline-line" :class="{'timeline-line-completed': item.orders[0].status === 'completed'}">
  13. </view>
  14. <up-list-item v-for="(order, orderIndex) in item.orders" :key="orderIndex">
  15. <view class="timeline-item" :class="{'item-completed': order.status === 'completed'}">
  16. <view class="timeline-dot"></view>
  17. <view class="mb28 container-list-item">
  18. <view class="order-time-tag"
  19. :class="{'order-time-tag-completed' : order.status === 'completed'}">
  20. <!-- <view class="time-box">{{ order.time }}</view> -->
  21. <view class="order-status">
  22. <view class="status-icon"></view>
  23. <view>
  24. <!-- {{ order.count }}
  25. {{ order.count }} -->
  26. <template v-if="order.status === 'completed'">已完成</template>
  27. <template v-else>待上门</template>
  28. </view>
  29. </view>
  30. </view>
  31. <view class="container-list">
  32. <view class="flex-between flex">
  33. <view class="address-info flex">
  34. <view class="address-icon"></view>
  35. <view class="address-text">{{ order.address }}</view>
  36. </view>
  37. <view class="expand-btn" @click="toggleExpand(index, orderIndex)">
  38. {{ order.isExpanded ? '收起' : '展开' }} <text
  39. class="expand-icon">{{ order.isExpanded ? '∧' : '∨' }}</text>
  40. </view>
  41. </view>
  42. <view v-if="order.isExpanded" class="pet-info">
  43. <view class="pet-title">陪伴对象</view>
  44. <view class="pet-list">
  45. <view v-for="(pet, petIndex) in order.pets" :key="petIndex" class="pet-item">
  46. <view class="pet-avatar">
  47. <up-image width="70px" height="70px" :src="pet.avatar"
  48. shape="circle"></up-image>
  49. </view>
  50. <view class="pet-detail">
  51. <view class="pet-name">{{ pet.name }} <text
  52. class="pet-tag" :class="{'pet-tag-female': pet.gender === 'female', 'pet-tag-male': pet.gender === 'male'}">{{ pet.gender === 'female' ? '♀' : '♂' }}</text></view>
  53. <view class="pet-desc">{{ pet.desc }}</view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="address-detail mb28">{{ order.fullAddress }}</view>
  58. <view class="action-buttons flex flex-between">
  59. <up-button type="primary" text="打卡" v-if="false" @click="toClock" shape="circle"
  60. class="mr20" color="var(--status-color)"></up-button>
  61. <up-button type="primary" text="查看订单详情" @click="toDetail" shape="circle"
  62. class="mr20" color="var(--status-color)"></up-button>
  63. <up-button type="primary" text="查看宠物档案" @click="toPet" shape="circle"
  64. class="mr20" color="var(--status-color)"></up-button>
  65. <up-button type="primary" text="服务档案" @click="toService" shape="circle"
  66. color="var(--status-color)"></up-button>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. </view>
  72. </up-list-item>
  73. </view>
  74. </template>
  75. </up-list>
  76. </template>
  77. <script setup>
  78. import {
  79. ref,
  80. reactive,
  81. } from 'vue';
  82. const {
  83. list
  84. } = defineProps({
  85. list: {
  86. type: Array,
  87. required: true
  88. },
  89. });
  90. // 模拟订单数据
  91. const orderList = reactive([{
  92. date: '12-04',
  93. orders: [{
  94. time: '12-04',
  95. count: 2,
  96. status: 'completed', // 已完成状态
  97. address: '湖南省长沙市雨花区人民东路',
  98. fullAddress: '湖南省长沙市雨花区人民东路88号',
  99. isExpanded: true,
  100. pets: [{
  101. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  102. name: '小咪',
  103. gender: 'female',
  104. desc: '中华田园犬(小型犬) | 专业喂养+提前熟悉+陪玩'
  105. },
  106. {
  107. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  108. name: 'Billion',
  109. gender: 'male',
  110. desc: '狗狗(小型狗) | 上门喂养+陪玩'
  111. }
  112. ]
  113. },
  114. {
  115. time: '12-04',
  116. count: 2,
  117. status: 'completed', // 已完成状态
  118. address: '湖南省长沙市雨花区人民东路',
  119. fullAddress: '湖南省长沙市雨花区人民东路88号',
  120. isExpanded: true,
  121. pets: [{
  122. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  123. name: '小咪',
  124. gender: 'female',
  125. desc: '中华田园犬(小型犬) | 专业喂养+提前熟悉+陪玩'
  126. },
  127. {
  128. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  129. name: 'Billion',
  130. gender: 'male',
  131. desc: '狗狗(小型狗) | 上门喂养+陪玩'
  132. }
  133. ]
  134. }]
  135. },
  136. {
  137. date: '12-05',
  138. orders: [{
  139. time: '12-05',
  140. count: 1,
  141. status: 'completed', // 已完成状态
  142. address: '湖南省长沙市雨花区人民东路',
  143. fullAddress: '湖南省长沙市雨花区人民东路88号',
  144. isExpanded: false,
  145. pets: [{
  146. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  147. name: '小黑',
  148. gender: 'male',
  149. desc: '中华田园犬(小型犬) | 专业喂养+提前熟悉+陪玩'
  150. }]
  151. }]
  152. },
  153. {
  154. date: '12-08',
  155. orders: [{
  156. time: '12-08',
  157. count: 1,
  158. status: 'pending', // 待上门状态
  159. address: '湖南省长沙市雨花区人民东路',
  160. fullAddress: '湖南省长沙市雨花区人民东路88号',
  161. isExpanded: false,
  162. pets: [{
  163. avatar: 'https://cdn.catmdogd.com/Work/image/work/tx.png',
  164. name: '小白',
  165. gender: 'female',
  166. desc: '中华田园猫 | 专业喂养+提前熟悉+陪玩'
  167. }]
  168. }]
  169. }
  170. ]);
  171. // 展开/收起订单详情
  172. function toggleExpand(dateIndex, orderIndex) {
  173. orderList[dateIndex].orders[orderIndex].isExpanded = !orderList[dateIndex].orders[orderIndex].isExpanded;
  174. }
  175. // 滚动到底部加载更多
  176. const scrolltolower = () => {
  177. // 实际项目中这里应该调用API加载更多数据
  178. console.log('加载更多数据');
  179. }
  180. // 页面跳转函数
  181. function toClock() {
  182. uni.navigateTo({
  183. url: "/otherPages/myOrdersManage/clock/index"
  184. })
  185. }
  186. function toDetail() {
  187. uni.navigateTo({
  188. url: "/otherPages/orderTakingManage/detail/index"
  189. })
  190. }
  191. function toPet() {
  192. uni.navigateTo({
  193. url: "/otherPages/orderTakingManage/pet/index"
  194. })
  195. }
  196. function toService() {
  197. uni.navigateTo({
  198. url: "/otherPages/myOrdersManage/service/index"
  199. })
  200. }
  201. </script>
  202. <style scoped lang="scss">
  203. @import "../index";
  204. .date-label {
  205. display: flex;
  206. align-items: center;
  207. margin: 20rpx 0;
  208. position: relative;
  209. z-index: 3;
  210. .date-box {
  211. background: #333333;
  212. color: #FFFFFF;
  213. padding: 8rpx 16rpx;
  214. border-radius: 8rpx;
  215. font-size: 24rpx;
  216. margin-right: 20rpx;
  217. }
  218. .order-tag {
  219. color: #7D8196;
  220. font-size: 24rpx;
  221. }
  222. }
  223. .order-time-tag {
  224. display: flex;
  225. align-items: center;
  226. background: rgba(#FFAA48, 0.2);
  227. padding: 22rpx 42rpx;
  228. .time-box {
  229. background: var(--status-color);
  230. color: #FFFFFF;
  231. padding: 4rpx 12rpx;
  232. border-radius: 8rpx;
  233. font-size: 24rpx;
  234. margin-right: 20rpx;
  235. }
  236. .order-status {
  237. display: flex;
  238. align-items: center;
  239. font-size: 24rpx;
  240. .status-icon {
  241. width: 24rpx;
  242. height: 24rpx;
  243. background: var(--status-color);
  244. border-radius: 50%;
  245. margin-right: 10rpx;
  246. }
  247. .status-icon-completed {
  248. background: #4CD964;
  249. }
  250. }
  251. }
  252. .order-time-tag-completed {
  253. background: rgba(#4CD964, 0.2);
  254. }
  255. .time-box-completed {
  256. background: #4CD964;
  257. }
  258. .address-info {
  259. display: flex;
  260. align-items: center;
  261. margin: 20rpx 0;
  262. .address-icon {
  263. width: 36rpx;
  264. height: 36rpx;
  265. background: var(--status-color);
  266. border-radius: 50%;
  267. margin-right: 12rpx;
  268. }
  269. .address-icon-completed {
  270. background: #4CD964;
  271. }
  272. .address-text {
  273. font-size: 28rpx;
  274. color: #333333;
  275. font-weight: 500;
  276. }
  277. }
  278. .expand-btn {
  279. font-size: 26rpx;
  280. color: #FFAA48;
  281. font-weight: 500;
  282. .expand-icon {
  283. margin-left: 8rpx;
  284. }
  285. }
  286. .expand-btn-completed {
  287. color: #4CD964;
  288. }
  289. .pet-info {
  290. margin-top: 20rpx;
  291. .pet-title {
  292. font-size: 28rpx;
  293. color: #333333;
  294. margin-bottom: 16rpx;
  295. }
  296. .pet-list {
  297. .pet-item {
  298. display: flex;
  299. margin-bottom: 20rpx;
  300. .pet-avatar {
  301. margin-right: 20rpx;
  302. flex-shrink: 0;
  303. }
  304. .pet-detail {
  305. .pet-name {
  306. font-size: 28rpx;
  307. color: #333333;
  308. margin-bottom: 10rpx;
  309. .pet-tag {
  310. background: var(--status-color);
  311. color: #FFFFFF;
  312. padding: 2rpx 10rpx;
  313. border-radius: 20rpx;
  314. font-size: 20rpx;
  315. margin-left: 10rpx;
  316. }
  317. .pet-tag-female {
  318. background: #FF6B9A;
  319. }
  320. .pet-tag-male {
  321. background: #4A90E2;
  322. }
  323. }
  324. .pet-desc {
  325. font-size: 24rpx;
  326. color: #7D8196;
  327. }
  328. }
  329. }
  330. }
  331. }
  332. .address-detail {
  333. background: #F6FAFC;
  334. border-radius: 8rpx;
  335. padding: 14rpx 20rpx;
  336. font-size: 24rpx;
  337. color: #7D8196;
  338. margin: 20rpx 0;
  339. }
  340. .action-buttons {
  341. display: flex;
  342. justify-content: space-between;
  343. margin-top: 20rpx;
  344. }
  345. /* 时间线样式 */
  346. .timeline-container {
  347. position: relative;
  348. padding-left: 40rpx;
  349. margin-bottom: 30rpx;
  350. z-index: 1;
  351. }
  352. .timeline-line {
  353. position: absolute;
  354. left: 20rpx;
  355. top: 0;
  356. height: 100%;
  357. width: 2rpx;
  358. background-color: #FFAA48;
  359. z-index: 0;
  360. }
  361. .timeline-line-completed {
  362. background-color: #4CD964;
  363. }
  364. .timeline-item {
  365. position: relative;
  366. padding-left: 30rpx;
  367. margin-bottom: 20rpx;
  368. }
  369. .timeline-dot {
  370. position: absolute;
  371. left: -10rpx;
  372. top: 30rpx;
  373. width: 20rpx;
  374. height: 20rpx;
  375. border-radius: 50%;
  376. background-color: #FFAA48;
  377. z-index: 2;
  378. border: 4rpx solid #FFF;
  379. }
  380. .timeline-dot-completed {
  381. background-color: #4CD964;
  382. }
  383. /* 默认状态颜色变量 */
  384. .timeline-item {
  385. --status-color: #FFAA48;
  386. }
  387. /* 添加状态类,集中控制样式 */
  388. .item-completed {
  389. --status-color: #4CD964;
  390. }
  391. </style>