index.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <div id="app" v-cloak>
  2. <el-card shadow="never" style="border:0;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  3. <div slot="header">
  4. <div>
  5. <span>售后订单列表</span>
  6. </div>
  7. </div>
  8. <div class="table-body">
  9. <el-form :inline="true" v-model="searchData" class="demo-form-inline" label-width="100px">
  10. <el-row :gutter="24">
  11. <el-form-item label="商品名称">
  12. <el-input size="small" v-model="searchData.name"></el-input>
  13. </el-form-item>
  14. <el-form-item label="售后单号">
  15. <el-input size="small" v-model="searchData.order_no"></el-input>
  16. </el-form-item>
  17. <el-form-item label="订单编号">
  18. <el-input size="small" v-model="searchData.shop_order_no"></el-input>
  19. </el-form-item>
  20. <el-form-item label="售后时间">
  21. <el-date-picker
  22. size="small"
  23. v-model="searchData.data"
  24. type="datetimerange"
  25. range-separator="至"
  26. start-placeholder="开始日期"
  27. end-placeholder="结束日期"
  28. value-format="yyyy-MM-dd HH:mm:ss"
  29. >
  30. </el-date-picker>
  31. </el-form-item>
  32. <el-form-item label="售后状态">
  33. <el-select size="small" v-model="searchData.refund_status">
  34. <el-option v-for="(name, key) in refund_status_list" :key="key" :value="key" :label="name"></el-option>
  35. </el-select>
  36. </el-form-item>
  37. </el-row>
  38. <el-row :gutter="24">
  39. <el-form-item label=" ">
  40. <el-button size="small" type="primary" @click="onSearch">查询</el-button>
  41. <el-button size="small" type="primary" @click="onReset">重置</el-button>
  42. </el-form-item>
  43. </el-row>
  44. </el-form>
  45. </div>
  46. <div class="table-body">
  47. <el-table class="table-info" ref="multipleTable" stripe :data="list" v-loading="listLoading">
  48. <!-- 空数据 -->
  49. <template slot="empty">
  50. <el-empty description="暂无订单"></el-empty>
  51. </template>
  52. <el-table-column type="selection"></el-table-column>
  53. <el-table-column prop="order_no" align="center" label="售后单号">
  54. <template slot-scope="scope">
  55. <a href="javascript:void(0);" @click="mallOrder(scope.row.refund.id)">
  56. {{ scope.row.refund.order_no }}
  57. </a>
  58. </template>
  59. </el-table-column>
  60. <el-table-column prop="order_no" align="center" label="订单编号">
  61. <template slot-scope="scope">
  62. <a href="javascript:void(0);" @click="mallOrderDetail(scope.row.order_id)">
  63. {{ scope.row.order_no }}
  64. </a>
  65. </template>
  66. </el-table-column>
  67. <el-table-column prop="goods" align="center" width="200px" label="商品">
  68. <template slot-scope="scope">
  69. <div class="goods">
  70. <div class="goods-img">
  71. <el-image :src="scope.row.detail.pic_url" fit="fill" style="width: 60px; height: 60px"></el-image>
  72. </div>
  73. <div class="goods-name">
  74. <span>{{ sub(scope.row.detail.goods_name) }}</span>
  75. </div>
  76. </div>
  77. </template>
  78. </el-table-column>
  79. <el-table-column prop="attr" align="center" label="商品属性">
  80. <template slot-scope="scope">
  81. {{ scope.row.detail.goods_attr_name }}
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="price" label="实际支付" align="center">
  85. <template slot-scope="scope">
  86. {{ scope.row.order.goods_price }}
  87. +
  88. {{ scope.row.order.shipping_money }}
  89. </template>
  90. </el-table-column>
  91. <el-table-column prop="price" label="申请退款" align="center">
  92. <template slot-scope="scope">
  93. <div>
  94. <div>
  95. {{ scope.row.refund.refund_price }}
  96. </div>
  97. </div>
  98. </template>
  99. </el-table-column>
  100. <el-table-column prop="price" label="推送状态" align="center">
  101. <template slot-scope="scope">
  102. {{ scope.row.status_text }}
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="售后状态" align="center">
  106. <template slot-scope="scope">
  107. <el-tag size="small" effect="plain" :type="scope.row.refund.refund_status == 1 ? 'success' : 'danger'">{{ refund_status_list[scope.row.refund.refund_status] }}</el-tag>
  108. </template>
  109. </el-table-column>
  110. <el-table-column prop="error_msg" label="错误信息" align="center">
  111. <template slot-scope="scope">
  112. {{ scope.row.error_msg }}
  113. </template>
  114. </el-table-column>
  115. <el-table-column align="center" label="操作">
  116. <template slot-scope="scope">
  117. <el-button type="text" @click="showDetail(scope.row)">售后管理</el-button>
  118. </template>
  119. </el-table-column>
  120. </el-table>
  121. <!-- 分页 -->
  122. <el-row type="flex" class="page" justify="end">
  123. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount" v-if="list"></el-pagination>
  124. </el-row>
  125. </div>
  126. <!-- 订单详情 -->
  127. <el-dialog title="订单详情" :visible.sync="dialogVisible" width="50%" @close="onCloseDialogVisible">
  128. <el-descriptions class="margin-top" title="" :column="2" border v-if="refund" v-loading="reqLoading">
  129. <el-descriptions-item>
  130. <template slot="label">
  131. 售后订单编号
  132. </template>
  133. {{ refund.order_no }}
  134. </el-descriptions-item>
  135. <el-descriptions-item>
  136. <template slot="label">
  137. 售后类型
  138. </template>
  139. {{ refund.type_text }}
  140. </el-descriptions-item>
  141. <el-descriptions-item>
  142. <template slot="label">
  143. 售后原因
  144. </template>
  145. {{ refund.reason }}
  146. </el-descriptions-item>
  147. <el-descriptions-item>
  148. <template slot="label">
  149. 售后金额
  150. </template>
  151. {{ refund.refund_price }}
  152. </el-descriptions-item>
  153. <el-descriptions-item span="2" v-if="chain_refund_sn">
  154. <template slot="label">
  155. 供应链端售后订单号
  156. </template>
  157. {{ chain_refund_sn }}
  158. </el-descriptions-item>
  159. <el-descriptions-item span="2">
  160. <template slot="label">
  161. 售后备注
  162. </template>
  163. {{ refund.remark }}
  164. </el-descriptions-item>
  165. <el-descriptions-item span="2">
  166. <template slot="label">
  167. 售后凭证
  168. </template>
  169. <el-image :src="item" v-for="item in refund.pic_list" :preview-src-list="refund.pic_list" style="height:80px;margin-right:5px"></el-image>
  170. </el-descriptions-item>
  171. <!-- 部分退款 -->
  172. <template v-if="thirdOrder">
  173. <el-descriptions-item span="2">
  174. <template slot="label">
  175. 中台最多可退
  176. </template>
  177. {{ thirdOrder.amount }}
  178. </el-descriptions-item>
  179. <el-descriptions-item span="2">
  180. <template slot="label">
  181. 申请退款金额*
  182. </template>
  183. <el-input :disabled="status != 0 || refund_status != 0" v-model="third_refund_amount" placeholder="请输入中台退款金额"></el-input>
  184. </el-descriptions-item>
  185. </template>
  186. </el-descriptions>
  187. <span slot="footer" class="dialog-footer" v-if="status == 0 && refund_status == 0">
  188. <el-button type="warning" @click="reject">驳回售后</el-button>
  189. <el-button type="primary" @click="agree">推送售后</el-button>
  190. </span>
  191. </el-dialog>
  192. </el-card>
  193. </div>
  194. <script>
  195. const app = new Vue({
  196. el: '#app',
  197. data() {
  198. return {
  199. searchData: {
  200. name: '',
  201. order_no: '',
  202. data: '',
  203. refund_status: ''
  204. },
  205. refund: {},
  206. listLoading: false,
  207. removeLoading: false,
  208. list: [],
  209. removeImportBtn: false,
  210. pageCount: 0,
  211. page: 1,
  212. dialogVisible: false,
  213. refund_status: 0,
  214. status: 0,
  215. chain_refund_sn: '',
  216. id: null,
  217. thirdOrder: null,
  218. third_refund_amount: '',
  219. reqLoading: false,
  220. refund_way: null,
  221. refund_status_list: {}
  222. };
  223. },
  224. methods: {
  225. /**
  226. * 获取商品库
  227. */
  228. getOrderList() {
  229. this.listLoading = true
  230. request({
  231. params: {
  232. r: 'qi-juhe/refund/index',
  233. page: this.page,
  234. },
  235. method: 'post',
  236. data: this.searchData,
  237. }).then(e => {
  238. if (e.data.code === 0) {
  239. this.list = e.data.data.list
  240. this.pageCount = e.data.data.page_count
  241. this.refund_status_list = e.data.data.refund_status_list;
  242. } else {
  243. this.$message.error(e.data.msg);
  244. }
  245. this.listLoading = false
  246. }).
  247. catch(e => {
  248. console.log(e);
  249. })
  250. },
  251. /**
  252. * 分页
  253. */
  254. pagination(currentPage) {
  255. this.page = currentPage
  256. this.getOrderList()
  257. },
  258. /**
  259. * 字符串裁剪
  260. */
  261. sub(string) {
  262. string = string + ''
  263. var reg = /[\u4e00-\u9fa5]/g, //专业匹配中文
  264. slice = string.substring(0, 15),
  265. chineseCharNum = (~~(slice.match(reg) && slice.match(reg).length)),
  266. realen = slice.length * 2 - chineseCharNum;
  267. return string.substr(0, realen) + (realen < string.length ? "..." : "");
  268. },
  269. /**
  270. * 跳转到商城商品
  271. */
  272. mallOrder(id) {
  273. this.$navigate({
  274. r: 'mall/order/refund-detail',
  275. id: id
  276. })
  277. },
  278. /**
  279. * 跳转到订单详情
  280. */
  281. mallOrderDetail(id) {
  282. this.$navigate({
  283. r: 'mall/order/detail',
  284. id: id
  285. })
  286. },
  287. /**
  288. * 搜索
  289. */
  290. onSearch() {
  291. this.page = 1
  292. this.getOrderList()
  293. },
  294. /**
  295. * 重置
  296. */
  297. onReset() {
  298. this.searchData = {
  299. name: '',
  300. order_no: '',
  301. receiver_name: '',
  302. refund_status: ''
  303. }
  304. },
  305. /**
  306. * 展示订单详情
  307. */
  308. showDetail(row) {
  309. this.id = row.id
  310. this.refund = row.refund
  311. this.chain_refund_sn = row.chain_refund_sn
  312. this.status = row.status
  313. this.refund_status = row.refund_status
  314. this.dialogVisible = true
  315. this.refund_way = row.data.refund_way
  316. if (row.data.refund_way == 0) {
  317. this.reqLoading = true
  318. request({
  319. params: {
  320. r: 'qi-juhe/order/third-order-detail',
  321. order_no: row.order_no,
  322. refund_id: row.order_refund_id
  323. },
  324. method: 'get',
  325. }).then(e => {
  326. if (e.data.code === 0) {
  327. this.reqLoading = false
  328. this.thirdOrder = e.data.data
  329. if (row.data.amount != parseInt(row.data.apply_amount * 100)) {
  330. this.third_refund_amount = parseFloat(row.data.amount * 0.01).toFixed(2)
  331. }
  332. } else {
  333. this.$message.error(e.data.msg);
  334. }
  335. this.listLoading = false
  336. }).
  337. catch(e => {
  338. console.log(e);
  339. this.$message.error('网络错误');
  340. })
  341. }
  342. },
  343. /**
  344. * 同意申请
  345. */
  346. agree() {
  347. // 判断是否设置金额
  348. if (this.refund_way == 0 && this.third_refund_amount == '') {
  349. this.$message.error('申请退款金额不能为空');
  350. return
  351. }
  352. this.$confirm('确认操作吗?').then(() => {
  353. request({
  354. params: {
  355. r: 'qi-juhe/refund/agree',
  356. },
  357. method: 'post',
  358. data: {
  359. id: this.id,
  360. amount: this.third_refund_amount,
  361. refund_way: this.refund_way
  362. },
  363. }).then(e => {
  364. if (e.data.code === 0) {
  365. this.$message.success('操作成功');
  366. let self = this
  367. setTimeout(() => {
  368. self.thirdOrder = null
  369. self.refund_way = null
  370. self.third_refund_amount = ''
  371. self.dialogVisible = false
  372. self.getOrderList()
  373. }, 1500);
  374. } else {
  375. this.$message.error(e.data.msg);
  376. }
  377. this.listLoading = false
  378. }).
  379. catch(e => {
  380. console.log(e);
  381. })
  382. }).catch(_ => {})
  383. },
  384. /**
  385. * 驳回申请
  386. */
  387. reject() {
  388. this.$confirm('确认操作吗?').then(() => {
  389. request({
  390. params: {
  391. r: 'qi-juhe/refund/reject',
  392. },
  393. method: 'post',
  394. data: {
  395. id: this.id
  396. },
  397. }).then(e => {
  398. if (e.data.code === 0) {
  399. this.$message.success('操作成功');
  400. let self = this
  401. setTimeout(() => {
  402. self.thirdOrder = null
  403. self.third_refund_amount = ''
  404. self.dialogVisible = false
  405. self.getOrderList()
  406. }, 1500);
  407. } else {
  408. this.$message.error(e.data.msg);
  409. }
  410. this.listLoading = false
  411. }).
  412. catch(e => {
  413. console.log(e);
  414. })
  415. }).catch(_ => {})
  416. },
  417. onCloseDialogVisible() {
  418. this.thirdOrder = null
  419. this.third_refund_amount = ''
  420. }
  421. },
  422. mounted: function() {
  423. this.page = getQuery('page') ? getQuery('page') : 1
  424. this.getOrderList()
  425. }
  426. })
  427. </script>
  428. <style>
  429. .goods {
  430. display: flex;
  431. }
  432. .goods-name {
  433. margin-left: 5px;
  434. }
  435. .page {
  436. margin-top: 10px;
  437. }
  438. </style>