after-sale-detail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. <template>
  2. <view class="container">
  3. <Navbar title="我的订单" background-color="#fff" color="#333"></Navbar>
  4. <view class="head">
  5. <text class="status">{{ infoStatus | filterStatus }}</text>
  6. </view>
  7. <!-- <view class="logistics" @click="tologistics" v-if="logList.length">
  8. <text class="icon">&#xe6f3;</text>
  9. <view class="logistics-detail">
  10. <text class="word12 title">{{ logList[0].context }}</text>
  11. <text class="word12-gray9 time">{{ logList[0].time }}</text>
  12. </view>
  13. <text class="right">&#xe70d;</text>
  14. </view> -->
  15. <view class="address-info" v-if="infoStatus === 2">
  16. 退货地址:{{returnInfo.address}}
  17. <view>
  18. <text class="name">{{returnInfo.name}}</text>
  19. <text class="phone">{{returnInfo.phone}}</text>
  20. </view>
  21. </view>
  22. <view class="order-wrap">
  23. <OrderItem :sku="skuList" :oid="oid" :total="payment"></OrderItem>
  24. </view>
  25. <view class="row">
  26. 退款金额
  27. <text>¥{{info.amount | moneyFormat}}</text>
  28. </view>
  29. <view class="row">
  30. 售后方式
  31. <text>{{typeMap[info.afterType]}}</text>
  32. </view>
  33. <view class="row row2">
  34. 退款原因
  35. <text>{{info.afterReason}}</text>
  36. </view>
  37. <view class="remark">
  38. {{info.afterRemark}}
  39. </view>
  40. <view class="detail">
  41. <text class="word12-gray9">订单编号:</text>
  42. <text class="word12-gray9 half">{{ oid }}</text>
  43. <text class="word12-gray9">申请时间</text>
  44. <text class="word12-gray9 half">{{ info.created }}</text>
  45. </view>
  46. <button class="conchat" open-type="contact" :session-from="`7moor|${_userInfo.nickname}|${_userInfo.avatar}|${JSON.stringify({uid: _userInfo.uid})}`">
  47. <view class="left">
  48. <IconText class="icon" :code="`\ue751`" size="12" color="#333"></IconText>
  49. 联系客服
  50. </view>
  51. <IconText :code="`\ue84a`" size="12" color="#999"></IconText>
  52. </button>
  53. <view class="steps-box">
  54. <uni-steps :options="histories" active-color="#333" :active="0" direction="column" />
  55. </view>
  56. <view class="btn-box" v-if="infoStatus === 1">
  57. <view class="btn btn2" @click.stop="cancelAfterSaleModal">撤销售后</view>
  58. </view>
  59. <view class="bottom-btn" v-if="infoStatus === 2">
  60. <view class="solid-btn" @click="toDeliverGoods">去发货</view>
  61. </view>
  62. <ShowModal ref="cancelOrder" title="提示" @submit="cancelAfterSale" leftBtnText="取消" content="确定要撤销该售后吗"
  63. btnText="确认" />
  64. </view>
  65. </template>
  66. <script lang="ts">
  67. import {
  68. Component,
  69. Vue,
  70. } from 'vue-property-decorator';
  71. import {
  72. namespace
  73. } from 'vuex-class';
  74. const baseModule = namespace('base');
  75. @Component({
  76. filters: {
  77. filterStatus(val: any) {
  78. let objMap: any = {
  79. 1: '已申请待审核',
  80. 2: '已审核待退货',
  81. 3: '已退货待确认',
  82. 5: '已审核待退款',
  83. 6: '售后成功',
  84. 7: '售后失败'
  85. }
  86. return objMap[val] || '';
  87. },
  88. phoneStatus(val: string): string {
  89. if (!val) return '';
  90. return val.substring(0, 3) + '****' + val.substring(7);
  91. },
  92. moneyFormat(val: any) {
  93. if (!+val) return '0.00';
  94. return (+val).toFixed(2);
  95. },
  96. freightFormat(val: any) {
  97. if (val <= 0) {
  98. return "包邮"
  99. } else {
  100. return (+val).toFixed(2);
  101. }
  102. }
  103. }
  104. })
  105. export default class OrderDetail extends Vue {
  106. @baseModule.Getter('_userInfo') _userInfo: any;
  107. detail: any = {
  108. address: {
  109. phone: ''
  110. }
  111. };
  112. oid: number = 0;
  113. info: any = {};
  114. Status: any = {};
  115. minite: number = 0;
  116. second: number = 0;
  117. timer: any = null; // 倒计时定时器
  118. from: string = '';
  119. logList: any[] = [];
  120. isFirst: boolean = false;
  121. payment: number = 0;
  122. skuList: any[] = [];
  123. infoStatus: number = 0;
  124. statusMap: any = {
  125. 1: '已申请待审核',
  126. 2: '已审核待退货',
  127. 3: '已退货待确认',
  128. 5: '已审核待退款',
  129. 6: '售后成功',
  130. 7: '售后失败'
  131. };
  132. typeMap: any = {
  133. 2: '仅退款',
  134. 3: '退货退款'
  135. };
  136. statusMap2: any = {
  137. 1: '未收货',
  138. 2: '已收货'
  139. };
  140. returnInfo: any = {};
  141. histories: any = [];
  142. onLoad() {
  143. // this.from = this.$Route.query.from;
  144. // this.getShareInfo();
  145. // this.getDetail();
  146. }
  147. onShow() {
  148. if (this.$Route.query.id) {
  149. this.getDetail();
  150. }
  151. }
  152. updateData() {
  153. this.getDetail();
  154. }
  155. getDetail(): void {
  156. let id = this.$Route.query.id;
  157. if (!id) return;
  158. // 获取订单详情
  159. this.$http
  160. .get({
  161. url: this.$api.getAfterSaleDetail,
  162. data: {
  163. id: id
  164. }
  165. })
  166. .then((res: any) => {
  167. this.detail = res;
  168. // 以下变量均为app层级太深无法渲染创建
  169. this.info = res.afterSale;
  170. this.payment = +res.afterSale.payment;
  171. this.skuList = res.skuList;
  172. this.oid = res.afterSale.oid;
  173. this.returnInfo = res.returnInfo;
  174. this.infoStatus = res.afterSale.status;
  175. this.histories = res.histories.map((item: any) => {
  176. return {
  177. ...item,
  178. title: item.content,
  179. desc: item.created
  180. }
  181. });
  182. })
  183. .catch((err: any) => {
  184. console.log(err);
  185. });
  186. }
  187. tologistics(): void {
  188. this.$Router.push({
  189. path: '/packages/order/logistics',
  190. query: {
  191. oid: this.oid
  192. }
  193. });
  194. }
  195. cancelAfterSaleModal() {
  196. (this.$refs.cancelOrder as any).open();
  197. }
  198. cancelAfterSale() {
  199. this.$http
  200. .put({
  201. url: this.$api.cancelAfterSale,
  202. data: {
  203. id: this.info.id
  204. }
  205. })
  206. .then((res: any) => {
  207. uni.hideLoading();
  208. this.$Router.pushTab({
  209. path: '/pages/order/order-list',
  210. });
  211. uni.showToast({
  212. title: "已撤销售后",
  213. icon: 'none'
  214. })
  215. }, (err: any) => {
  216. uni.hideLoading();
  217. console.log(err);
  218. });
  219. }
  220. toDeliverGoods() {
  221. this.$Router.push({
  222. path: '/packages/order/deliver-goods',
  223. query: {
  224. id: this.info.id
  225. }
  226. })
  227. }
  228. }
  229. </script>
  230. <style lang="scss" scoped>
  231. .word14 {
  232. @include word-vw(14, $gray3);
  233. }
  234. .word12 {
  235. @include word-vw(12);
  236. }
  237. .word12-gray9 {
  238. @include word-vw(12, $gray9);
  239. }
  240. .container {
  241. width: 100vw;
  242. padding-bottom: vw(100);
  243. background: #F8F8F8;
  244. }
  245. .address {
  246. width: 100%;
  247. background-color: white;
  248. padding: $cell-padding;
  249. box-sizing: border-box;
  250. display: flex;
  251. flex-wrap: wrap;
  252. align-content: space-between;
  253. .icon {
  254. @include icon(16, $gray9);
  255. }
  256. .address-detail {
  257. width: vw(310);
  258. display: flex;
  259. flex-wrap: wrap;
  260. align-content: space-between;
  261. margin-left: 10px;
  262. .area {
  263. width: vw(310);
  264. margin-top: vw(8);
  265. }
  266. .name {
  267. width: vw(200);
  268. }
  269. }
  270. }
  271. .logistics {
  272. width: 100%;
  273. background-color: white;
  274. padding: $cell-padding;
  275. box-sizing: border-box;
  276. display: flex;
  277. justify-content: space-between;
  278. flex-flow: row;
  279. flex-wrap: wrap;
  280. align-content: space-between;
  281. margin: 10px 0;
  282. .icon {
  283. @include icon(16, $gray9);
  284. margin-top: 3px;
  285. }
  286. .right {
  287. @include icon(12, $gray9);
  288. align-self: center;
  289. }
  290. .logistics-detail {
  291. width: vw(280);
  292. display: flex;
  293. flex-wrap: wrap;
  294. align-content: flex-start;
  295. .time {
  296. width: vw(280);
  297. margin-top: vw(8);
  298. }
  299. .title {
  300. width: vw(280);
  301. line-height: 1.5;
  302. }
  303. }
  304. }
  305. .remark {
  306. margin-top: 1px;
  307. width: 100vw;
  308. background-color: white;
  309. @include word-vw(14);
  310. padding: vw(15);
  311. box-sizing: border-box;
  312. }
  313. .head {
  314. width: 100vw;
  315. height: vw(90);
  316. @include flex-y(center, flex-start);
  317. background: #333333;
  318. padding: $cell-padding;
  319. box-sizing: border-box;
  320. color: #fff;
  321. font-size: vw(12);
  322. .status {
  323. font-size: vw(18);
  324. margin-bottom: vw(5);
  325. font-weight: 600;
  326. }
  327. }
  328. .address-info {
  329. width: 100%;
  330. padding: vw(10) vw(15);
  331. box-sizing: border-box;
  332. @include word-vw(14, #666);
  333. line-height: vw(20);
  334. background: #fff;
  335. .name {
  336. margin-right: vw(12);
  337. }
  338. view {
  339. margin-top: vw(8);
  340. }
  341. }
  342. .order-wrap {
  343. width: 100vw;
  344. display: flex;
  345. margin-top: vw(10);
  346. flex-wrap: wrap;
  347. align-content: space-between;
  348. background: white;
  349. padding-top: vw(10);
  350. .oid {
  351. flex: 1;
  352. padding: vw(15);
  353. box-sizing: border-box;
  354. @include word-vw(12);
  355. }
  356. .time {
  357. flex: 1;
  358. padding: vw(15);
  359. box-sizing: border-box;
  360. text-align: right;
  361. }
  362. .total-detail {
  363. width: 100%;
  364. padding: vw(6) vw(15);
  365. box-sizing: border-box;
  366. border-top: vw(1) solid #F5F5F5;
  367. border-bottom: vw(1) solid #F5F5F5;
  368. line-height: vw(27);
  369. .top {
  370. @include word-vw(14, #333);
  371. @include flex-x();
  372. }
  373. .bottom {
  374. @include word-vw(14, #999);
  375. @include flex-x();
  376. }
  377. }
  378. .total {
  379. width: 100%;
  380. height: vw(50);
  381. text-align: right;
  382. padding: 0 vw(15);
  383. box-sizing: border-box;
  384. @include flex-x(flex-end);
  385. background: #fff;
  386. @include word-vw(14, #999);
  387. text {
  388. @include word-vw(16, #333);
  389. }
  390. }
  391. }
  392. .row {
  393. height: vw(40);
  394. @include flex-x();
  395. background: #fff;
  396. @include word-vw(14, #333);
  397. padding: 0 vw(15);
  398. margin-top: vw(10);
  399. }
  400. .row2 {
  401. margin-top: vw(1);
  402. }
  403. .remark {
  404. @include word-vw(14, #333);
  405. padding: vw(10) vw(15);
  406. margin-top: vw(1);
  407. line-height: vw(20);
  408. }
  409. .oid {
  410. height: vw(36);
  411. @include flex-x();
  412. background: #fff;
  413. margin-top: vw(10);
  414. padding: 0 vw(15);
  415. box-sizing: border-box;
  416. @include word-vw(14, #999);
  417. }
  418. .detail {
  419. margin-top: 10px;
  420. @include flex-x();
  421. flex-wrap: wrap;
  422. align-content: space-between;
  423. width: 100vw;
  424. padding: vw(10) vw(15);
  425. box-sizing: border-box;
  426. background-color: white;
  427. line-height: 2;
  428. .half {
  429. width: vw(250);
  430. text-align: right;
  431. }
  432. }
  433. .conchat {
  434. @include flex-x();
  435. @include word-vw(14, #333);
  436. height: vw(50);
  437. background: #fff;
  438. margin-top: vw(10);
  439. padding: 0 vw(15);
  440. .icon {
  441. margin-right: vw(10);
  442. }
  443. &::after {
  444. border: none;
  445. }
  446. }
  447. .steps-box{
  448. background: #fff;
  449. margin-top: vw(10);
  450. }
  451. .btn-box {
  452. height: vw(56);
  453. @include flex-x(flex-end);
  454. width: 100%;
  455. padding: 0 vw(15);
  456. box-sizing: border-box;
  457. background: #fff;
  458. position: fixed;
  459. bottom: 0;
  460. .btn {
  461. height: vw(30);
  462. width: vw(90);
  463. line-height: vw(30);
  464. @include word-vw(12, #fff);
  465. background: $btn-color;
  466. border-radius: vw(15);
  467. margin-left: vw(10);
  468. text-align: center;
  469. box-sizing: border-box;
  470. }
  471. .btn2 {
  472. color: #333;
  473. border: vw(1) solid #BF2071;
  474. background: #FFEBF1;
  475. }
  476. }
  477. .bottom-btn {
  478. height: vw(60);
  479. width: 100%;
  480. background: #fff;
  481. @include flex-x(center);
  482. position: fixed;
  483. bottom: 0;
  484. left: 0;
  485. .solid-btn {
  486. background: $bk-color;
  487. @include solid-btn(345, 48, #333);
  488. border-radius: vw(24);
  489. @include word-vw(14, #fff);
  490. }
  491. }
  492. .select-pay-type {
  493. background: #FAFAFA;
  494. border-top-right-radius: vw(34);
  495. border-top-left-radius: vw(34);
  496. overflow: hidden;
  497. padding: vw(20) vw(10);
  498. box-sizing: border-box;
  499. @include flex-y();
  500. .title {
  501. @include word-vw(18, #333);
  502. font-weight: bold;
  503. }
  504. .time-tip {
  505. @include word-vw(10, #999);
  506. margin-top: vw(5);
  507. }
  508. .amount {
  509. @include word-vw(40, #000);
  510. font-weight: 450;
  511. margin-top: vw(20);
  512. }
  513. .price {
  514. @include word-vw(14, #999);
  515. margin-top: vw(3);
  516. }
  517. .pay-item-box {
  518. border-radius: vw(10);
  519. overflow: hidden;
  520. width: 100%;
  521. margin-top: vw(36);
  522. }
  523. .pay-item {
  524. background: #fff;
  525. // margin-bottom: vw(10);
  526. height: vw(70);
  527. line-height: vw(70);
  528. padding: 0 vw(18);
  529. // border-radius: vw(10);
  530. @include word-vw(16, #333);
  531. @include flex-x();
  532. overflow: hidden;
  533. margin-bottom: vw(1);
  534. .item-left {
  535. @include flex-x(flex-start);
  536. }
  537. .icon {
  538. margin-right: vw(10);
  539. }
  540. .item-right {
  541. .icon {
  542. margin: 0;
  543. }
  544. }
  545. }
  546. .popup-btn-box {
  547. width: 100%;
  548. @include flex-x();
  549. margin-top: vw(20);
  550. .btn {
  551. font-weight: bold;
  552. border-radius: vw(24);
  553. height: vw(48);
  554. @include flex-x(center);
  555. }
  556. .cancel-btn {
  557. width: vw(127);
  558. background: #fff;
  559. @include word-vw(16, $btn-color);
  560. }
  561. .confirm-btn {
  562. width: vw(355);
  563. background: $btn-color;
  564. @include word-vw(16, #fff);
  565. }
  566. }
  567. }
  568. </style>