order-list.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <view class="order-list">
  3. <tui-skeleton v-if="isRequest" loadingType="2"></tui-skeleton>
  4. <cm-header-nav
  5. @leftClick="handleLeftClick"
  6. @rightClick="handleRightClick"
  7. @init="headerNavInit"
  8. :leftButtonGroup="leftButtonGroup"
  9. title="订单列表"
  10. ></cm-header-nav>
  11. <!-- 滑块 tabs -->
  12. <view class="tabs">
  13. <tui-tabs
  14. :tabs="tabs"
  15. :currentTab="currentTab"
  16. @change="tabChange"
  17. :sliderWidth="48"
  18. color="#333333"
  19. selectedColor="#FF457B"
  20. sliderBgColor="#FF457B"
  21. ></tui-tabs>
  22. </view>
  23. <!-- 协销筛选订单 -->
  24. <cm-order-filter-control
  25. @click="handleFilter"
  26. :buttonGroup="screenTabBar"
  27. v-if="isDealer"
  28. ></cm-order-filter-control>
  29. <swiper
  30. :indicator-dots="false"
  31. :autoplay="false"
  32. class="swiper"
  33. :style="[swiperHeight]"
  34. :current="currentTab"
  35. @change="swiperChange"
  36. >
  37. <swiper-item v-for="tab in tabs" :key="tab.state">
  38. <!-- tab.orderList.length === 0 -->
  39. <view class="order-empty" v-if="tab.orderList.length === 0">
  40. <cm-empty :image="emptyInfo.image" :message="emptyInfo.message" :offset="100"></cm-empty>
  41. </view>
  42. <scroll-view scroll-y="true" v-else class="scroll-box" @scrolltolower="scrollBottom">
  43. <template v-for="(orderInfo, orderIndex) in tab.orderList">
  44. <view class="grid" :key="orderIndex"></view>
  45. <view class="order-section" :key="orderIndex" @click="handleToDetail(orderInfo)">
  46. <!-- 订单信息 -->
  47. <view class="order-info">
  48. <view class="order-num">
  49. <text class="label">订单编号:</text>
  50. <text>{{ orderInfo.orderNo }}</text>
  51. </view>
  52. <view class="order-time">
  53. <text class="label">下单时间:</text>
  54. <text>{{ orderInfo.orderTime }}</text>
  55. </view>
  56. <view class="status">{{ stateExpFormat(orderInfo.status) }}</view>
  57. </view>
  58. <view class="line"></view>
  59. <view
  60. class="shop-order"
  61. v-for="(shopOrder, shopOrderIndex) in orderInfo.shopOrderList"
  62. :key="shopOrderIndex"
  63. >
  64. <!-- 供应商 -->
  65. <view class="origin">
  66. <image class="cover" :src="shopOrder.shopLogo"></image>
  67. <view class="name">{{ shopOrder.shopName }}</view>
  68. </view>
  69. <!-- 商品列表 -->
  70. <view class="goods-list">
  71. <!-- 商品信息 -->
  72. <view
  73. class="order-goods"
  74. v-for="goods in shopOrder.orderProductList"
  75. :key="goods.productId"
  76. >
  77. <cm-order-prodcut :goods-data="goods"></cm-order-prodcut>
  78. </view>
  79. </view>
  80. </view>
  81. <!-- 统计 -->
  82. <view class="total">
  83. <view class="count">共{{ orderInfo.productCount }}件商品</view>
  84. <view class="status">
  85. <template v-if="['31', '32', '33'].includes(orderInfo.status)">
  86. <text class="label">已支付:</text>
  87. <text>¥{{ orderInfo.receiptAmount | formatPrice }}</text>
  88. </template>
  89. <template v-else>
  90. <text class="label">待付总额:</text>
  91. <text>¥{{ orderInfo.pendingPayments | formatPrice }}</text>
  92. </template>
  93. </view>
  94. </view>
  95. <!-- 操作 -->
  96. <cm-order-control-nav
  97. v-if="orderInfo.userId == userId"
  98. :orderInfo="orderInfo"
  99. @confirm="handleConfirmClick"
  100. ></cm-order-control-nav>
  101. </view>
  102. </template>
  103. <!-- loading -->
  104. <view class="loading-more">
  105. <tui-loadmore :index="3" :visible="loadmore"></tui-loadmore>
  106. <tui-nomore :text="loadMoreText" :visible="!loadmore" backgroundColor="#f7f7f7"></tui-nomore>
  107. </view>
  108. </scroll-view>
  109. </swiper-item>
  110. </swiper>
  111. <!-- 操作弹窗 -->
  112. <tui-modal
  113. :show="modal"
  114. :content="modalText"
  115. :size="32"
  116. :maskClosable="false"
  117. color="#333"
  118. shape="circle"
  119. @click="handleModalConfirm"
  120. ></tui-modal>
  121. <!-- 加载框 -->
  122. <cm-loading :visible="isSubLoading" :text="loadingText"></cm-loading>
  123. <!-- 失效商品列表 -->
  124. <cm-order-invalid-modal
  125. :goodsList="invalidList"
  126. :visible="buyAgainModal"
  127. @confirm="buyAgainModalClick"
  128. @cancel="buyAgainModalHide"
  129. ></cm-order-invalid-modal>
  130. </view>
  131. </template>
  132. <script>
  133. import CmOrderProdcut from '@/components/cm-module/cm-order-prodcut/cm-order-prodcut.vue'
  134. import CmOrderControlNav from '@/components/cm-module/cm-order-control-nav/cm-order-control-nav.vue'
  135. import CmOrderInvalidModal from '@/components/cm-module/cm-order-invalid-modal/cm-order-invalid-modal.vue'
  136. import CmOrderFilterControl from '@/components/cm-module/cm-order-filter-control/cm-order-filter-control.vue'
  137. import CmLoading from '@/components/cm-module/cm-loading/cm-loading.vue'
  138. import CmEmpty from '@/components/cm-module/cm-empty/cm-empty.vue'
  139. import CmHeaderNav from '@/components/cm-module/cm-header-nav/cm-header-nav.vue'
  140. import { debounce } from '@/common/common.js'
  141. import orderList from './mixins/orderList.js'
  142. import wechatPay from './mixins/wechatPay.js'
  143. import { mapGetters } from 'vuex'
  144. export default {
  145. mixins: [wechatPay, orderList],
  146. components: {
  147. CmOrderProdcut,
  148. CmOrderControlNav,
  149. CmOrderInvalidModal,
  150. CmOrderFilterControl,
  151. CmLoading,
  152. CmEmpty,
  153. CmHeaderNav
  154. },
  155. data() {
  156. return {
  157. tabs: [
  158. {
  159. name: '全部',
  160. state: 0,
  161. pageNum: 1,
  162. orderList: []
  163. },
  164. {
  165. name: '待付款',
  166. state: 1,
  167. pageNum: 1,
  168. orderList: []
  169. },
  170. {
  171. name: '待发货',
  172. state: 2,
  173. pageNum: 1,
  174. orderList: []
  175. },
  176. {
  177. name: '已发货',
  178. state: 3,
  179. pageNum: 1,
  180. orderList: []
  181. },
  182. {
  183. name: '退货/款',
  184. state: 4,
  185. pageNum: 1,
  186. orderList: []
  187. }
  188. ],
  189. currentTab: 0,
  190. screenTabBar: [{ id: 0, name: '全部订单' }, { id: 1, name: '用户订单' }, { id: 2, name: '自身订单' }],
  191. screenTab: 0,
  192. refresh: false,
  193. loadmore: false, // 正在加载更多
  194. isRequest: true,
  195. leftButtonGroup: [
  196. {
  197. icon: 'icon-daohangfanhui',
  198. color: '#333'
  199. }
  200. ],
  201. headerNavHeight: 0
  202. }
  203. },
  204. computed: {
  205. ...mapGetters(['userId', 'userIdentity']),
  206. // 当前用户是否为协销
  207. isDealer() {
  208. return this.userIdentity === 2
  209. },
  210. tabInfo() {
  211. return this.tabs[this.currentTab]
  212. },
  213. loadMoreText() {
  214. if (this.tabInfo.orderList.length === 0) return '没有更多了'
  215. return this.tabInfo.hasMore ? '上拉加载更多' : '没有更多了'
  216. },
  217. emptyInfo() {
  218. const info = {}
  219. info.image = `${this.$Static}icon-empty-address.png`
  220. if (this.tabInfo.state === 0) {
  221. info.message = '您还没有任何的订单哟~_~'
  222. } else {
  223. info.message = '您还没有相关的订单哟~_~'
  224. }
  225. return info
  226. },
  227. swiperHeight(){
  228. let offset = 44
  229. if(this.isDealer){
  230. offset = 84
  231. }
  232. return {
  233. height: `calc(100vh - ${offset}px - ${this.headerNavHeight}px);`
  234. }
  235. }
  236. },
  237. onLoad(options) {
  238. this.currentTab = options.state
  239. this.fetchOrderData()
  240. this.$on('orderAction', () => {
  241. this.resetOrderList()
  242. })
  243. },
  244. // 下拉刷新
  245. onPullDownRefresh() {
  246. this.resetOrderList()
  247. },
  248. beforeDestroy() {
  249. this.$off('orderAction')
  250. },
  251. methods: {
  252. // 导航栏初始化
  253. headerNavInit(info){
  254. this.headerNavHeight = info.height
  255. },
  256. // 导航栏点击事件
  257. handleLeftClick(e) {
  258. if (e.index) {
  259. uni.switchTab({ url: '/pages/tabBar/index/index' })
  260. } else {
  261. uni.navigateBack({ delta: 1 })
  262. }
  263. },
  264. handleRightClick() {
  265. uni.navigateTo({ url: '/pages/order/order-search' })
  266. },
  267. // 重置订单列表
  268. resetOrderList() {
  269. this.refresh = true
  270. this.tabInfo.pageNum = 1
  271. this.fetchOrderData()
  272. },
  273. // 更新订单列表
  274. updateOrderList(response) {
  275. const { name, state, pageNum } = this.tabInfo
  276. this.$set(this.tabs, this.currentTab, {
  277. name,
  278. state,
  279. pageNum: pageNum + 1,
  280. orderList: this.tabInfo.orderList.concat(response.data.list),
  281. hasMore: response.data.hasNextPage
  282. })
  283. },
  284. // 获取订单列表 使用防抖函数封装
  285. fetchOrderData: debounce(function() {
  286. this.loadmore = true
  287. const params = {
  288. orderState: this.currentTab,
  289. userId: this.userId,
  290. orderType: this.screenTab,
  291. pageNum: this.tabInfo.pageNum,
  292. pageSize: 10
  293. }
  294. if (this.isDealer) {
  295. this.queryOrderDealerList(params)
  296. } else {
  297. this.queryOrderList(params)
  298. }
  299. }, 500),
  300. // 普通用户获取订单列表
  301. queryOrderList(params) {
  302. this.OrderService.QueryOrderList(params)
  303. .then(res => {
  304. if (this.refresh) this.tabInfo.orderList = []
  305. this.updateOrderList(res)
  306. })
  307. .catch(err => {
  308. console.log(err)
  309. })
  310. .finally(() => {
  311. uni.stopPullDownRefresh()
  312. this.refresh = false
  313. this.loadmore = false
  314. this.isRequest = false
  315. })
  316. },
  317. // 分销者获取订单列表
  318. queryOrderDealerList(params) {
  319. console.log(params)
  320. this.OrderService.QueryOrderDealerList(params)
  321. .then(res => {
  322. if (this.refresh) this.tabInfo.orderList = []
  323. this.updateOrderList(res)
  324. })
  325. .catch(err => {
  326. console.log(err)
  327. })
  328. .finally(() => {
  329. uni.stopPullDownRefresh()
  330. this.refresh = false
  331. this.loadmore = false
  332. this.isRequest = false
  333. })
  334. },
  335. // 筛选订单
  336. handleFilter(e) {
  337. console.log(e.index)
  338. this.screenTab = e.index
  339. this.resetOrderList()
  340. this.fetchOrderData()
  341. },
  342. // 跳转详情
  343. handleToDetail(orderInfo) {
  344. this.$api.navigateTo('/pages/order/order-detail?orderId=' + orderInfo.orderId)
  345. },
  346. // 滚动到底部
  347. scrollBottom() {
  348. if (!this.tabInfo.hasMore) return
  349. this.fetchOrderData()
  350. },
  351. // tab切换
  352. tabChange(e) {
  353. this.currentTab = e.index
  354. },
  355. // 轮播切换
  356. swiperChange(e) {
  357. this.currentTab = e.detail.current
  358. if (this.tabInfo.pageNum !== 1) return
  359. this.isRequest = true
  360. this.fetchOrderData()
  361. }
  362. }
  363. }
  364. </script>
  365. <style lang="scss" scoped>
  366. .order-list {
  367. min-height: 100vh;
  368. background: #f7f7f7;
  369. .tabs {
  370. position: relative;
  371. z-index: 100000;
  372. }
  373. .swiper {
  374. &.swiper-hegiht1 {
  375. height: calc(100vh - 44px);
  376. }
  377. &.swiper-hegiht2 {
  378. height: calc(100vh - 84px);
  379. }
  380. .scroll-box {
  381. height: 100%;
  382. }
  383. }
  384. .grid {
  385. height: 20rpx;
  386. background: #f7f7f7;
  387. }
  388. .order-section {
  389. padding: 38rpx 0;
  390. background-color: #fff;
  391. .line {
  392. width: 702rpx;
  393. height: 1px;
  394. background: #f7f7f7;
  395. }
  396. .order-info {
  397. position: relative;
  398. padding: 0 24rpx;
  399. margin-bottom: 32rpx;
  400. line-height: 1.6;
  401. .order-num,
  402. .order-time {
  403. font-size: 26rpx;
  404. color: #333333;
  405. .label {
  406. color: #999999;
  407. }
  408. }
  409. .status {
  410. position: absolute;
  411. font-size: 26rpx;
  412. color: #ff457b;
  413. right: 24rpx;
  414. bottom: 0;
  415. }
  416. }
  417. .origin {
  418. padding: 0 24rpx;
  419. margin-top: 24rpx;
  420. margin-bottom: 16rpx;
  421. display: flex;
  422. justify-content: flex-start;
  423. align-items: center;
  424. .cover {
  425. width: 56rpx;
  426. height: 56rpx;
  427. border-radius: 4rpx;
  428. border: 1px solid #f7f7f7;
  429. box-sizing: border-box;
  430. }
  431. .name {
  432. margin-left: 16rpx;
  433. font-size: 30rpx;
  434. color: #333333;
  435. font-weight: bold;
  436. }
  437. }
  438. .goods-list {
  439. .order-goods {
  440. padding-top: 32rpx;
  441. &:first-child {
  442. padding-top: 0;
  443. }
  444. }
  445. }
  446. .total {
  447. display: flex;
  448. justify-content: space-between;
  449. align-items: center;
  450. padding: 0 24rpx;
  451. margin: 32rpx 0;
  452. font-size: 26rpx;
  453. color: #333333;
  454. .count {
  455. font-weight: bold;
  456. }
  457. .status {
  458. color: #ff457b;
  459. .label {
  460. color: #333333;
  461. }
  462. }
  463. }
  464. }
  465. }
  466. </style>