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

487 lines
11 KiB

1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
6 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 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. uni.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. background: #f8f8f8;
  243. padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
  244. overflow: hidden;
  245. height: 100vh;
  246. }
  247. .nav-bar {
  248. display: flex;
  249. align-items: center;
  250. height: calc(150rpx + var(--status-bar-height));
  251. padding: 0 32rpx;
  252. padding-top: var(--status-bar-height);
  253. background: #fff;
  254. position: fixed;
  255. top: 0;
  256. left: 0;
  257. right: 0;
  258. z-index: 999;
  259. box-sizing: border-box;
  260. .back {
  261. padding: 20rpx;
  262. margin-left: -20rpx;
  263. }
  264. .title {
  265. flex: 1;
  266. text-align: center;
  267. font-size: 34rpx;
  268. font-weight: 500;
  269. color: #222;
  270. }
  271. .right-btns {
  272. display: flex;
  273. align-items: center;
  274. gap: 32rpx;
  275. .more, .target {
  276. font-size: 40rpx;
  277. color: #333;
  278. }
  279. }
  280. }
  281. .content {
  282. padding: 30rpx 0 0 0;
  283. margin-top: calc(150rpx + var(--status-bar-height) + 80rpx);
  284. height: 100%;
  285. display: flex;
  286. flex-direction: column;
  287. overflow: hidden;
  288. box-sizing: border-box;
  289. .page-header {
  290. display: flex;
  291. justify-content: space-between;
  292. align-items: center;
  293. margin-bottom: 30rpx;
  294. .page-title {
  295. font-size: 34rpx;
  296. font-weight: bold;
  297. }
  298. .view-all {
  299. font-size: 28rpx;
  300. color: #999;
  301. }
  302. }
  303. }
  304. .tabs {
  305. display: flex;
  306. background: #f5f5f5;
  307. border-radius: 8rpx;
  308. margin-bottom: 30rpx;
  309. position: fixed;
  310. top: calc(150rpx + var(--status-bar-height));
  311. left: 0;
  312. width: 100%;
  313. z-index: 998;
  314. box-sizing: border-box;
  315. .tab-item {
  316. flex: 1;
  317. height: 80rpx;
  318. display: flex;
  319. align-items: center;
  320. justify-content: center;
  321. font-size: 28rpx;
  322. color: #666;
  323. position: relative;
  324. &.active {
  325. color: #333;
  326. background-color: #e7e7e7;
  327. font-weight: 500;
  328. border-radius: 8rpx;
  329. }
  330. .badge {
  331. position: absolute;
  332. top: 10rpx;
  333. right: 10rpx;
  334. min-width: 32rpx;
  335. height: 32rpx;
  336. line-height: 32rpx;
  337. text-align: center;
  338. background: #ff4d4f;
  339. color: #fff;
  340. border-radius: 16rpx;
  341. font-size: 24rpx;
  342. padding: 0 6rpx;
  343. }
  344. }
  345. }
  346. .order-list {
  347. flex: 1;
  348. min-height: 0;
  349. overflow-y: scroll;
  350. padding-bottom: env(safe-area-inset-bottom);
  351. box-sizing: border-box;
  352. }
  353. .order-card {
  354. background: #fff;
  355. border-radius: 16rpx;
  356. padding: 40rpx;
  357. margin-bottom: 20rpx;
  358. .order-header {
  359. margin-bottom: 20rpx;
  360. .order-id {
  361. font-size: 28rpx;
  362. color: #999;
  363. .order-ids{
  364. font-family: PingFang SC;
  365. font-weight: 600;
  366. font-size: 16px;
  367. line-height: 140%;
  368. letter-spacing: 0%;
  369. color: #333;
  370. }
  371. }
  372. }
  373. .order-content {
  374. display: flex;
  375. align-items: center;
  376. margin-bottom: 20rpx;
  377. flex-direction: row;
  378. justify-content: space-between;
  379. .order-image {
  380. width: 160rpx;
  381. height: 160rpx;
  382. border-radius: 8rpx;
  383. // background-color: #fff8ea;
  384. background: #fffbe6;
  385. padding: 20rpx;
  386. box-sizing: border-box;
  387. display: block;
  388. }
  389. .order-arrow {
  390. padding: 0 30rpx;
  391. color: #999;
  392. }
  393. .order-info {
  394. // flex: 1;
  395. display: flex;
  396. flex-direction: column;
  397. text-align: center;
  398. .order-count {
  399. font-size: 32rpx;
  400. font-weight: 500;
  401. margin-bottom: 10rpx;
  402. background-color: #fffaee;
  403. // display: block;
  404. }
  405. .order-price {
  406. font-size: 28rpx;
  407. color: #666;
  408. margin-bottom: 10rpx;
  409. background-color: #fffaee;
  410. // display: block;
  411. }
  412. .order-estimate {
  413. display: inline-block;
  414. background:#ffac07;
  415. color: #fff;
  416. font-size: 26rpx;
  417. padding: 8rpx 20rpx;
  418. border-radius: 20rpx;
  419. }
  420. }
  421. }
  422. .order-status {
  423. display: flex;
  424. align-items: center;
  425. padding: 20rpx;
  426. background: #f4f4f4;
  427. border-radius: 8rpx;
  428. .status-icon {
  429. width: 80rpx;
  430. height: 80rpx;
  431. margin-right: 20rpx;
  432. }
  433. .status-info {
  434. flex: 1;
  435. .status-text {
  436. font-size: 28rpx;
  437. color: #333;
  438. margin-bottom: 6rpx;
  439. display: block;
  440. }
  441. .status-time {
  442. font-size: 26rpx;
  443. color: #999;
  444. }
  445. }
  446. }
  447. }
  448. </style>