多租户商城-客户PC端
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.

695 lines
22 KiB

2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="orderDetail">
  3. <div class="content">
  4. <div class="head">
  5. <router-link to="/orderAfterSale">
  6. <div class="mar-right-10">售后订单</div>
  7. </router-link>
  8. <div class='arrow'></div>
  9. <div class="mar-right-10" v-if="state==='2'">售后详情</div>
  10. <div class="mar-right-10" v-if="state==='1'">申请售后</div>
  11. </div>
  12. <div class="orderTitle">
  13. <p class="fs16 fw-blod" v-if="state==='2'">售后编号{{orderData.afterFormid}}</p>
  14. <p class="fs16 fw-blod" v-if="state==='1'">订单号{{orderData.orderFormid}}</p>
  15. </div>
  16. <div class="status">
  17. <div class="top">
  18. <div class="state text-align">
  19. <p class="fs30 fw-blod" v-if="state==='1'">申请售后</p>
  20. <p class="fs24 fw-blod" v-if="orderData.afterState===1">审核中</p>
  21. <p class="fs24 fw-blod" v-if="orderData.afterState===2">退款中</p>
  22. <p class="fs24 fw-blod" v-if="orderData.afterState===3">退货中</p>
  23. <p class="fs24 fw-blod font-color-71B" v-if="orderData.afterState===4">退款成功</p>
  24. <p class="fs24 fw-blod" v-if="orderData.afterState===5">退款失败<br><span class="font-color-999">(如有问题请联系商家)</span></p>
  25. <p class="fs24 fw-blod" v-if="orderData.afterState===6">审核不通过</p>
  26. <p class="fs16 fw-blod" v-if="orderData.afterState===6">拒绝理由{{orderData.reason}}</p>
  27. <p class="fs24 fw-blod" v-if="orderData.afterState===7">评审中</p>
  28. <p class="fs24 fw-blod font-color-999" v-if="orderData.afterState===8">退货完成拒绝退款</p>
  29. <p class="fs24 fw-blod font-color-999" v-if="orderData.afterState===9">已关闭</p>
  30. <p class="fs24 fw-blod" v-if="orderData.afterState===10">审核通过</p>
  31. <el-button plain v-if="orderData.afterState===6 || orderData.afterState===8"
  32. class="intervention mar-top-10" type="info" @click="platform">
  33. 申请平台介入
  34. </el-button>
  35. <el-button plain v-if="(orderData.afterState===1 && orderData.afterType===1)
  36. || (orderData.afterState===6 && orderData.afterType===1)
  37. || (orderData.afterState===10 && orderData.afterType===1)"
  38. class="intervention mar-top-10" type="info" @click="returnRefund">
  39. 撤销申请
  40. </el-button>
  41. <el-button plain v-if="orderData.afterState===1 && orderData.afterType===2
  42. || orderData.afterState===6 && orderData.afterType===2"
  43. class="intervention mar-top-10" type="info" @click="returnGoods">
  44. 撤销退货
  45. </el-button>
  46. </div>
  47. </div>
  48. <div class="bottom">
  49. <AfterSaleState v-if="state==='1'" :state="''"></AfterSaleState>
  50. <AfterSaleState v-else :state="orderData.afterState"></AfterSaleState>
  51. </div>
  52. </div>
  53. <div class="desc">
  54. <div class="storeInfo">
  55. <p class="title">卖家信息</p>
  56. <div class="info">
  57. <p>店铺名称{{orderData.shopName}}</p>
  58. <p>联系电话{{orderData.chargePersonPhone || orderData.shopPhone}}</p>
  59. </div>
  60. </div>
  61. <div class="orderInfo">
  62. <p class="title">订单信息</p>
  63. <div class="info">
  64. <p>订单号{{orderData.orderFormid}}</p>
  65. <p>支付渠道{{orderData.paymentMode}}</p>
  66. <p>交易号{{orderData.transactionId}}</p>
  67. <p>创建时间{{orderData.createTime}}</p>
  68. <p>付款时间{{orderData.paymentTime}}</p>
  69. <p v-if="orderData.receiveTime">成交时间{{orderData.receiveTime}}</p>
  70. </div>
  71. </div>
  72. <div class="productInfo">
  73. <div class="top">
  74. <p class="big"><span>宝贝</span></p>
  75. <p>宝贝属性</p>
  76. <p>状态</p>
  77. <p>数量</p>
  78. <p>单价</p>
  79. </div>
  80. <div class="bottom" v-for="(pro, idx) in orderData.skus" :key="idx">
  81. <div class="big">
  82. <img :src="pro.image" alt="">
  83. <p>{{pro.productName}}</p>
  84. </div>
  85. <div style="flex-direction: column;">
  86. <p v-for="(text, ins) in pro.values" :key="ins">{{text}}</p>
  87. </div>
  88. <div v-if="orderData.state==1 || orderData.orderState==1">待付款</div>
  89. <div v-if="orderData.state==2 || orderData.orderState==2">待发货</div>
  90. <div v-if="orderData.state==3 || orderData.orderState==3">待收货</div>
  91. <div v-if="orderData.state==4 || orderData.orderState==4">已完成</div>
  92. <div v-if="orderData.state==5 || orderData.orderState==5">已关闭</div>
  93. <div>{{pro.number}}</div>
  94. <div class="fs-bold" style="color: #C83732;">¥{{pro.price}}</div>
  95. </div>
  96. </div>
  97. <div class="returnPrice" v-if="orderData.afterState===4">
  98. <div>
  99. <span class="mar-right-40">退款金额</span>
  100. <span style="color: #C83732;">¥{{orderData.price}}</span>
  101. </div>
  102. </div>
  103. <div class="apply" v-if="state==='1'">
  104. <div class="submitAS">
  105. <div class="itemBox">
  106. <div class="title">售后方式</div>
  107. <el-select
  108. v-model="mode"
  109. placeholder="请选择售后方式"
  110. style="width:500px;"
  111. >
  112. <el-option
  113. v-for="item in modes"
  114. :key="item.value"
  115. :label="item.label"
  116. :value="item.value">
  117. </el-option>
  118. </el-select>
  119. </div>
  120. <div class="itemBox">
  121. <div class="title">货物状态</div>
  122. <el-select
  123. v-model="goodsState"
  124. placeholder="请选择货物状态"
  125. style="width:500px;"
  126. >
  127. <el-option
  128. v-for="item in goodsStatus"
  129. :key="item.value"
  130. :label="item.label"
  131. :value="item.value">
  132. </el-option>
  133. </el-select>
  134. </div>
  135. <div class="itemBox">
  136. <div class="title">售后理由</div>
  137. <el-select
  138. v-model="reason"
  139. placeholder="请选择售后理由"
  140. style="width:500px;"
  141. >
  142. <el-option
  143. v-for="item in reasons"
  144. :key="item"
  145. :label="item"
  146. :value="item">
  147. </el-option>
  148. </el-select>
  149. </div>
  150. <div class="itemBox reason">
  151. <div class="title">原因描述</div>
  152. <el-input
  153. type="textarea"
  154. :rows="6"
  155. placeholder="输入申请退货原因描述"
  156. v-model="textarea"
  157. style="width:500px;">
  158. </el-input>
  159. </div>
  160. <div class="itemBox upload">
  161. <div class="title">上传凭证</div>
  162. <el-upload
  163. :action="action"
  164. list-type="picture-card"
  165. :limit="3"
  166. :on-success="handleSuccess"
  167. :on-remove="handleRemove">
  168. <i class="el-icon-camera"></i>
  169. <span
  170. style="
  171. display: block;
  172. height: 0px;
  173. line-height: 0px;
  174. margin-top: -30px;
  175. ">最多上传3张</span>
  176. </el-upload>
  177. </div>
  178. <div class="submit">
  179. <el-button plain @click="submit" v-throttle>提交申请</el-button>
  180. </div>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. </template>
  187. <script>
  188. import AfterSaleState from '@/components/base/afterSaleState'
  189. import {
  190. upload
  191. } from '@/api/upload.js'
  192. import {
  193. getOrderDetail
  194. } from '@/api/user/order.js'
  195. import {
  196. submitAfter,
  197. getAfterSaleDetail,
  198. returnRefund,
  199. returnGoods,
  200. getReasons,
  201. requestPlatform
  202. } from '@/api/user/afterSale.js'
  203. export default {
  204. components: {
  205. AfterSaleState
  206. },
  207. data () {
  208. return {
  209. state: 0,
  210. orderData: {},
  211. modes: [{
  212. value: 1,
  213. label: '仅退款'
  214. }, {
  215. value: 2,
  216. label: '退货退款'
  217. }],
  218. reasons: [],
  219. goodsStatus: [{
  220. value: 1,
  221. label: '已收到货'
  222. }, {
  223. value: 0,
  224. label: '未收到货'
  225. }],
  226. exp: '',
  227. mode: '',
  228. reason: '',
  229. goodsState: '',
  230. textarea: '',
  231. textarea1: '',
  232. text: '',
  233. dialogImageUrl: '',
  234. dialogVisible: false,
  235. disabled: false,
  236. skus: [],
  237. productPrice: 0,
  238. urls: [],
  239. orderId: '',
  240. afterId: '',
  241. afterSaleDetail: {},
  242. action: upload,
  243. image: []
  244. }
  245. },
  246. created () {
  247. this.state = this.$route.query.state
  248. if (this.$route.query.state === '2') {
  249. this.orderId = this.$route.query.orderId
  250. this.afterId = this.$route.query.afterId
  251. }
  252. },
  253. mounted () {
  254. if (this.state === '1') {
  255. this.getReasonSelect()
  256. this.getOrderDetail()
  257. } else if (this.state === '2' || this.state === '3') {
  258. this.getASDetail()
  259. // this.getExpressSelect()
  260. }
  261. },
  262. methods: {
  263. // 获取订单详情
  264. async getOrderDetail () {
  265. const rLoading = this.openLoading()
  266. const response = await getOrderDetail({
  267. orderId: JSON.parse(this.$route.query.orderData).orderId
  268. })
  269. const res = response.data
  270. if (res.code === '200') {
  271. this.orderData = res.data
  272. this.orderData.skus = JSON.parse(this.$route.query.orderData).skus
  273. } else {
  274. this.$message.warning(res.message)
  275. }
  276. rLoading.close()
  277. },
  278. // 获取售后订单详情
  279. async getASDetail () {
  280. const rLoading = this.openLoading()
  281. const response = await getAfterSaleDetail({
  282. afterId: this.afterId,
  283. orderId: this.orderId
  284. })
  285. const res = response.data
  286. if (res.code === '200') {
  287. this.orderData = res.data
  288. this.image = res.data.image.split(',')
  289. } else {
  290. this.$message.warning(res.message)
  291. }
  292. rLoading.close()
  293. },
  294. // 撤销申请
  295. async returnRefund () {
  296. const response = await returnRefund({
  297. afterId: this.orderData.afterId,
  298. orderId: this.orderData.orderId
  299. })
  300. const res = response.data
  301. if (res.code === '200') {
  302. this.$message.success('撤销申请成功')
  303. this.getASDetail()
  304. } else {
  305. this.$message.warning(res.message)
  306. }
  307. },
  308. // 撤销退货
  309. async returnGoods () {
  310. const response = await returnGoods({
  311. afterId: this.orderData.afterId,
  312. orderId: this.orderData.orderId
  313. })
  314. const res = response.data
  315. if (res.code === '200') {
  316. this.$message.success('撤销退货成功')
  317. this.getASDetail()
  318. } else {
  319. this.$message.warning(res.message)
  320. }
  321. },
  322. // 申请平台介入
  323. async platform () {
  324. const response = await requestPlatform({
  325. afterId: this.orderData.afterId,
  326. orderId: this.orderData.orderId,
  327. image: '',
  328. reason: ''
  329. })
  330. const res = response.data
  331. if (res.code === '200') {
  332. this.$message.success('申请平台介入成功')
  333. this.getASDetail()
  334. } else {
  335. this.$message(res.message)
  336. }
  337. },
  338. // 选择退款原因查询
  339. async getReasonSelect () {
  340. const response = await getReasons()
  341. const res = response.data
  342. if (res.code === '200') {
  343. this.reasons = res.data
  344. } else {
  345. this.$message.warning(res.message)
  346. }
  347. },
  348. // 申请售后
  349. async submit () {
  350. let errMsg = ''
  351. if (this.mode === '') {
  352. errMsg += ' 请选择售后方式 '
  353. }
  354. if (this.goodsState === '') {
  355. errMsg += ' 请选择货物状态 '
  356. }
  357. if (this.reason === '') {
  358. errMsg += ' 请选择售后理由 '
  359. }
  360. if (errMsg.length !== 0) {
  361. this.$message.warning(errMsg)
  362. return
  363. }
  364. this.productPrice = 0
  365. for (var i in this.orderData.skus) {
  366. this.skus[i] = {
  367. number: this.orderData.skus[i].number,
  368. skuId: this.orderData.skus[i].skuId
  369. }
  370. this.productPrice += this.orderData.skus[i].actualPrice
  371. if (parseInt(this.goodsState) === 0) {
  372. this.productPrice += this.orderData.skus[i].logisticsPrice
  373. }
  374. }
  375. const response = await submitAfter({
  376. afterType: this.mode,
  377. explain: this.textarea,
  378. goodsState: this.goodsState,
  379. image: this.urls.join(','),
  380. orderId: this.orderData.orderId,
  381. price: this.productPrice.toFixed(2),
  382. returnReason: this.reason,
  383. isAllSelect: 1,
  384. skus: this.skus
  385. })
  386. const res = response.data
  387. if (res.code === '200') {
  388. this.$message.success({
  389. message: '售后申请成功',
  390. type: 'success'
  391. })
  392. setTimeout(() => {
  393. this.$router.push('/orderAfterSale')
  394. }, 1000)
  395. } else {
  396. this.$message.warning(res.message)
  397. }
  398. },
  399. handleSuccess (res) {
  400. this.urls.push(res.data.url)
  401. },
  402. handleRemove (file, fileList) {
  403. this.urls = []
  404. for (var i in fileList) {
  405. this.urls.push(fileList[i].response.data.url)
  406. }
  407. }
  408. }
  409. }
  410. </script>
  411. <style lang="scss">
  412. .orderDetail{
  413. width: 100%;
  414. .content{
  415. width: 1250px;
  416. margin: 0 auto;
  417. .head {
  418. width: 100%;
  419. height: 50px;
  420. line-height: 50px;
  421. font-size: 16px;
  422. display: flex;
  423. align-items: center;
  424. .arrow {
  425. background-image: url('../../../static/image/xiangyou@2x.png');
  426. width: 5px;
  427. height: 10px;
  428. margin-right: 10px;
  429. }
  430. }
  431. .orderTitle{
  432. width: 100%;
  433. max-width: 1250px;
  434. height: 80px;
  435. margin: 20px 0;
  436. padding: 0 30px;
  437. font-size: 16px;
  438. font-family: Microsoft YaHei;
  439. color: #333333;
  440. background: #FAFAFA;
  441. display: flex;
  442. align-items: center;
  443. }
  444. .status{
  445. width: 100%;
  446. height: 325px;
  447. border: 1px solid #E5E5E5;
  448. box-sizing: border-box;
  449. padding: 15px;
  450. display: flex;
  451. flex-direction: column;
  452. margin-bottom: 20px;
  453. .top{
  454. flex: 1;
  455. display: flex;
  456. align-items: center;
  457. flex-direction: column;
  458. position: relative;
  459. color: $mainGlod;
  460. .state{
  461. position: absolute;
  462. top: 50%;
  463. left: 50%;
  464. transform: translate(-50%,-50%);
  465. }
  466. .cancel{
  467. width: 100px;
  468. }
  469. .intervention{
  470. border-color: $mainGlod;
  471. color: $mainGlod;
  472. margin-left: 0;
  473. }
  474. .intervention:hover{
  475. background-color: rgba($color: $mainGlod, $alpha: 0.3);
  476. }
  477. .box{
  478. display: flex;
  479. flex-direction: column;
  480. justify-content: center;
  481. }
  482. }
  483. .bottom{
  484. flex: 3;
  485. // padding: 20px;
  486. box-sizing: border-box;
  487. }
  488. }
  489. .desc{
  490. width: 100%;
  491. border: 1px solid #E5E5E5;
  492. margin-bottom: 140px;
  493. .storeInfo,.orderInfo{
  494. padding: 25px;
  495. border-bottom: 1px solid #E5E5E5;
  496. .title{
  497. font-size: 16px;
  498. margin-bottom: 25px;
  499. }
  500. .info{
  501. display: flex;
  502. margin-left: 75px;
  503. flex-wrap: wrap;
  504. p{
  505. line-height: 30px;
  506. width: 50%;
  507. font-size: 14px;
  508. margin-bottom: 10px;
  509. }
  510. .long{
  511. width: 100%;
  512. }
  513. .pic{
  514. margin-top: 10px;
  515. width: 100%;
  516. font-size: 14px;
  517. span{
  518. vertical-align: top;
  519. margin-right: 10px;
  520. }
  521. .el-image{
  522. img{
  523. margin-right: 10px;
  524. }
  525. }
  526. }
  527. }
  528. }
  529. .orderInfo{
  530. .info{
  531. p{
  532. width: 33.33%;
  533. }
  534. }
  535. }
  536. .productInfo{
  537. width: 100%;
  538. .top{
  539. height: 40px;
  540. width: 100%;
  541. color: #FFF;
  542. background-color: #333;
  543. display: flex;
  544. align-items: center;
  545. text-align: center;
  546. p{
  547. flex: 1;
  548. font-size: 12px;
  549. }
  550. .big{
  551. flex: 2;
  552. text-align: left;
  553. span{
  554. margin-left: 20px;
  555. }
  556. }
  557. }
  558. .bottom{
  559. width: 100%;
  560. padding: 20px 0;
  561. box-sizing: border-box;
  562. text-align: center;
  563. display: flex;
  564. border-bottom: 1px solid #E5E5E5;
  565. div{
  566. flex: 1;
  567. font-size: 14px;
  568. display: flex;
  569. align-items: center;
  570. justify-content: center;
  571. p{
  572. font-size: 14px;
  573. line-height: 20px;
  574. }
  575. }
  576. .big{
  577. text-align: left;
  578. flex: 2;
  579. display: flex;
  580. box-sizing: border-box;
  581. justify-content: flex-start;
  582. align-items: center;
  583. img{
  584. width: 80px;
  585. height: 80px;
  586. margin: 0 20px;
  587. }
  588. p{
  589. width: 50%;
  590. }
  591. }
  592. }
  593. }
  594. .settlement{
  595. width: 100%;
  596. display: flex;
  597. padding: 25px;
  598. box-sizing: border-box;
  599. justify-content: flex-end;
  600. .box{
  601. display: flex;
  602. .left{
  603. text-align: right;
  604. p{
  605. width: 250px;
  606. display: flex;
  607. justify-content: space-between;
  608. font-size: 20px;
  609. color: #666666;
  610. line-height: 30px;
  611. }
  612. .right{
  613. text-align: right;
  614. margin-left: 40px;
  615. }
  616. }
  617. }
  618. }
  619. .returnPrice{
  620. width: 100%;
  621. padding: 50px 50px;
  622. font-size: 20px;
  623. box-sizing: border-box;
  624. text-align: right;
  625. border-bottom: 1px solid #E5E5E5;
  626. }
  627. .apply{
  628. width: 100%;
  629. padding: 25px;
  630. box-sizing: border-box;
  631. .submitAS{
  632. display: flex;
  633. flex-direction: column;
  634. justify-content: center;
  635. align-items: center;
  636. position: relative;
  637. .itemBox{
  638. width: 580px;
  639. display: flex;
  640. margin: 10px;
  641. .title{
  642. min-width: 80px;
  643. line-height: 40px;
  644. text-align: right;
  645. }
  646. >>> .el-input__icon{
  647. color: $mainGlod;
  648. }
  649. }
  650. .reason{
  651. position: relative;
  652. }
  653. .upload{
  654. display: flex;
  655. .title{
  656. line-height: 40px;
  657. }
  658. >>> .el-upload--picture-card{
  659. height: 140px;
  660. background-color: #FFF;
  661. display: flex;
  662. flex-direction: column;
  663. justify-content: center;
  664. align-items: center;
  665. i{
  666. font-size: 32px;
  667. }
  668. &:hover{
  669. i{
  670. color: $mainGlod;
  671. }
  672. }
  673. }
  674. }
  675. .submit{
  676. margin: 30px 0;
  677. .el-button{
  678. width: 200px;
  679. height: 50px;
  680. color: #FFF;
  681. background-color: #333333;
  682. border-radius: 0px;
  683. }
  684. }
  685. >>> .el-select-dropdown__item{
  686. &:hover{
  687. background: $mainGlod;
  688. }
  689. }
  690. }
  691. }
  692. }
  693. }
  694. }
  695. </style>