爱简收旧衣按件回收前端代码仓库
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.

473 lines
11 KiB

1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
5 days ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
  1. <template>
  2. <view class="container">
  3. <!-- 顶部导航 -->
  4. <view class="nav-bar">
  5. <view class="back" @tap="goBack">
  6. <uni-icons type="left" size="20"></uni-icons>
  7. </view>
  8. <text class="title">我的订单</text>
  9. </view>
  10. <!-- 页面内容 -->
  11. <view class="content">
  12. <!-- <view class="page-header">
  13. <text class="page-title">我的订单</text>
  14. <text class="view-all" @tap="viewAll">查看全部 ></text>
  15. </view> -->
  16. <!-- 标签页 -->
  17. <view class="tabs">
  18. <view
  19. v-for="(tab, index) in tabs"
  20. :key="index"
  21. class="tab-item"
  22. :class="{ active: currentTab === index }"
  23. @tap="switchTab(index)"
  24. >
  25. <text>{{ tab.name }}</text>
  26. <text v-if="tab.count > 0" class="badge">{{ tab.count }}</text>
  27. </view>
  28. </view>
  29. <!-- 订单列表 -->
  30. <scroll-view
  31. scroll-y
  32. class="order-list"
  33. @scrolltolower="loadMore"
  34. >
  35. <view
  36. v-for="order in orderList"
  37. :key="order.id"
  38. class="order-card"
  39. @tap="goToDetail(order)"
  40. >
  41. <!-- 订单号 -->
  42. <view class="order-header">
  43. <text class="order-id">
  44. 订单编号
  45. <text class="order-ids">{{order.id }} </text>
  46. </text>
  47. </view>
  48. <!-- 订单内容 -->
  49. <view class="order-content">
  50. <image class="order-image" :src="order.image" mode="aspectFill"></image>
  51. <view class="order-arrow">
  52. <text class="iconfont"></text>
  53. </view>
  54. <view class="order-info">
  55. <text class="order-count">{{ order.count }} </text>
  56. <text class="order-price">¥ {{ order.priceRange }} /</text>
  57. <view class="order-estimate">
  58. <text>预估 ¥{{ order.estimatePrice }}</text>
  59. </view>
  60. </view>
  61. </view>
  62. <!-- 订单状态 -->
  63. <view class="order-status">
  64. <image class="status-icon" :src="order.statusIcon" mode="aspectFill"></image>
  65. <view class="status-info">
  66. <text class="status-text">{{ order.statusText }}</text>
  67. <text class="status-time">{{ order.statusTime }}</text>
  68. </view>
  69. </view>
  70. </view>
  71. </scroll-view>
  72. </view>
  73. </view>
  74. </template>
  75. <script>
  76. import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
  77. export default {
  78. mixins: [pullRefreshMixin],
  79. data() {
  80. return {
  81. tabs: [
  82. { name: '全部', count: 0 },
  83. { name: '进行中', count: 2 },
  84. { name: '已完成', count: 0 }
  85. ],
  86. currentTab: 0,
  87. // 所有订单数据
  88. allOrders: [
  89. {
  90. id: 'RE82738127861526',
  91. image: '/static/回收/衣物.png',
  92. count: 8,
  93. priceRange: '3-10',
  94. estimatePrice: '76-80',
  95. statusIcon: '/static/.png',
  96. statusText: '【已取件】快递员正在送至质检',
  97. statusTime: '周四 11:00~13:00',
  98. status: 'collected'
  99. },
  100. {
  101. id: 'RE82738127861525',
  102. image: '/static/回收/衣物.png',
  103. count: 8,
  104. priceRange: '3-10',
  105. estimatePrice: '76-80',
  106. statusIcon: '/static/my/【待取件】快递员正在赶来.png',
  107. statusText: '【待取件】快递员正在赶来',
  108. statusTime: '2025-04-20 11:00~13:00',
  109. status: 'processing'
  110. },{
  111. id: 'RE82738127861525',
  112. image: '/static/回收/衣物.png',
  113. count: 8,
  114. priceRange: '3-10',
  115. estimatePrice: '76-80',
  116. statusIcon: '/static/my/【质检中】质检员正在质检.png',
  117. statusText: '【质检中】质检员正在质检',
  118. statusTime: '2025-04-20 11:00~13:00',
  119. status: 'inspecting'
  120. },
  121. {
  122. id: 'RE82738127861524',
  123. image: '/static/回收/衣物.png',
  124. count: 8,
  125. priceRange: '3-10',
  126. estimatePrice: '76-80',
  127. statusText: '已取消',
  128. cancelled: true,
  129. status: 'cancelled'
  130. },
  131. {
  132. id: 'RE82738127861523',
  133. image: '/static/回收/衣物.png',
  134. count: 8,
  135. priceRange: '3-10',
  136. estimatePrice: '76-80',
  137. statusIcon: '/static/completed-icon.png',
  138. statusText: '【待结款】待平台确认结款项',
  139. statusTime: '2025-03-20 11:00',
  140. status: 'pending_payment'
  141. },
  142. {
  143. id: 'RE82738127861523',
  144. image: '/static/回收/衣物.png',
  145. count: 8,
  146. priceRange: '3-10',
  147. estimatePrice: '76-80',
  148. statusIcon: '/static/my/【已结款】平台已结款至账户.png',
  149. statusText: '【已结款】平台已结款至账户',
  150. statusTime: '2025-03-20 11:00',
  151. status: 'completed'
  152. }
  153. ],
  154. orderList: [], // 当前显示的订单列表
  155. loading: false,
  156. page: 1,
  157. pageSize: 10
  158. }
  159. },
  160. created() {
  161. this.initOrderData()
  162. },
  163. methods: {
  164. async onRefresh() {
  165. // 模拟刷新数据
  166. await new Promise(resolve => setTimeout(resolve, 1000))
  167. this.stopPullRefresh()
  168. },
  169. goBack() {
  170. uni.navigateBack()
  171. },
  172. showMore() {
  173. // 显示更多选项
  174. },
  175. onShare() {
  176. // 分享功能
  177. },
  178. viewAll() {
  179. this.switchTab(0) // 切换到全部标签
  180. },
  181. // 初始化订单数据和计数
  182. initOrderData() {
  183. // 计算各状态订单数量
  184. const processingOrders = this.allOrders.filter(order => order.status === 'processing')
  185. const completedOrders = this.allOrders.filter(order => order.status === 'completed')
  186. // 更新标签计数
  187. this.tabs[0].count = this.allOrders.length
  188. this.tabs[1].count = processingOrders.length
  189. this.tabs[2].count = completedOrders.length
  190. // 初始加载全部订单
  191. this.loadOrdersByTab(0)
  192. },
  193. // 切换标签
  194. switchTab(index) {
  195. if (this.currentTab === index) return
  196. this.currentTab = index
  197. this.page = 1 // 重置页码
  198. this.loadOrdersByTab(index)
  199. },
  200. // 根据标签加载对应订单
  201. loadOrdersByTab(tabIndex) {
  202. this.loading = true
  203. let filteredOrders = []
  204. switch(tabIndex) {
  205. case 0: // 全部
  206. filteredOrders = this.allOrders
  207. break
  208. case 1: // 进行中
  209. filteredOrders = this.allOrders.filter(order => order.status === 'processing'|| order.status === 'pending_payment')
  210. break
  211. case 2: // 已完成
  212. filteredOrders = this.allOrders.filter(order => order.status === 'completed')
  213. break
  214. }
  215. // 模拟分页
  216. const start = (this.page - 1) * this.pageSize
  217. const end = start + this.pageSize
  218. const pageOrders = filteredOrders.slice(start, end)
  219. if (this.page === 1) {
  220. this.orderList = pageOrders
  221. } else {
  222. this.orderList = [...this.orderList, ...pageOrders]
  223. }
  224. this.loading = false
  225. },
  226. // 加载更多
  227. loadMore() {
  228. if (this.loading) return
  229. this.page++
  230. this.loadOrdersByTab(this.currentTab)
  231. },
  232. goToDetail(order) {
  233. uni.navigateTo({
  234. url: `/pages/subcomponent/detail?id=${order.id}&status=${order.status}`
  235. })
  236. }
  237. }
  238. }
  239. </script>
  240. <style lang="scss" scoped>
  241. .container {
  242. min-height: 100vh;
  243. background: #f8f8f8;
  244. padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
  245. }
  246. .nav-bar {
  247. display: flex;
  248. align-items: center;
  249. height: calc(88rpx + var(--status-bar-height));
  250. padding: 0 32rpx;
  251. padding-top: var(--status-bar-height);
  252. background: #fff;
  253. position: fixed;
  254. top: 0;
  255. left: 0;
  256. right: 0;
  257. z-index: 999;
  258. box-sizing: border-box;
  259. .back {
  260. padding: 20rpx;
  261. margin-left: -20rpx;
  262. }
  263. .title {
  264. flex: 1;
  265. text-align: center;
  266. font-size: 34rpx;
  267. font-weight: 500;
  268. color: #222;
  269. }
  270. .right-btns {
  271. display: flex;
  272. align-items: center;
  273. gap: 32rpx;
  274. .more, .target {
  275. font-size: 40rpx;
  276. color: #333;
  277. }
  278. }
  279. }
  280. .content {
  281. padding: 30rpx;
  282. margin-top: calc(88rpx + var(--status-bar-height));
  283. min-height: calc(100vh - 88rpx - var(--status-bar-height));
  284. box-sizing: border-box;
  285. .page-header {
  286. display: flex;
  287. justify-content: space-between;
  288. align-items: center;
  289. margin-bottom: 30rpx;
  290. .page-title {
  291. font-size: 34rpx;
  292. font-weight: bold;
  293. }
  294. .view-all {
  295. font-size: 28rpx;
  296. color: #999;
  297. }
  298. }
  299. }
  300. .tabs {
  301. display: flex;
  302. background: #f5f5f5;
  303. border-radius: 8rpx;
  304. margin-bottom: 30rpx;
  305. .tab-item {
  306. flex: 1;
  307. height: 80rpx;
  308. display: flex;
  309. align-items: center;
  310. justify-content: center;
  311. font-size: 28rpx;
  312. color: #666;
  313. position: relative;
  314. &.active {
  315. color: #333;
  316. background-color: #e7e7e7;
  317. font-weight: 500;
  318. border-radius: 8rpx;
  319. }
  320. .badge {
  321. position: absolute;
  322. top: 10rpx;
  323. right: 10rpx;
  324. min-width: 32rpx;
  325. height: 32rpx;
  326. line-height: 32rpx;
  327. text-align: center;
  328. background: #ff4d4f;
  329. color: #fff;
  330. border-radius: 16rpx;
  331. font-size: 24rpx;
  332. padding: 0 6rpx;
  333. }
  334. }
  335. }
  336. .order-list {
  337. height: calc(100vh - 400rpx);
  338. }
  339. .order-card {
  340. background: #fff;
  341. border-radius: 16rpx;
  342. padding: 40rpx;
  343. margin-bottom: 20rpx;
  344. .order-header {
  345. margin-bottom: 20rpx;
  346. .order-id {
  347. font-size: 28rpx;
  348. color: #999;
  349. .order-ids{
  350. font-family: PingFang SC;
  351. font-weight: 600;
  352. font-size: 16px;
  353. line-height: 140%;
  354. letter-spacing: 0%;
  355. color: #333;
  356. }
  357. }
  358. }
  359. .order-content {
  360. display: flex;
  361. align-items: center;
  362. margin-bottom: 20rpx;
  363. flex-direction: row;
  364. justify-content: space-between;
  365. .order-image {
  366. width: 160rpx;
  367. height: 160rpx;
  368. border-radius: 8rpx;
  369. // background-color: #fff8ea;
  370. background: #fffbe6;
  371. padding: 20rpx;
  372. box-sizing: border-box;
  373. display: block;
  374. }
  375. .order-arrow {
  376. padding: 0 30rpx;
  377. color: #999;
  378. }
  379. .order-info {
  380. // flex: 1;
  381. display: flex;
  382. flex-direction: column;
  383. text-align: center;
  384. .order-count {
  385. font-size: 32rpx;
  386. font-weight: 500;
  387. margin-bottom: 10rpx;
  388. background-color: #fffaee;
  389. // display: block;
  390. }
  391. .order-price {
  392. font-size: 28rpx;
  393. color: #666;
  394. margin-bottom: 10rpx;
  395. background-color: #fffaee;
  396. // display: block;
  397. }
  398. .order-estimate {
  399. display: inline-block;
  400. background:#ffac07;
  401. color: #fff;
  402. font-size: 26rpx;
  403. padding: 8rpx 20rpx;
  404. border-radius: 20rpx;
  405. }
  406. }
  407. }
  408. .order-status {
  409. display: flex;
  410. align-items: center;
  411. padding: 20rpx;
  412. background: #f4f4f4;
  413. border-radius: 8rpx;
  414. .status-icon {
  415. width: 80rpx;
  416. height: 80rpx;
  417. margin-right: 20rpx;
  418. }
  419. .status-info {
  420. flex: 1;
  421. .status-text {
  422. font-size: 28rpx;
  423. color: #333;
  424. margin-bottom: 6rpx;
  425. display: block;
  426. }
  427. .status-time {
  428. font-size: 26rpx;
  429. color: #999;
  430. }
  431. }
  432. }
  433. }
  434. </style>