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.

692 lines
15 KiB

6 months ago
  1. <template>
  2. <view class="content">
  3. <view class="navbar">
  4. <view
  5. v-for="(item, index) in navList" :key="index"
  6. class="nav-item"
  7. :class="{current: tabCurrentIndex === index}"
  8. @click="tabClick(index)"
  9. >
  10. {{item.text}}
  11. </view>
  12. </view>
  13. <swiper :current="tabCurrentIndex" class="swiper-box" duration="300" @change="changeTab">
  14. <swiper-item class="tab-content" v-for="(tabItem,tabIndex) in navList" :key="tabIndex">
  15. <scroll-view
  16. class="list-scroll-content"
  17. scroll-y
  18. @scrolltolower="loadData"
  19. >
  20. <!-- 空白页 -->
  21. <empty v-if="tabItem.loaded === true && tabItem.orderList.length === 0"></empty>
  22. <!-- 订单列表 -->
  23. <view
  24. v-for="(item,index) in tabItem.orderList" :key="index"
  25. class="order-item"
  26. >
  27. <view class="i-top b-b">
  28. <text class="time">{{item[0].dh}}</text>
  29. <text class="state" :style="{color: item.stateTipColor}">{{item[0].zt_text}}</text>
  30. <text
  31. v-if="item.state===9"
  32. class="del-btn yticon icon-iconfontshanchu1"
  33. @click="deleteOrder(index)"
  34. ></text>
  35. </view>
  36. <scroll-view v-if="item.length > 1" class="goods-box" scroll-x>
  37. <view
  38. v-for="(goodsItem, goodsIndex) in item" :key="goodsIndex"
  39. class="goods-item"
  40. >
  41. <image class="goods-img" :src="goodsItem.img" mode="aspectFill"></image>
  42. </view>
  43. </scroll-view>
  44. <view
  45. v-if="item.length === 1"
  46. class="goods-box-single"
  47. v-for="(goodsItem, goodsIndex) in item"
  48. >
  49. <image class="goods-img" :src="goodsItem.img" mode="aspectFill"></image>
  50. <view class="right">
  51. <text class="title clamp">{{goodsItem.mc}}</text>
  52. <text class="attr-box">{{goodsItem.gg}} x {{goodsItem.shisl}}</text>
  53. <text class="price">{{goodsItem.dj}}</text>
  54. </view>
  55. </view>
  56. <view class="price-box">
  57. <text class="num">{{item.length}}</text>
  58. 件商品 实付款
  59. <text class="price">{{allmoneylist[index]}}</text>
  60. </view>
  61. <view class="action-box b-t" v-if="item[0].is_pay == 0">
  62. <button class="action-btn" @click="cancelOrder(item)">取消订单</button>
  63. <button class="action-btn recom">立即支付</button>
  64. </view>
  65. <view class="action-box b-t" v-if="item[0].is_pay == 1&&item[0].order_zt<1">
  66. <button class="action-btn">已支付</button>
  67. <button class="action-btn recom" @click="dosqtuik(item)">申请退款</button>
  68. </view>
  69. </view>
  70. <uni-load-more :status="tabItem.loadingType"></uni-load-more>
  71. </scroll-view>
  72. </swiper-item>
  73. </swiper>
  74. </view>
  75. </template>
  76. <script>
  77. import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
  78. import empty from "@/components/empty";
  79. export default {
  80. components: {
  81. uniLoadMore,
  82. empty
  83. },
  84. data() {
  85. return {
  86. tabCurrentIndex: 0,
  87. navList: [{
  88. state: 0,
  89. text: '全部',
  90. loadingType: 'more',
  91. orderList: []
  92. },
  93. {
  94. state: 1,
  95. text: '待付款',
  96. loadingType: 'more',
  97. orderList: []
  98. },
  99. {
  100. state: 2,
  101. text: '待收货',
  102. loadingType: 'more',
  103. orderList: []
  104. },
  105. {
  106. state: 4,
  107. text: '售后',
  108. loadingType: 'more',
  109. orderList: []
  110. }
  111. ],
  112. getorderlist:[],
  113. allmoneylist:[]
  114. };
  115. },
  116. onShow(){
  117. },
  118. onLoad(options){
  119. /**
  120. * 修复app端点击除全部订单外的按钮进入时不加载数据的问题
  121. * 替换onLoad下代码即可
  122. */
  123. this.tabCurrentIndex = +options.state;
  124. // #ifndef MP
  125. this.loadData()
  126. // #endif
  127. // #ifdef MP
  128. if(options.state == 0){
  129. this.loadData()
  130. }
  131. // #endif
  132. },
  133. methods: {
  134. async orderlist(type) {
  135. let userinfo=uni.getStorageSync('userinfo');
  136. let redata=await this.$api.orderlist({action:'orderlist',uid:userinfo.uid,type:type});
  137. this.getorderlist=redata.data
  138. console.log(redata,'返回数据')
  139. },
  140. async cancelorder(dhid,item) {
  141. let reinfo=await this.$api.cancelOrder({action:'cancelOrder',dhid:dhid});
  142. let index = this.tabCurrentIndex;
  143. if(reinfo.code==1){
  144. //剔除该订单
  145. let {stateTip, stateTipColor} = this.orderStateExp(9);
  146. item = Object.assign(item, {
  147. state: 9,
  148. stateTip,
  149. stateTipColor
  150. })
  151. //取消订单后删除待付款中该项
  152. console.log(this.tabCurrentIndex,'当前类目')
  153. let list = this.navList[this.tabCurrentIndex].orderList;
  154. let index = list.findIndex(val=>val[0].dhid === item[0].dhid);
  155. index !== -1 && list.splice(index, 1);
  156. }
  157. uni.hideLoading();
  158. },
  159. async orderlist(type) {
  160. let userinfo=uni.getStorageSync('userinfo');
  161. let redata=await this.$api.orderlist({action:'orderlist',uid:userinfo.uid,type:type});
  162. this.getorderlist=redata.data
  163. console.log(redata,'返回数据')
  164. },
  165. async sqtuik(dhid,item) {
  166. let reinfo=await this.$api.sqtuik({action:'sqtuik',dhid:dhid});
  167. let index = this.tabCurrentIndex;
  168. if(reinfo.code==1){
  169. //剔除该订单
  170. let {stateTip, stateTipColor} = this.orderStateExp(9);
  171. item = Object.assign(item, {
  172. state: 9,
  173. stateTip,
  174. stateTipColor
  175. })
  176. //删除该项
  177. console.log(this.tabCurrentIndex,'当前类目')
  178. let list = this.navList[this.tabCurrentIndex].orderList;
  179. let index = list.findIndex(val=>val[0].dhid === item[0].dhid);
  180. index !== -1 && list.splice(index, 1);
  181. }
  182. uni.hideLoading();
  183. },
  184. //获取订单列表
  185. loadData(source){
  186. //这里是将订单挂载到tab列表下
  187. let index = this.tabCurrentIndex;
  188. this.orderlist(index);
  189. let navItem = this.navList[index];
  190. let state = navItem.index;
  191. if(source === 'tabChange' && navItem.loaded === true){
  192. //tab切换只有第一次需要加载数据
  193. return;
  194. }
  195. if(source != 'tabChange' &&navItem.loadingType === 'loading'){
  196. //防止重复加载
  197. return;
  198. }
  199. if(source != 'tabChange' && navItem.loadingType === 'noMore'){
  200. //tab切换只有第一次需要加载数据
  201. return;
  202. }
  203. navItem.loadingType = 'loading';
  204. let t=this;
  205. setTimeout(()=>{
  206. console.log(t.getorderlist,'')
  207. let allorderlist=t.getorderlist;
  208. let detailarrlist=[];
  209. for (var index in allorderlist) {
  210. detailarrlist.push(allorderlist[index])
  211. //console.log('key=', index, 'value=', allorderlist[index])
  212. }
  213. let orderList =detailarrlist.filter(item=>{
  214. //添加不同状态下订单的表现形式
  215. item = Object.assign(item, this.orderStateExp(item.is_pay));
  216. let allmoney=0;
  217. item.forEach(items=>{
  218. allmoney+=Number(items.sjmoney)
  219. })
  220. item.allmoney=allmoney
  221. this.allmoneylist.push(allmoney);
  222. //演示数据所以自己进行状态筛选
  223. if(state === 0){
  224. //0为全部订单
  225. return item;
  226. }
  227. return item.state === state
  228. });
  229. orderList.forEach(item=>{
  230. navItem.orderList.push(item);
  231. })
  232. //loaded新字段用于表示数据加载完毕,如果为空可以显示空白页
  233. t.$set(navItem, 'loaded', true);
  234. //判断是否还有数据, 有改为 more, 没有改为noMore
  235. navItem.loadingType = 'noMore';
  236. console.log(navItem.loadingType,'navItem.loadingType')
  237. }, 500);
  238. },
  239. refesh(type){
  240. this.orderlist(type)
  241. let allorderlist=this.getorderlist;
  242. this.navList[type].orderList=[]
  243. let navItem = this.navList[type];
  244. let detailarrlist=[];
  245. for (var index in allorderlist) {
  246. detailarrlist.push(allorderlist[index])
  247. }
  248. let orderList =detailarrlist.filter(item=>{
  249. //添加不同状态下订单的表现形式
  250. item = Object.assign(item, this.orderStateExp(item.is_pay));
  251. let allmoney=0;
  252. item.forEach(items=>{
  253. allmoney+=Number(items.sjmoney)
  254. })
  255. item.allmoney=allmoney
  256. this.allmoneylist.push(allmoney);
  257. //演示数据所以自己进行状态筛选
  258. return item;
  259. });
  260. orderList.forEach(item=>{
  261. navItem.orderList.push(item);
  262. })
  263. //loaded新字段用于表示数据加载完毕,如果为空可以显示空白页
  264. this.$set(navItem, 'loaded', true);
  265. navItem.loadingType = 'noMore';
  266. },
  267. //swiper 切换
  268. changeTab(e){
  269. this.tabCurrentIndex = e.target.current;
  270. this.loadData('tabChange');
  271. },
  272. //顶部tab点击
  273. tabClick(index){
  274. this.tabCurrentIndex = index;
  275. },
  276. //删除订单
  277. deleteOrder(index){
  278. uni.showLoading({
  279. title: '请稍后'
  280. })
  281. setTimeout(()=>{
  282. this.navList[this.tabCurrentIndex].orderList.splice(index, 1);
  283. uni.hideLoading();
  284. }, 600)
  285. },
  286. //取消订单
  287. cancelOrder(item){
  288. console.log(item,'得到')
  289. let t=this;
  290. uni.showModal({
  291. title: '温馨提示',
  292. content: '是否删除该订单?',
  293. success: function (res) {
  294. if (res.confirm) {
  295. uni.showLoading({
  296. title:'正在删除...'
  297. })
  298. t.cancelorder(item[0].dhid,item)
  299. } else if (res.cancel) {
  300. console.log('用户点击取消');
  301. }
  302. }
  303. });
  304. },
  305. dosqtuik(item){
  306. let t=this;
  307. uni.showModal({
  308. title: '温馨提示',
  309. content: '是否申请退款该订单?',
  310. success: function (res) {
  311. if (res.confirm) {
  312. uni.showLoading({
  313. title:'正在申请...'
  314. })
  315. t.sqtuik(item[0].dhid,item)
  316. } else if (res.cancel) {
  317. console.log('用户点击取消');
  318. }
  319. }
  320. });
  321. },
  322. //订单状态文字和颜色
  323. orderStateExp(state){
  324. let stateTip = '',
  325. stateTipColor = '#fa436a';
  326. switch(+state){
  327. case 1:
  328. stateTip = '待付款'; break;
  329. case 2:
  330. stateTip = '待发货'; break;
  331. case 9:
  332. stateTip = '订单已关闭';
  333. stateTipColor = '#909399';
  334. break;
  335. //更多自定义
  336. }
  337. return {stateTip, stateTipColor};
  338. }
  339. },
  340. }
  341. </script>
  342. <style lang="scss">
  343. page, .content{
  344. background: $page-color-base;
  345. height: 100%;
  346. }
  347. .swiper-box{
  348. height: calc(100% - 40px);
  349. }
  350. .list-scroll-content{
  351. height: 100%;
  352. }
  353. .navbar{
  354. display: flex;
  355. height: 40px;
  356. padding: 0 5px;
  357. background: #fff;
  358. box-shadow: 0 1px 5px rgba(0,0,0,.06);
  359. position: relative;
  360. z-index: 10;
  361. .nav-item{
  362. flex: 1;
  363. display: flex;
  364. justify-content: center;
  365. align-items: center;
  366. height: 100%;
  367. font-size: 15px;
  368. color: $font-color-dark;
  369. position: relative;
  370. &.current{
  371. color: $base-color;
  372. &:after{
  373. content: '';
  374. position: absolute;
  375. left: 50%;
  376. bottom: 0;
  377. transform: translateX(-50%);
  378. width: 44px;
  379. height: 0;
  380. border-bottom: 2px solid $base-color;
  381. }
  382. }
  383. }
  384. }
  385. .uni-swiper-item{
  386. height: auto;
  387. }
  388. .order-item{
  389. display: flex;
  390. flex-direction: column;
  391. padding-left: 30upx;
  392. background: #fff;
  393. margin-top: 16upx;
  394. .i-top{
  395. display: flex;
  396. align-items: center;
  397. height: 80upx;
  398. padding-right:30upx;
  399. font-size: $font-base;
  400. color: $font-color-dark;
  401. position: relative;
  402. .time{
  403. flex: 1;
  404. }
  405. .state{
  406. color: $base-color;
  407. }
  408. .del-btn{
  409. padding: 10upx 0 10upx 36upx;
  410. font-size: $font-lg;
  411. color: $font-color-light;
  412. position: relative;
  413. &:after{
  414. content: '';
  415. width: 0;
  416. height: 30upx;
  417. border-left: 1px solid $border-color-dark;
  418. position: absolute;
  419. left: 20upx;
  420. top: 50%;
  421. transform: translateY(-50%);
  422. }
  423. }
  424. }
  425. /* 多条商品 */
  426. .goods-box{
  427. height: 160upx;
  428. padding: 20upx 0;
  429. white-space: nowrap;
  430. .goods-item{
  431. width: 120upx;
  432. height: 120upx;
  433. display: inline-block;
  434. margin-right: 24upx;
  435. }
  436. .goods-img{
  437. display: block;
  438. width: 100%;
  439. height: 100%;
  440. }
  441. }
  442. /* 单条商品 */
  443. .goods-box-single{
  444. display: flex;
  445. padding: 20upx 0;
  446. .goods-img{
  447. display: block;
  448. width: 120upx;
  449. height: 120upx;
  450. }
  451. .right{
  452. flex: 1;
  453. display: flex;
  454. flex-direction: column;
  455. padding: 0 30upx 0 24upx;
  456. overflow: hidden;
  457. .title{
  458. font-size: $font-base + 2upx;
  459. color: $font-color-dark;
  460. line-height: 1;
  461. }
  462. .attr-box{
  463. font-size: $font-sm + 2upx;
  464. color: $font-color-light;
  465. padding: 10upx 12upx;
  466. }
  467. .price{
  468. font-size: $font-base + 2upx;
  469. color: $font-color-dark;
  470. &:before{
  471. content: '¥';
  472. font-size: $font-sm;
  473. margin: 0 2upx 0 8upx;
  474. }
  475. }
  476. }
  477. }
  478. .price-box{
  479. display: flex;
  480. justify-content: flex-end;
  481. align-items: baseline;
  482. padding: 20upx 30upx;
  483. font-size: $font-sm + 2upx;
  484. color: $font-color-light;
  485. .num{
  486. margin: 0 8upx;
  487. color: $font-color-dark;
  488. }
  489. .price{
  490. font-size: $font-lg;
  491. color: $font-color-dark;
  492. &:before{
  493. content: '¥';
  494. font-size: $font-sm;
  495. margin: 0 2upx 0 8upx;
  496. }
  497. }
  498. }
  499. .action-box{
  500. display: flex;
  501. justify-content: flex-end;
  502. align-items: center;
  503. height: 100upx;
  504. position: relative;
  505. padding-right: 30upx;
  506. }
  507. .action-btn{
  508. width: 160upx;
  509. height: 60upx;
  510. margin: 0;
  511. margin-left: 24upx;
  512. padding: 0;
  513. text-align: center;
  514. line-height: 60upx;
  515. font-size: $font-sm + 2upx;
  516. color: $font-color-dark;
  517. background: #fff;
  518. border-radius: 100px;
  519. &:after{
  520. border-radius: 100px;
  521. }
  522. &.recom{
  523. background: #fff9f9;
  524. color: $base-color;
  525. &:after{
  526. border-color: #f7bcc8;
  527. }
  528. }
  529. }
  530. }
  531. /* load-more */
  532. .uni-load-more {
  533. display: flex;
  534. flex-direction: row;
  535. height: 80upx;
  536. align-items: center;
  537. justify-content: center
  538. }
  539. .uni-load-more__text {
  540. font-size: 28upx;
  541. color: #999
  542. }
  543. .uni-load-more__img {
  544. height: 24px;
  545. width: 24px;
  546. margin-right: 10px
  547. }
  548. .uni-load-more__img>view {
  549. position: absolute
  550. }
  551. .uni-load-more__img>view view {
  552. width: 6px;
  553. height: 2px;
  554. border-top-left-radius: 1px;
  555. border-bottom-left-radius: 1px;
  556. background: #999;
  557. position: absolute;
  558. opacity: .2;
  559. transform-origin: 50%;
  560. animation: load 1.56s ease infinite
  561. }
  562. .uni-load-more__img>view view:nth-child(1) {
  563. transform: rotate(90deg);
  564. top: 2px;
  565. left: 9px
  566. }
  567. .uni-load-more__img>view view:nth-child(2) {
  568. transform: rotate(180deg);
  569. top: 11px;
  570. right: 0
  571. }
  572. .uni-load-more__img>view view:nth-child(3) {
  573. transform: rotate(270deg);
  574. bottom: 2px;
  575. left: 9px
  576. }
  577. .uni-load-more__img>view view:nth-child(4) {
  578. top: 11px;
  579. left: 0
  580. }
  581. .load1,
  582. .load2,
  583. .load3 {
  584. height: 24px;
  585. width: 24px
  586. }
  587. .load2 {
  588. transform: rotate(30deg)
  589. }
  590. .load3 {
  591. transform: rotate(60deg)
  592. }
  593. .load1 view:nth-child(1) {
  594. animation-delay: 0s
  595. }
  596. .load2 view:nth-child(1) {
  597. animation-delay: .13s
  598. }
  599. .load3 view:nth-child(1) {
  600. animation-delay: .26s
  601. }
  602. .load1 view:nth-child(2) {
  603. animation-delay: .39s
  604. }
  605. .load2 view:nth-child(2) {
  606. animation-delay: .52s
  607. }
  608. .load3 view:nth-child(2) {
  609. animation-delay: .65s
  610. }
  611. .load1 view:nth-child(3) {
  612. animation-delay: .78s
  613. }
  614. .load2 view:nth-child(3) {
  615. animation-delay: .91s
  616. }
  617. .load3 view:nth-child(3) {
  618. animation-delay: 1.04s
  619. }
  620. .load1 view:nth-child(4) {
  621. animation-delay: 1.17s
  622. }
  623. .load2 view:nth-child(4) {
  624. animation-delay: 1.3s
  625. }
  626. .load3 view:nth-child(4) {
  627. animation-delay: 1.43s
  628. }
  629. @-webkit-keyframes load {
  630. 0% {
  631. opacity: 1
  632. }
  633. 100% {
  634. opacity: .2
  635. }
  636. }
  637. </style>