detail_sales_orderDetail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <template>
  2. <div id="form-1">
  3. <el-row>
  4. <el-col
  5. :span="24"
  6. class="main animate__animated animate__backInRight"
  7. v-loading="loadings"
  8. element-loading-text="拼命加载中"
  9. element-loading-spinner="el-icon-loading"
  10. >
  11. <el-col class="top-btn">
  12. <el-button type="primary" size="mini" @click="toBack()">返回</el-button>
  13. </el-col>
  14. <el-col :span="9" class="one">
  15. <el-col :span="24" class="add">
  16. <el-col :span="2">
  17. <i class="el-icon-location"></i>
  18. </el-col>
  19. <el-col :span="22">
  20. <el-col>
  21. <p>{{ address.name }},{{ address.phone }}</p>
  22. </el-col>
  23. <el-col>
  24. <p>{{ address.province }} , {{ address.city }} , {{ address.area }} , {{ address.address }}</p>
  25. </el-col>
  26. </el-col>
  27. </el-col>
  28. <el-col :span="24" class="shop"> <i class="el-icon-s-shop"></i>{{ shop.name }}</el-col>
  29. <el-col :span="24" v-for="(item, index) in list" :key="index">
  30. <el-col :span="24" class="goods bode">
  31. <el-col :span="6"><el-image :src="item.goods.file[0].url"></el-image></el-col>
  32. <el-col :span="18">
  33. <el-col :span="12">
  34. <el-col>
  35. <p>{{ item.goods.name }}</p>
  36. </el-col>
  37. <el-col>
  38. <p>规格:{{ item.name }}</p>
  39. </el-col>
  40. </el-col>
  41. <el-col :span="12" class="money">
  42. <el-col>
  43. <p v-if="info.type == '0'">¥{{ item.sell_money }}</p>
  44. <p v-else-if="info.type == '1'">¥{{ item.group_config.money }}</p>
  45. </el-col>
  46. <el-col>
  47. <p>X{{ item.buy_num }}</p>
  48. </el-col>
  49. <el-col>
  50. <span class="spanfour" style="color: blue" @click="toUrl(item.goods.url)"> 查看商品来源:{{ item.goods.source }}</span>
  51. </el-col>
  52. <el-col>
  53. <p>{{ item.is_afterSale == true ? '已申请售后' : '未申请售后' }}</p>
  54. </el-col>
  55. <el-col>
  56. <p>{{ item.is_rate == true ? '已评价' : '未评价' }}</p>
  57. </el-col>
  58. </el-col>
  59. </el-col>
  60. </el-col>
  61. <el-col :span="24" class="bode">
  62. <el-col :span="6">运费</el-col>
  63. <el-col :span="18" class="other" v-if="!item.goods.freight == '0'">{{ item.goods.freight }}</el-col>
  64. <el-col :span="18" class="other" v-else>包邮</el-col>
  65. </el-col>
  66. </el-col>
  67. <el-col :span="24" class="bode">
  68. <el-col :span="6">订单备注</el-col>
  69. <el-col :span="18" class="other" v-if="info.remarks">{{ info.remarks }}</el-col>
  70. <el-col :span="18" class="other" v-else>暂无备注</el-col>
  71. </el-col>
  72. <el-col :span="24" class="bode">
  73. <el-col :span="6">配送方式</el-col>
  74. <el-col :span="18" class="other">快递配送</el-col>
  75. </el-col>
  76. <el-col :span="24" class="goods_total bode">
  77. <el-col :span="6">快递费</el-col>
  78. <el-col :span="18" class="other">
  79. <p>¥{{ total_detail.freight_total }}</p>
  80. </el-col>
  81. </el-col>
  82. <el-col :span="24" class="goods_total bode">
  83. <el-col :span="8">优惠后实付金额</el-col>
  84. <el-col :span="16" class="other">
  85. <p>¥{{ pay.pay_money }}</p>
  86. </el-col>
  87. </el-col>
  88. <el-col :span="24" class="bode">
  89. <el-col :span="6">下单时间</el-col>
  90. <el-col :span="18" class="other">{{ info.buy_time }}</el-col>
  91. </el-col>
  92. <el-col :span="24" class="bode">
  93. <el-col :span="6">支付时间</el-col>
  94. <el-col :span="18" class="other">{{ info.pay_time }}</el-col>
  95. </el-col>
  96. <el-col :span="24" class="bode" v-if="info.status == '3'">
  97. <el-col :span="6">寄出运单号</el-col>
  98. <el-col :span="18" class="other">{{ transport.shop_transport_no || '暂无单号' }}</el-col>
  99. </el-col>
  100. <el-col :span="24" class="bode" v-if="info.status == '3'">
  101. <el-col :span="6">寄出快递公司</el-col>
  102. <el-col :span="18" class="other">{{ transport.shop_transport_name || '暂无快递信息' }}</el-col>
  103. </el-col>
  104. </el-col>
  105. <el-col :span="9" class="one">
  106. <el-button type="danger" @click="toSales('1')" v-if="this.status == '1'"> 取消订单 </el-button>
  107. <el-button type="danger" @click="toSales('2')" v-if="this.status == '2' || this.status == '2-'"> 拒收 </el-button>
  108. <el-col v-if="this.status == '3'">
  109. <el-form :model="form" :rules="rules" ref="form" label-width="180px">
  110. <el-col :span="24">
  111. <el-form-item label="售后商品" prop="goods">
  112. <el-select v-model="form.goods" clearable filterable placeholder="请选择售后商品" size="small" style="width: 100%" @change="goodsChange">
  113. <el-option v-for="i in list" :key="i.goods.name" :label="i.goods.name" :value="i.id"> </el-option>
  114. </el-select>
  115. </el-form-item>
  116. </el-col>
  117. <el-col :span="24">
  118. <el-form-item label="售后类型" prop="type">
  119. <el-select v-model="form.type" clearable filterable placeholder="请选择售后类型" size="small" style="width: 100%" @change="typeChange">
  120. <el-option v-for="i in typeList" :key="i.value" :label="i.label" :value="i.value"> </el-option>
  121. </el-select>
  122. </el-form-item>
  123. </el-col>
  124. <el-col :span="24" v-if="this.form.type == '1' || this.form.type == '2'">
  125. <el-form-item label="退款金额" prop="money">
  126. <el-input v-model="form.money" placeholder="请输入退款金额" size="small" type="Number" @input="toMoney"></el-input>
  127. <p>
  128. 退款金额不得超过<span style="color: red">{{ payMoney.payTotal || '' }}</span
  129. >元
  130. <span @click="allMoney" style="color: blue; margin: 0 0 0 10px">全部退款</span>
  131. </p>
  132. </el-form-item>
  133. </el-col>
  134. <el-col :span="24">
  135. <el-form-item label="申请理由" prop="reason">
  136. <el-select v-model="form.reason" clearable filterable placeholder="请选择申请理由" size="small" style="width: 100%">
  137. <el-option v-for="i in reasonList" :key="i.value" :label="i.label" :value="i.value"> </el-option>
  138. </el-select>
  139. </el-form-item>
  140. </el-col>
  141. <el-col :span="24">
  142. <el-form-item label="售后描述" prop="desc">
  143. <el-input v-model="form.desc" placeholder="请输入售后描述" size="small" type="textarea"></el-input>
  144. </el-form-item>
  145. </el-col>
  146. <el-col :span="24">
  147. <el-form-item label="附件" prop="file">
  148. <c-upload :url="url" v-model="form.file" :limit="6"></c-upload>
  149. </el-form-item>
  150. </el-col>
  151. <el-col :span="24" class="btn">
  152. <el-button type="primary" size="mini" @click="onSubmit('form')">提交</el-button>
  153. <el-button type="danger" size="mini" @click="toBack()">取消</el-button>
  154. </el-col>
  155. </el-form>
  156. </el-col>
  157. </el-col>
  158. </el-col>
  159. </el-row>
  160. </div>
  161. </template>
  162. <script>
  163. const _ = require('lodash');
  164. const moment = require('moment');
  165. import { mapState, mapGetters, createNamespacedHelpers } from 'vuex';
  166. const { mapActions: orderDetail } = createNamespacedHelpers('orderDetail');
  167. const { mapActions } = createNamespacedHelpers('afterSale');
  168. const { mapActions: dictData } = createNamespacedHelpers('dictData');
  169. const { mapActions: sot } = createNamespacedHelpers('sot');
  170. export default {
  171. name: 'form-1',
  172. props: { id: { type: String }, status: { type: String } },
  173. components: { cUpload: () => import('@/components/usual/c-upload.vue') },
  174. data: function () {
  175. return {
  176. info: {},
  177. // 地址
  178. address: {},
  179. // 实付金额
  180. total_detail: {},
  181. // 商铺
  182. shop: {},
  183. // 运单号
  184. transport: {},
  185. pay: {},
  186. // 商品列表
  187. list: [],
  188. // 物流
  189. reverse: false,
  190. activities: [],
  191. activit: {},
  192. // 订单状态
  193. order_processList: [],
  194. // 快递公司
  195. shop_transport_typeList: [],
  196. loading: false,
  197. rules: {
  198. goods: [{ required: true, message: '请选择商品', trigger: 'change' }],
  199. type: [{ required: true, message: '请选择售后类型', trigger: 'change' }],
  200. money: [{ required: true, message: '请输入金额', trigger: 'blur' }],
  201. },
  202. // 售后表单
  203. form: {},
  204. // 售后类型
  205. typeList: [],
  206. // 售后申请理由
  207. reasonList: [],
  208. // 退款金额
  209. payMoney: {},
  210. url: '/files/point/afterSale/upload',
  211. loadings: true,
  212. };
  213. },
  214. async created() {
  215. await this.searchOther();
  216. await this.search();
  217. },
  218. methods: {
  219. ...dictData({ dictQuery: 'query' }),
  220. ...orderDetail({ orderFetch: 'fetch' }),
  221. ...sot({ sotFetch: 'fetch' }),
  222. ...mapActions(['query', 'cgfr', 'fetch', 'create', 'update']),
  223. // 查询
  224. async search() {
  225. let res;
  226. res = await this.orderFetch(this.id);
  227. if (this.$checkRes(res)) {
  228. this.$set(this, `info`, res.data);
  229. // 地址
  230. this.$set(this, `address`, res.data.address);
  231. this.$set(this, `shop`, res.data.shop);
  232. // 商品
  233. this.$set(this, `list`, res.data.goods);
  234. // 应付金额
  235. this.$set(this, `total_detail`, res.data.total_detail);
  236. this.$set(this, `pay`, res.data.order.pay);
  237. }
  238. this.loadings = false;
  239. },
  240. toUrl(url) {
  241. if (url) {
  242. window.open(url, '_blank');
  243. } else {
  244. this.$message.error('该商品还未添加来源网址,无法跳转');
  245. }
  246. },
  247. handleSelect(value) {},
  248. async toSales(status) {
  249. if (status == '1') {
  250. var info = { order_detail: this.id, type: '4' };
  251. } else if (status == '2') {
  252. var info = { order_detail: this.id, type: '5' };
  253. }
  254. this.$confirm('是否确认申请售后', '提示', {
  255. confirmButtonText: '确定',
  256. cancelButtonText: '取消',
  257. type: 'warning',
  258. }).then(async () => {
  259. let res = await this.create(info);
  260. if (this.$checkRes(res)) {
  261. this.$message({ type: `success`, message: `申请售后成功` });
  262. this.search();
  263. }
  264. });
  265. },
  266. // 选择商品
  267. goodsChange(value) {
  268. this.$set(this.form, `goods`, value);
  269. this.typeChange(this.form.type || '');
  270. },
  271. // 选择类型
  272. async typeChange(value) {
  273. this.$set(this.form, `type`, value);
  274. if (value != '3') {
  275. let info = {
  276. order_detail: this.id,
  277. goods_id: this.form.goods,
  278. };
  279. let res = await this.cgfr(info);
  280. if (this.$checkRes(res)) {
  281. this.$set(this, `payMoney`, res.data);
  282. this.allMoney();
  283. }
  284. }
  285. },
  286. // 全部退款
  287. allMoney() {
  288. this.$set(this.form, `money`, this.payMoney.payTotal);
  289. },
  290. // 输入金额
  291. toMoney(val) {
  292. if (val > this.payMoney.payTotal) {
  293. this.$message.error('超过退款最大金额');
  294. this.$set(this.form, `money`, '');
  295. }
  296. },
  297. // 提交
  298. async onSubmit(formName, val) {
  299. this.$refs[formName].validate(async (valid) => {
  300. if (valid) {
  301. this.$confirm('是否确认保存', '提示', {
  302. confirmButtonText: '确定',
  303. cancelButtonText: '取消',
  304. type: 'warning',
  305. }).then(async () => {
  306. let form = this.form;
  307. form.order_detail = this.id;
  308. let res = await this.create(form);
  309. if (this.$checkRes(res)) {
  310. this.$message({ type: `success`, message: `申请售后成功` });
  311. this.search();
  312. }
  313. });
  314. } else {
  315. return false;
  316. }
  317. });
  318. },
  319. // 返回
  320. toBack() {
  321. this.$emit('toBack');
  322. },
  323. // 查询其他信息
  324. async searchOther() {
  325. let res;
  326. // 减免方式
  327. res = await this.dictQuery({ code: 'order_process' });
  328. if (this.$checkRes(res)) this.$set(this, `order_processList`, res.data);
  329. // 售后类型
  330. res = await this.dictQuery({ code: 'afterSale_type' });
  331. if (this.$checkRes(res)) {
  332. let type = res.data.filter((i) => i.value != '4' && i.value != '5');
  333. this.$set(this, `typeList`, type);
  334. }
  335. // 售后申请理由
  336. res = await this.dictQuery({ code: 'afterSale_reason' });
  337. if (this.$checkRes(res)) {
  338. let type = res.data.filter((i) => i.value != '4' && i.value != '5');
  339. this.$set(this, `reasonList`, res.data);
  340. }
  341. },
  342. },
  343. computed: {},
  344. metaform() {
  345. return { title: this.$route.meta.title };
  346. },
  347. watch: {
  348. test: {
  349. deep: true,
  350. immediate: true,
  351. handler(val) {},
  352. },
  353. },
  354. };
  355. </script>
  356. <style lang="less" scoped>
  357. .main {
  358. .one {
  359. margin: 10px 0 0 5%;
  360. padding: 5px;
  361. .add {
  362. border-bottom: 2px dashed #ccc;
  363. margin: 0 0 5px 0;
  364. padding: 5px 0;
  365. }
  366. .shop {
  367. padding: 4px 0;
  368. font-size: 18px;
  369. border-bottom: 1px solid #ccc;
  370. }
  371. .goods {
  372. padding: 10px 0;
  373. .money {
  374. text-align: right;
  375. }
  376. }
  377. .other {
  378. text-align: right;
  379. word-break: break-all;
  380. p {
  381. color: red;
  382. }
  383. .spanfour {
  384. color: blue;
  385. }
  386. }
  387. .el-col {
  388. margin: 3px 0;
  389. }
  390. .bode {
  391. border-bottom: 1px solid rgb(238, 237, 237);
  392. }
  393. .form {
  394. margin: 20px 0 0 0;
  395. }
  396. }
  397. }
  398. .btn {
  399. text-align: center;
  400. }
  401. /deep/.el-timeline {
  402. margin: 20px 0 0 0;
  403. font-size: 16px;
  404. }
  405. /deep/.el-timeline-item__node:nth-child(1) {
  406. background-color: green;
  407. }
  408. </style>