refund.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <template>
  2. <view>
  3. <view class="header" v-if="order.refund_status != ''">
  4. <view class="left">{{order.refund_status_text}}</view>
  5. </view>
  6. <view class="product">
  7. <view class="goods-for" v-for="(goodsItem, goodsIndex) in order.products" :key="goodsIndex" @click="check(goodsIndex)">
  8. <view class="goods-box-single">
  9. <image class="goods-img" :src="goodsItem.image" mode="aspectFill"></image>
  10. <view class="right">
  11. <text class="title clamp">{{goodsItem.title}}</text>
  12. <text class="attr-box">{{goodsItem.spec}} x {{goodsItem.number}}</text>
  13. <text class="price">{{goodsItem.price}}</text>
  14. </view>
  15. <view class="yticon icon-xuanzhong checkbox" :class="{checked: goodsItem.choose}"></view>
  16. </view>
  17. </view>
  18. </view>
  19. <view class="yt-list-cell" v-if=" (order.refund_status && order.refund_status == 2) || (order.refund && order.refund.express_number)">
  20. <view class="cell-tit clamp">快递编号
  21. <input style="max-width: 350rpx;" class="input" type="text" v-model="expressNumber" placeholder="请填写快递编号" placeholder-class="placeholder" />
  22. </view>
  23. <button type="warn" @click="confirmDelivery" v-if="order.refund_status == 2">确认发货</button>
  24. </view>
  25. <view class="yt-list-cell">
  26. <view class="cell-tit clamp">货物状态</view>
  27. <view class="cell-tip">
  28. <picker :disabled="order.status == 1 ? false : true" @change="receivingStatusChange" range-key="name" :value="receivingStatusIndex" :range="receivingStatus">
  29. <view class="uni-input">{{receivingStatus[receivingStatusIndex].name}}</view>
  30. </picker>
  31. <text class="yticon icon-you"></text>
  32. </view>
  33. </view>
  34. <view class="yt-list-cell">
  35. <view class="cell-tit clamp">服务类型</view>
  36. <view class="cell-tip">
  37. <picker :disabled="order.status == 1 ? false : true" @change="typeChange" range-key="name" :value="serviceTypeIndex" :range="serviceType">
  38. <view class="uni-input">{{serviceType[serviceTypeIndex].name}}</view>
  39. </picker>
  40. <text class="yticon icon-you"></text>
  41. </view>
  42. </view>
  43. <view class="yt-list-cell" v-if="order.total_price > 0 && (serviceTypeIndex == 0 || serviceTypeIndex == 1)">
  44. <view class="cell-tit clamp">退款金额: <text style="color: #ed6b00;">¥ {{order.total_price}}</text>
  45. <input :disabled="order.status == 1 ? false : true" type="digit" v-model="amount" :placeholder="'最多 ¥'+order.total_price + ', 含发货邮费 ¥'+ order.delivery_price" placeholder-class="placeholder" />
  46. </view>
  47. </view>
  48. <view class="yt-list-cell">
  49. <view class="cell-tit clamp">换货原因</view>
  50. <view class="cell-tip">
  51. <picker :disabled="order.status == 1 ? false : true" @change="reasonTypeChange" range-key="name" :value="reasonTypeIndex" :range="reasonType">
  52. <view class="uni-input">{{reasonType[reasonTypeIndex].name}}</view>
  53. </picker>
  54. <text class="yticon icon-you"></text>
  55. </view>
  56. </view>
  57. <view class="yt-list-cell">
  58. <view class="cell-tit clamp">换货说明
  59. <input :disabled="order.status == 1 ? false : true" class="input" type="text" v-model="refundExplain" placeholder="选填" placeholder-class="placeholder" />
  60. </view>
  61. </view>
  62. <button v-if="order.status == 1" class="button" @click="submit" type="warn">提交</button>
  63. </view>
  64. </template>
  65. <script>
  66. import uniRate from '@/components/uni-rate/uni-rate.vue'
  67. export default {
  68. computed: {
  69. orderProductIds(){
  70. var order_product_id = [];
  71. this.order.products.forEach(item=>{
  72. if (item.choose == 1) {
  73. order_product_id.push(item.order_product_id);
  74. }
  75. });
  76. return order_product_id.join(',');
  77. },
  78. status() {
  79. if (this.order.have_refunded == 0) {
  80. return '申请中';
  81. } else {
  82. return '已退货'
  83. }
  84. }
  85. },
  86. components: {
  87. uniRate
  88. },
  89. data() {
  90. return {
  91. order_id: 0,
  92. order: {},
  93. amount: '',
  94. serviceType:[{
  95. 'value': 0,
  96. 'name': '我要退款(无需退货)'
  97. },
  98. {
  99. 'value': 1,
  100. 'name': '我要退货退款'
  101. },
  102. {
  103. 'value': 2,
  104. 'name': '换货'
  105. },
  106. {
  107. 'value': 3,
  108. 'name':'请选择'
  109. }
  110. ],
  111. serviceTypeIndex:3,
  112. receivingStatus: [{
  113. 'value': 0,
  114. 'name': '未收到'
  115. },
  116. {
  117. 'value': 1,
  118. 'name': '已收到'
  119. },
  120. {
  121. 'value': 2,
  122. 'name': '请选择'
  123. }
  124. ],
  125. receivingStatusIndex: 2,
  126. reasonType: [{
  127. 'name': '其他'
  128. },
  129. {
  130. 'name': '拍错/不喜欢/效果不好'
  131. },
  132. {
  133. 'name': '质量与商品描述不符'
  134. },
  135. {
  136. 'name': '版本/批次/颜色/容量等与商品描述不符'
  137. },
  138. {
  139. 'name': '发错货'
  140. },
  141. {
  142. 'name': '假冒品牌'
  143. }
  144. ],
  145. reasonTypeIndex: 0,
  146. refundExplain: '',
  147. expressNumber: ''
  148. }
  149. },
  150. onPullDownRefresh() {
  151. this.refundInfo();
  152. },
  153. onLoad(options) {
  154. this.order_id = options.order_id;
  155. this.refundInfo();
  156. },
  157. methods: {
  158. async refundInfo() {
  159. let data = await this.$api.request('/order/refundInfo', 'POST', {
  160. order_id: this.order_id
  161. });
  162. uni.stopPullDownRefresh();
  163. if (data) {
  164. this.order = data;
  165. if (data.status == -1) { // 状态为退款
  166. let refund = data.refund;
  167. this.amount = refund.amount;
  168. let that = this;
  169. this.reasonType.filter(function(item, index){
  170. if (item.name == refund.reason_type) {
  171. that.reasonTypeIndex = index;
  172. }
  173. })
  174. this.receivingStatusIndex = refund.receiving_status;
  175. this.refundExplain = refund.refund_explain;
  176. this.serviceTypeIndex = refund.service_type;
  177. this.expressNumber = refund.express_number;
  178. }
  179. }
  180. },
  181. async submit(){
  182. if (this.receivingStatusIndex == 2) {
  183. this.$api.msg('请选择货物状态');
  184. return;
  185. }
  186. if ((this.serviceTypeIndex == 0 || this.serviceTypeIndex == 1) && parseFloat(this.order.total_price) > 0) {
  187. if (!this.amount) {
  188. this.$api.msg('请填写退货金额');
  189. return;
  190. }
  191. if (parseFloat(this.amount) > parseFloat(this.order.total_price)) {
  192. this.$api.msg('退款金额不得大于订单金额');
  193. return;
  194. }
  195. }
  196. if (this.serviceTypeIndex == 3) {
  197. this.$api.msg('请选择服务类型')
  198. return;
  199. }
  200. let data = await this.$api.request('/order/refund', 'POST', {
  201. order_id: this.order_id,
  202. amount: this.amount ? parseFloat(this.amount) : 0,
  203. service_type: this.serviceType[this.serviceTypeIndex].value,
  204. receiving_status: this.receivingStatus[this.receivingStatusIndex].value,
  205. reason_type: this.reasonType[this.reasonTypeIndex].name,
  206. refund_explain: this.refundExplain,
  207. order_product_id: this.orderProductIds
  208. });
  209. if (data) {
  210. this.refundInfo();
  211. }
  212. },
  213. // 更改商品状态
  214. receivingStatusChange(e) {
  215. this.receivingStatusIndex = e.detail.value;
  216. },
  217. // 更改换货原因
  218. reasonTypeChange(e) {
  219. this.reasonTypeIndex = e.detail.value;
  220. },
  221. // 选择服务类型
  222. typeChange(e) {
  223. this.serviceTypeIndex = e.detail.value;
  224. },
  225. // 选商品
  226. check(index) {
  227. this.order.products[index].choose = this.order.products[index].choose ? 0 : 1;
  228. },
  229. // 确认发货
  230. async confirmDelivery(){
  231. if (this.expressNumber == '') {
  232. this.$api.msg('请添加物流单号');
  233. return;
  234. }
  235. let data = await this.$api.request('/order/refundDelivery', 'POST', {order_id: this.order_id, express_number:this.expressNumber});
  236. if (data) {
  237. this.refundInfo();
  238. }
  239. }
  240. }
  241. }
  242. </script>
  243. <style lang="scss">
  244. page {
  245. background: #f5f5f5;
  246. }
  247. .header {
  248. height: 200rpx;
  249. background: linear-gradient(to right, #ffac30, #fa436a, #F56C6C);
  250. .left {
  251. color: #ffffff;
  252. line-height: 200rpx;
  253. padding-left: 100rpx;
  254. }
  255. }
  256. .product {
  257. background: #ffffff;
  258. margin-top: 20rpx;
  259. padding: 30rpx;
  260. .goods-for{
  261. border-bottom: 1rpx solid #eaeaea;
  262. }
  263. /* 单条商品 */
  264. .goods-box-single {
  265. display: flex;
  266. padding: 20upx 0;
  267. position: relative;
  268. .goods-img {
  269. display: block;
  270. width: 120upx;
  271. height: 120upx;
  272. }
  273. .right {
  274. flex: 1;
  275. display: flex;
  276. flex-direction: column;
  277. padding: 0 30upx 0 24upx;
  278. overflow: hidden;
  279. position: relative;
  280. .title {
  281. font-size: $font-base + 2upx;
  282. color: $font-color-dark;
  283. line-height: 1;
  284. }
  285. .attr-box {
  286. font-size: $font-sm + 2upx;
  287. color: $font-color-light;
  288. padding: 10upx 12upx;
  289. }
  290. .price {
  291. font-size: $font-base + 2upx;
  292. color: $font-color-dark;
  293. margin-top: 0;
  294. &:before {
  295. content: '¥';
  296. font-size: $font-sm;
  297. margin: 0 2upx 0 8upx;
  298. }
  299. }
  300. .action-btn {
  301. width: 160rpx;
  302. height: 60rpx;
  303. padding: 0;
  304. text-align: center;
  305. line-height: 60rpx;
  306. font-size: 26rpx;
  307. color: #303133;
  308. background: #fff;
  309. border-radius: 100px;
  310. float: right;
  311. position: absolute;
  312. right: 0;
  313. bottom: 0;
  314. }
  315. }
  316. .checkbox {
  317. position: absolute;
  318. left: -16upx;
  319. top: -16upx;
  320. z-index: 8;
  321. font-size: 44upx;
  322. line-height: 1;
  323. padding: 4upx;
  324. color: $font-color-disabled;
  325. background: #fff;
  326. border-radius: 50px;
  327. }
  328. .checkbox.checked {
  329. color: $uni-color-primary;
  330. }
  331. }
  332. }
  333. .yt-list-cell {
  334. margin-top: 16upx;
  335. background: #fff;
  336. display: flex;
  337. align-items: center;
  338. padding: 10upx 30upx 10upx;
  339. line-height: 70upx;
  340. position: relative;
  341. .cell-tit {
  342. flex: 1;
  343. font-size: 26rpx;
  344. color: #000000;
  345. margin-right: 10rpx;
  346. .input {
  347. display: inline-block;
  348. vertical-align: middle;
  349. line-height: 26rpx;
  350. margin-left: 20rpx;
  351. width: 550rpx;
  352. }
  353. }
  354. .cell-tip {
  355. font-size: 26rpx;
  356. color: $font-color-dark;
  357. picker {
  358. display: inline-block;
  359. width: 500rpx;
  360. text-align: right;
  361. padding-right: 20rpx;
  362. color: $font-color-light;
  363. }
  364. .yticon {
  365. font-size: 26rpx;
  366. }
  367. }
  368. }
  369. .button{
  370. margin: 20rpx;
  371. }
  372. </style>