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.

343 lines
8.7 KiB

4 years ago
  1. <template>
  2. <view class="app">
  3. <view class="nav-wrap">
  4. <mix-nav-bar :navs="navs" :counts="navCounts" :current="navCurrent" @onChange="onNavBarChange"></mix-nav-bar>
  5. </view>
  6. <mescroll-body
  7. ref="mescrollRef"
  8. @init="mescrollInit"
  9. :top="84"
  10. @down="downCallback"
  11. :up="upOption"
  12. @up="loadData"
  13. >
  14. <view class="item column" v-for="(item, index) in list" :key="index" @click="navTo('detail?id='+item._id)">
  15. <view class="i-header row b-b">
  16. <text class="time fill">{{ item.add_time | date('Y-m-d H:i') }}</text>
  17. <text class="state" :class="{gray:item.status===10}">{{ item.status_text }}</text>
  18. </view>
  19. <!-- 单商品 -->
  20. <view v-if="item.products.length === 1" class="goods-wrap row">
  21. <view class="image-wrapper lazyload lazypic" :class="{loaded: item.loaded}">
  22. <image :src="item.products[0].image" mode="aspectFill" lazy-load="true" @load="imageOnLoad(item)" ></image>
  23. </view>
  24. <view class="right column">
  25. <text class="title clamp">{{ item.products[0].title }}</text>
  26. <text class="attr">{{ item.products[0].sku.name }}</text>
  27. <view class="r-b">
  28. <text class="price">{{ item.products[0].price }}</text>
  29. <text class="number">x{{ item.products[0].number }}</text>
  30. </view>
  31. </view>
  32. </view>
  33. <!-- 多商品 -->
  34. <scroll-view v-else class="scroll-view" scroll-x>
  35. <view class="goods-list">
  36. <view v-for="(gItem, gIndex) in item.products" :key="gIndex" class="image-wrapper lazyload lazypic" :class="{loaded: item.loaded}">
  37. <image :src="gItem.image" mode="aspectFill" lazy-load="true" @load="imageOnLoad(item)" ></image>
  38. </view>
  39. </view>
  40. </scroll-view>
  41. <view class="price-wrap">
  42. <text>{{ item.product_number }} 实付:</text>
  43. <text class="price">{{ item.price_data.pay_price }}</text>
  44. </view>
  45. <view class="btn-group row" @click.stop.prevent="stopPrevent">
  46. <view v-if="item.status===4 || item.status===10 || item.status===11 || item.status===14" class="btn center round" @click="deleteOrder(index)">
  47. <text>删除订单</text>
  48. </view>
  49. <view v-if="item.status===0" class="btn center round" @click="cancelOrder(item)">
  50. <text>取消订单</text>
  51. </view>
  52. <view v-if="item.status===0" class="btn center" @click="pay(item)">
  53. <text>立即支付</text>
  54. </view>
  55. <!-- #ifdef MP -->
  56. <button type="default" open-type="contact">
  57. <view v-if="item.status===1" class="btn center round" @click="cancelOrder(item)">
  58. <text>联系客服</text>
  59. </view>
  60. </button>
  61. <!-- #endif -->
  62. <!-- #ifdef MP -->
  63. <view v-if="item.status===1" class="btn center round" @click="showRefundAction(item)">
  64. <text>申请退款</text>
  65. </view>
  66. <!-- #endif -->
  67. <view v-if="item.status===1" class="btn center round" @click="navTo('zizhufahuo?id='+item._id)">
  68. <text>自助发货</text>
  69. </view>
  70. <view v-if="item.status===2" class="btn center round" @click="navToExpress(item)">
  71. <text>查看物流</text>
  72. </view>
  73. <view v-if="item.status===2" class="btn center" @click="confirmReceipt(item)">
  74. <text>确认收货</text>
  75. </view>
  76. <view v-if="item.status===3" class="btn center" @click="rate(item)">
  77. <text>立即评价</text>
  78. </view>
  79. </view>
  80. </view>
  81. </mescroll-body>
  82. <mix-loading v-if="isLoading" :mask="true"></mix-loading>
  83. <mix-modal ref="mixModal" title="订单提示" :text="modalText" @onConfirm="onModalConfirm"></mix-modal>
  84. <mix-action-sheet ref="mixActionSheet" @onConfirm="refund"></mix-action-sheet>
  85. </view>
  86. </template>
  87. <script>
  88. import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue"
  89. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  90. import OrderMixin from './mixin/order.js'
  91. export default {
  92. components: {
  93. MescrollBody
  94. },
  95. mixins: [MescrollMixin, OrderMixin],
  96. data() {
  97. return {
  98. curPage: 'orderList',
  99. navCounts: [], //订单数量
  100. navs: [{name: '全部'}, {name: '待付款'}, {name: '待发货'}, {name: '待收货'}, {name: '待评价'}],
  101. navCurrent: 0, //当前tab
  102. upOption:{
  103. page: {
  104. num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
  105. size: 10 // 每页数据的数量
  106. },
  107. noMoreSize: 3, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
  108. },
  109. modalText: '', //确认对话框内容
  110. list: [] //订单列表
  111. }
  112. },
  113. computed: {
  114. orderCount(){
  115. return this.$store.state.orderCount;
  116. }
  117. },
  118. watch: {
  119. orderCount(){
  120. this.navCounts = [0].concat(Object.values(this.orderCount));
  121. }
  122. },
  123. onLoad(options) {
  124. this.navCurrent = +options.current;
  125. this.navCounts = [0].concat(Object.values(this.orderCount));
  126. },
  127. onShow(){
  128. if(this.loaded){
  129. this.refreshList(false);
  130. }
  131. },
  132. methods: {
  133. async loadData(e){
  134. this.mescroll && this.mescroll.removeEmpty();
  135. const sendData = {
  136. offset: (e.num - 1) * e.size,
  137. limit: e.size,
  138. }
  139. //tab对应订单状态
  140. const status = this.getCurrentStatus();
  141. if(status.length > 0){
  142. sendData.status = status;
  143. }
  144. const res = await this.$request('order', 'getList', sendData);
  145. const curList = res.data;
  146. if(e.num === 1){
  147. //第一页清空数据重载
  148. this.list = [];
  149. this.loaded && curList.forEach(item=> {item.loaded = true})
  150. if(curList.length > 0){
  151. uni.pageScrollTo({
  152. scrollTop: 0,
  153. duration: 0
  154. })
  155. }
  156. }
  157. this.list = this.list.concat(curList); //追加新数据
  158. this.mescroll.endSuccess(curList.length); //结束加载状态
  159. },
  160. //刷新列表
  161. refreshList(showLoading){
  162. this.mescroll && this.mescroll.resetUpScroll(false)
  163. if(showLoading !== false){
  164. this.isLoading = true;
  165. }
  166. this.$store.dispatch('getOrderCount');
  167. },
  168. mescrollInit(mescroll){
  169. this.mescroll = mescroll;
  170. setTimeout(()=>{
  171. this.refreshList();
  172. }, 10)
  173. },
  174. //tab切换
  175. onNavBarChange(current){
  176. if(this.navCurrent === current){
  177. return;
  178. }
  179. this.navCurrent = current;
  180. this.refreshList();
  181. },
  182. //获取当前tab对应订单状态
  183. getCurrentStatus(){
  184. if(this.navCurrent === 0){
  185. return [];
  186. }else{
  187. return [this.navCurrent - 1];
  188. }
  189. }
  190. }
  191. }
  192. </script>
  193. <style>
  194. page{
  195. background-color: #f7f7f7;
  196. }
  197. </style>
  198. <style scoped lang="scss">
  199. .app{
  200. }
  201. .item{
  202. width: 710rpx;
  203. padding-bottom: 24rpx;
  204. margin-top: 20rpx;
  205. margin-left: 20rpx;
  206. background-color: #fff;
  207. border-radius: 12rpx;
  208. }
  209. .b-b:after{
  210. left: 4rpx;
  211. right: 4rpx;
  212. border-color: #e5e5e5;
  213. }
  214. .i-header{
  215. height: 80rpx;
  216. padding: 0 24rpx;
  217. margin-bottom: 24rpx;
  218. .time{
  219. font-size: 26rpx;
  220. color: #999;
  221. }
  222. .state{
  223. font-size: 30rpx;
  224. color: $base-color;
  225. &.gray{
  226. color: #999;
  227. }
  228. }
  229. }
  230. .scroll-view{
  231. width: 100%;
  232. height: 150rpx;
  233. .goods-list{
  234. display: flex;
  235. &::before, &::after{
  236. content: '';
  237. width: 20rpx;
  238. height: 130rpx;
  239. flex-shrink: 0;
  240. }
  241. &::after{
  242. width: 10rpx;
  243. }
  244. .image-wrapper{
  245. flex-shrink: 0;
  246. width: 130rpx;
  247. height: 130rpx;
  248. margin-right: 16rpx;
  249. border-radius: 4rpx;
  250. overflow: hidden;
  251. }
  252. image{
  253. width: 100%;
  254. height: 100%;
  255. }
  256. }
  257. }
  258. .goods-wrap{
  259. padding: 0 20rpx;
  260. .image-wrapper{
  261. width: 130rpx;
  262. height: 130rpx;
  263. border-radius: 4rpx;
  264. overflow: hidden;
  265. image{
  266. width: 100%;
  267. height: 100%;
  268. }
  269. }
  270. .right{
  271. flex: 1;
  272. padding-left: 20rpx;
  273. overflow: hidden;
  274. }
  275. .title{
  276. font-size: 28rpx;
  277. color: #333;
  278. }
  279. .attr{
  280. margin: 16rpx 0 20rpx;
  281. min-height: 30rpx;
  282. font-size: 24rpx;
  283. color: #999;
  284. }
  285. .r-b{
  286. display: flex;
  287. height: 30rpx;
  288. }
  289. .price{
  290. font-size: 28rpx;
  291. color: #333;
  292. font-weight: normal;
  293. }
  294. .number{
  295. margin-left: 16rpx;
  296. font-size: 26rpx;
  297. color: #999;
  298. }
  299. }
  300. .price-wrap{
  301. display: flex;
  302. justify-content: flex-end;
  303. padding: 16rpx 24rpx 30rpx;
  304. font-size: 26rpx;
  305. color: #333;
  306. .price{
  307. font-size: 30rpx;
  308. font-weight: 700;
  309. }
  310. }
  311. .btn-group{
  312. justify-content: flex-end;
  313. padding-right: 16rpx;
  314. .btn{
  315. width: 150rpx;
  316. height: 60rpx;
  317. margin-left: 20rpx;
  318. font-size: 24rpx;
  319. color: #fff;
  320. background-color: $base-color;
  321. border-radius: 100rpx;
  322. }
  323. .round{
  324. background-color: #fff;
  325. color: #333;
  326. }
  327. }
  328. </style>