createRefundDialog.vue 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716
  1. <template>
  2. <div class="dialog_container" v-loading.fullscreen.lock="detailLoading">
  3. <div class="head"></div>
  4. <div>
  5. <div class="filter-container">
  6. <el-input
  7. :placeholder="$t('place.onlineShopNumber')"
  8. clearable
  9. style="width: 200px;"
  10. class="filter-item"
  11. v-model="listQuery.ormorder"
  12. @change="validateParams"
  13. />
  14. <el-input
  15. :placeholder="$t('place.shopifyNumber')"
  16. clearable
  17. style="width: 200px;"
  18. class="filter-item"
  19. v-model="listQuery.shopify"
  20. @change="validateParams"
  21. />
  22. <el-select
  23. :placeholder="$t('place.afterSalesType')"
  24. clearable
  25. style="width: 200px;"
  26. class="filter-item"
  27. v-model="listQuery.refundType"
  28. @change="validateParams"
  29. >
  30. <el-option
  31. v-for="afterSaleType in afterSaleTypes"
  32. :key="afterSaleType.value"
  33. :label="$t(afterSaleType.label)"
  34. :value="afterSaleType.value"
  35. >
  36. </el-option>
  37. </el-select>
  38. <el-button
  39. v-waves
  40. class="filter-item"
  41. type="success"
  42. icon="el-icon-search"
  43. @click="getDetail(null)"
  44. >{{ $t("view.search") }}</el-button
  45. >
  46. </div>
  47. </div>
  48. <div class="main" v-if="show">
  49. <div class="box" style="margin-top: 15px;">
  50. <div class="item_title">{{ $t("view.shippingInfo") }}</div>
  51. <div class="ptitle">
  52. <template>
  53. <el-descriptions
  54. class="margin-top"
  55. :title="$t('title.addressInfo')"
  56. :column="4"
  57. direction="horizontal"
  58. v-if="addressInfo.length == 1"
  59. >
  60. <el-descriptions-item :label="$t('country')">{{
  61. addressInfo[0].receiverCountryCode
  62. }}</el-descriptions-item>
  63. <el-descriptions-item :label="$t('label.postalCode')">{{
  64. addressInfo[0].receiverZip
  65. }}</el-descriptions-item>
  66. <el-descriptions-item :label="$t('state')">{{
  67. addressInfo[0].receiverState
  68. }}</el-descriptions-item>
  69. <el-descriptions-item :label="$t('city')">{{
  70. addressInfo[0].receiverCity
  71. }}</el-descriptions-item>
  72. <el-descriptions-item :label="$t('suburb')">{{
  73. addressInfo[0].receiverDistrict
  74. }}</el-descriptions-item>
  75. <el-descriptions-item :label="$t('street')">{{
  76. addressInfo[0].receiverStreet
  77. }}</el-descriptions-item>
  78. <el-descriptions-item :label="$t('address')">{{
  79. addressInfo[0].receiverAddress
  80. }}</el-descriptions-item>
  81. <el-descriptions-item :label="$t('dooeNo')">{{
  82. addressInfo[0].receiverAddress2
  83. }}</el-descriptions-item>
  84. <el-descriptions-item :label="$t('recipient')">{{
  85. addressInfo[0].receiverName
  86. }}</el-descriptions-item>
  87. <el-descriptions-item :label="$t('telephone')">{{
  88. addressInfo[0].receiverPhone
  89. }}</el-descriptions-item>
  90. <el-descriptions-item :label="$t('moPhone')">{{
  91. addressInfo[0].receiverMobile
  92. }}</el-descriptions-item>
  93. <el-descriptions-item :label="$t('post')">{{
  94. addressInfo[0].email
  95. }}</el-descriptions-item>
  96. <el-descriptions-item :label="$t('label.shippingFee')">{{
  97. addressInfo[0].freight
  98. }}</el-descriptions-item>
  99. </el-descriptions>
  100. <div class="container" width="500px" v-if="addressInfo.length > 1">
  101. <div
  102. v-for="(item, index) in addressInfo"
  103. :key="index"
  104. width="100px"
  105. margin-right="50px"
  106. >
  107. <el-popover
  108. placement="top"
  109. :title="$t('title.addressInfo')"
  110. width="300"
  111. offset="300"
  112. trigger="hover"
  113. >
  114. <el-descriptions
  115. class="margin-top"
  116. title=""
  117. :column="1"
  118. direction="horizontal"
  119. >
  120. <el-descriptions-item :label="$t('country')">{{
  121. item.receiverCountryCode
  122. }}</el-descriptions-item>
  123. <el-descriptions-item :label="$t('address')">{{
  124. item.receiverAddress
  125. }}</el-descriptions-item>
  126. <el-descriptions-item :label="$t('recipient')">{{
  127. item.receiverName
  128. }}</el-descriptions-item>
  129. <el-descriptions-item :label="$t('post')">{{
  130. item.email
  131. }}</el-descriptions-item>
  132. <el-descriptions-item :label="$t('label.shippingFee')">{{
  133. item.freight
  134. }}</el-descriptions-item>
  135. </el-descriptions>
  136. <el-button
  137. slot="reference"
  138. @click="chooseClick(item.idList)"
  139. >{{ item.receiverCountryCode }}</el-button
  140. >
  141. </el-popover>
  142. </div>
  143. </div>
  144. <!-- <el-descriptions class="margin-top" :title="'地址信息-' + (index + 1)" :column="4" direction="horizontal" v-for="(item, index) in addressInfo" :key="index"> -->
  145. <!-- <el-descriptions-item :label="$t('country')">{{item.receiverCountryCode}}</el-descriptions-item> -->
  146. <!-- <el-descriptions-item :label="$t('label.postalCode')">{{item.receiverZip}}</el-descriptions-item>
  147. <el-descriptions-item :label="$t('state')">{{item.receiverState}}</el-descriptions-item>
  148. <el-descriptions-item :label="$t('city')" >{{item.receiverCity}}</el-descriptions-item>
  149. <el-descriptions-item :label="$t('suburb')" >{{item.receiverDistrict}}</el-descriptions-item> -->
  150. <!-- <el-descriptions-item :label="$t('street')" >{{item.receiverStreet}}</el-descriptions-item> -->
  151. <!-- <el-descriptions-item :label="$t('address')" >{{item.receiverAddress}}</el-descriptions-item> -->
  152. <!-- <el-descriptions-item :label="$t('dooeNo')" >{{item.receiverAddress2}}</el-descriptions-item> -->
  153. <!-- <el-descriptions-item :label="$t('recipient')" >{{item.receiverName}}</el-descriptions-item> -->
  154. <!-- <el-descriptions-item :label="$t('telephone')" >{{item.receiverPhone}}</el-descriptions-item>
  155. <el-descriptions-item :label="$t('moPhone')" >{{item.receiverMobile}}</el-descriptions-item> -->
  156. <!-- <el-descriptions-item :label="$t('post')" >{{item.email}}</el-descriptions-item> -->
  157. <!-- <el-descriptions-item :label="$t('label.shippingFee')" >{{item.freight}}</el-descriptions-item> -->
  158. <!-- <el-descriptions-item v-if=" addressInfo.length !=0 && addressInfo.length !=1 " :label="$t('actions')">
  159. <el-button
  160. type="success"
  161. @click="chooseClick(item.idList)"
  162. v-loading="btnLoading"
  163. >选择</el-button
  164. >
  165. </el-descriptions-item> -->
  166. <!-- </el-descriptions> -->
  167. </template>
  168. </div>
  169. </div>
  170. <div
  171. class="box"
  172. style="margin-top: 15px;padding-bottom: 10px;"
  173. v-loading="fromLoading"
  174. v-if="
  175. (this.listQuery.ormorder || this.listQuery.shopify) &&
  176. this.listQuery.refundType
  177. "
  178. >
  179. <div class="item_title">{{ $t("view.refundInfo") }}</div>
  180. <div class="ptitle">
  181. <el-form
  182. label-position="left"
  183. ref="addRefundForm"
  184. :model="addRefundForm"
  185. >
  186. <div class="row">
  187. <div class="row-item">
  188. <div class="row">
  189. <el-form-item class="inputleft" :label="$t('currency')">
  190. <el-input
  191. disabled
  192. v-model="addRefundForm.currency"
  193. placeholder
  194. class="normal-input"
  195. ></el-input>
  196. </el-form-item>
  197. <el-form-item
  198. :label="$t('label.expectedRefundAmount')"
  199. required
  200. >
  201. <el-input
  202. v-model="addRefundForm.refundTotalAmount"
  203. :disabled="true"
  204. />
  205. </el-form-item>
  206. </div>
  207. <el-form-item :label="$t('label.refundMethod')" required>
  208. <el-radio-group v-model="addRefundForm.refundMethod">
  209. <el-radio label="system">{{
  210. $t("view.systemRefund")
  211. }}</el-radio>
  212. <el-radio label="manual">{{
  213. $t("view.manualRefund")
  214. }}</el-radio>
  215. </el-radio-group>
  216. </el-form-item>
  217. <el-form-item
  218. v-if="addRefundForm.refundMethod == 'manual'"
  219. :label="$t('label.accountType')"
  220. required
  221. >
  222. <el-radio-group v-model="addRefundForm.refundAccountType">
  223. <el-radio label="PayPal">PayPal</el-radio>
  224. <!-- 银行卡暂时隐藏 -->
  225. <!-- <el-radio label="bankCard">银行卡</el-radio> -->
  226. <!-- <el-radio label="Gift Card">Gift Card</el-radio> -->
  227. </el-radio-group>
  228. </el-form-item>
  229. <el-form-item
  230. :label="$t('label.receivingAccount')"
  231. v-if="
  232. addRefundForm.refundMethod == 'manual' &&
  233. addRefundForm.refundAccountType == 'PayPal'
  234. "
  235. required
  236. >
  237. <el-input
  238. v-model="addRefundForm.refundAccount"
  239. :placeholder="$t('place.pleaseFillIn')"
  240. class="normal-input"
  241. ></el-input>
  242. </el-form-item>
  243. <el-form-item :label="$t('label.taxRefund')">
  244. <el-radio-group
  245. v-model="addRefundForm.refundTaxAble"
  246. @change="calculateRefundAmount"
  247. >
  248. <el-radio label="0">{{ $t("view.noTaxRefund") }}</el-radio>
  249. <el-radio label="1">{{ $t("view.taxRefund") }}</el-radio>
  250. </el-radio-group>
  251. </el-form-item>
  252. <el-form-item
  253. v-if="addRefundForm.refundTaxAble == 1"
  254. :label="$t('label.taxRefundAmount')"
  255. >
  256. <el-input-number
  257. v-model="addRefundForm.refundTaxAmount"
  258. :min="0.0"
  259. :step="0.01"
  260. step-strictly
  261. @change="calculateRefundAmount"
  262. ></el-input-number>
  263. </el-form-item>
  264. <!-- 选择是否退运费-->
  265. <el-form-item :label="$t('label.shippingFee')">
  266. <el-radio-group
  267. v-model="addRefundForm.refundPostage"
  268. @change="calculateRefundAmount"
  269. >
  270. <el-radio label="0">{{ $t("view.noRefund") }}</el-radio>
  271. <el-radio label="1">{{
  272. $t("view.refundShippingFee")
  273. }}</el-radio>
  274. </el-radio-group>
  275. </el-form-item>
  276. <el-form-item
  277. v-if="addRefundForm.refundPostage == 1"
  278. :label="$t('label.returnShippingFeeAmount')"
  279. >
  280. <el-input-number
  281. v-model="addRefundForm.refundPostageAmount"
  282. :min="0.0"
  283. :step="0.01"
  284. step-strictly
  285. @change="calculateRefundAmount"
  286. ></el-input-number>
  287. </el-form-item>
  288. <el-form-item
  289. v-if="this.queryRefundType == 3"
  290. :label="$t('label.receivingReturnWarehouse')"
  291. >
  292. <el-select
  293. :placeholder="$t('place.pleaseSelect')"
  294. clearable
  295. style="width: 200px;"
  296. class="filter-item"
  297. v-model="addRefundForm.warehouseCode"
  298. @change="ShippingLabelOption"
  299. >
  300. <el-option
  301. v-for="item in warehouseItems"
  302. :key="item.key"
  303. :label="item.key"
  304. :value="item.value"
  305. ></el-option>
  306. </el-select>
  307. </el-form-item>
  308. <el-form-item
  309. v-if="
  310. addRefundForm.warehouseCode == 'PSJ-G001001' ||
  311. addRefundForm.warehouseCode == 'PSJ-G001003' ||
  312. addRefundForm.warehouseCode == 'PSJ-H0000024' ||
  313. addRefundForm.warehouseCode == 'PSJ-H0000019' ||
  314. addRefundForm.warehouseCode == 'PSJ-H0000011' ||
  315. addRefundForm.warehouseCode == 'PSJ-G001004'
  316. "
  317. label="ShippingLabel"
  318. >
  319. <el-radio-group
  320. v-model="addRefundForm.slUseable"
  321. @change="changeSlradio()"
  322. >
  323. <el-radio label="0" value="0">{{
  324. $t("view.notEnabled")
  325. }}</el-radio>
  326. <el-radio label="1" value="1">{{
  327. $t("view.enabled")
  328. }}</el-radio>
  329. </el-radio-group>
  330. </el-form-item>
  331. <el-form-item
  332. v-if="
  333. this.queryRefundType == 3 &&
  334. this.addRefundForm.slUseable == 0
  335. "
  336. :label="$t('label.returnLogisticsCompanyCode')"
  337. >
  338. <el-input
  339. v-model="addRefundForm.shipmodeId"
  340. :placeholder="$t('place.pleaseFillIn')"
  341. class="normal-input"
  342. ></el-input>
  343. </el-form-item>
  344. <el-form-item
  345. v-if="
  346. this.queryRefundType == 3 &&
  347. this.addRefundForm.slUseable == 0
  348. "
  349. :label="$t('label.returnLogisticsNumber')"
  350. >
  351. <el-input
  352. v-model="addRefundForm.shippingNo"
  353. :placeholder="$t('place.pleaseFillIn')"
  354. class="normal-input"
  355. ></el-input>
  356. </el-form-item>
  357. </div>
  358. <div class="row-item">
  359. <el-form-item :label="$t('label.afterSalesInstructions')">
  360. <el-input
  361. type="textarea"
  362. class="afertextarea"
  363. :placeholder="$t('place.enterContent')"
  364. v-model="addRefundForm.notes"
  365. :rows="4"
  366. maxlength="150"
  367. show-word-limit
  368. >
  369. </el-input>
  370. </el-form-item>
  371. <el-form-item :label="$t('label.uploadVoucher')">
  372. <el-upload
  373. class="avatar-uploader"
  374. :action="uploadPhotos"
  375. :show-file-list="false"
  376. :on-success="handleAvatarSuccess"
  377. :before-upload="beforeAvatarUpload"
  378. :headers="headers"
  379. >
  380. <img v-if="imageUrl" :src="imageUrl" class="avatar" />
  381. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  382. </el-upload>
  383. </el-form-item>
  384. </div>
  385. </div>
  386. </el-form>
  387. </div>
  388. <!-- 因为要多选的问题 不考虑分页 -->
  389. <div class="box" style="margin-top: 15px;">
  390. <div class="item_title">
  391. <span>{{ $t("view.selectItems") }}</span>
  392. <el-select
  393. v-if="this.multipleSelection && this.multipleSelection.length > 0"
  394. v-model="refundReasonAss"
  395. style="width: 260px;"
  396. :placeholder="$t('place.selectCheckedRefundReasons')"
  397. clearable
  398. @change="chooseReason(refundReasonAss, reasonListAll)"
  399. >
  400. <el-option
  401. v-for="status in reasonListAll"
  402. :key="status.id"
  403. :label="status.reasonContentChinese"
  404. :value="String(status.id)"
  405. >
  406. </el-option>
  407. </el-select>
  408. <el-input
  409. v-if="otherReasonFlag == '1'"
  410. :placeholder="$t('place.enterReason')"
  411. clearable
  412. style="width: 220px;"
  413. class="filter-item"
  414. v-model="refundOtherReasonAss"
  415. @change="writeReason(refundOtherReasonAss)"
  416. />
  417. </div>
  418. <div>
  419. <el-table
  420. class="itemtable"
  421. ref="multipleTable"
  422. @selection-change="handleSelectionChange"
  423. style="width: 100%;"
  424. v-loading="listLoading"
  425. :key="tableKey"
  426. :data="tableOrderDeatils"
  427. row-key="id"
  428. stripe
  429. border
  430. fit
  431. highlight-current-row
  432. >
  433. <el-table-column
  434. type="selection"
  435. width="55"
  436. :selectable="checkSelectable"
  437. >
  438. </el-table-column>
  439. <el-table-column
  440. :label="$t('label.orderNumber')"
  441. width="150"
  442. align="center"
  443. prop="ordersId"
  444. >
  445. </el-table-column>
  446. <el-table-column
  447. :label="$t('goodsCode')"
  448. width="150"
  449. align="center"
  450. prop="skuCode"
  451. >
  452. </el-table-column>
  453. <el-table-column
  454. :label="$t('onlyCode')"
  455. min-width="180"
  456. align="center"
  457. prop=""
  458. >
  459. <template slot-scope="scope">
  460. <div v-if="scope.row.uniqueCode">
  461. <div
  462. v-for="(item, index) in scope.row.uniqueCode"
  463. :key="index"
  464. >
  465. {{ item }}
  466. </div>
  467. </div>
  468. </template>
  469. </el-table-column>
  470. <el-table-column
  471. :label="$t('goodsName')"
  472. width="300"
  473. align="center"
  474. prop="productName"
  475. ></el-table-column>
  476. <el-table-column
  477. :label="$t('bagSkuCode')"
  478. width="180"
  479. align="center"
  480. prop="bagSkuCode"
  481. ></el-table-column>
  482. <el-table-column
  483. :label="$t('label.originalQuantity')"
  484. width="80"
  485. align="center"
  486. prop="oldQuantity"
  487. ></el-table-column>
  488. <el-table-column
  489. :label="$t('goodsPrice')"
  490. width="80"
  491. align="center"
  492. prop="price"
  493. ></el-table-column>
  494. <el-table-column
  495. :label="$t('offerAmount')"
  496. width="80"
  497. align="center"
  498. prop="discountFee"
  499. ></el-table-column>
  500. <el-table-column
  501. :label="$t('payAmount')"
  502. width="80"
  503. align="center"
  504. prop="totalFee"
  505. ></el-table-column>
  506. <el-table-column
  507. :label="$t('label.refundPercentage')"
  508. width="150"
  509. align="center"
  510. >
  511. <template slot-scope="scope">
  512. <div v-if="multipleSelection.indexOf(scope.row) == -1">
  513. <div>{{ scope.row.refundSales }}</div>
  514. </div>
  515. <div v-else>
  516. <el-input-number
  517. v-model="scope.row.refundSales"
  518. @change="changeQuantity(scope.row)"
  519. size="mini"
  520. :min="0"
  521. :max="1"
  522. :step="0.01"
  523. step-strictly
  524. ></el-input-number>
  525. </div>
  526. </template>
  527. </el-table-column>
  528. <el-table-column
  529. :label="$t('label.eligibleQuantity')"
  530. width="150"
  531. align="center"
  532. >
  533. <template slot-scope="scope">
  534. <div v-if="multipleSelection.indexOf(scope.row) == -1">
  535. <div>{{ scope.row | quantityFilter }}</div>
  536. </div>
  537. <div v-else>
  538. <!-- <tableEdit :row.sync="scope.row"></tableEdit> -->
  539. <el-input-number
  540. v-model="scope.row.quantity"
  541. @change="changeQuantity(scope.row)"
  542. size="mini"
  543. :min="0"
  544. :max="scope.row.maxq"
  545. :step="1"
  546. step-strictly
  547. ></el-input-number>
  548. </div>
  549. </template>
  550. </el-table-column>
  551. <el-table-column
  552. :label="$t('label.refundedAmount')"
  553. width="150"
  554. align="center"
  555. >
  556. <template slot-scope="scope">
  557. <div v-if="multipleSelection.indexOf(scope.row) == -1">
  558. <div>0</div>
  559. </div>
  560. <div v-else>
  561. <el-input-number
  562. v-model="scope.row.refundAmount"
  563. size="mini"
  564. @change="refundAmountChange"
  565. :min="0.0"
  566. :max="scope.row.originRefundAmount"
  567. ></el-input-number>
  568. </div>
  569. </template>
  570. </el-table-column>
  571. <el-table-column
  572. :label="$t('label.needPayWithCustomers')"
  573. width="150"
  574. align="center"
  575. >
  576. <template slot-scope="scope">
  577. <div v-if="multipleSelection.indexOf(scope.row) == -1">
  578. <div>0</div>
  579. </div>
  580. <div v-else>
  581. <el-input-number
  582. v-model="scope.row.differenceAmount"
  583. size="mini"
  584. :min="0.0"
  585. :max="scope.row.originPaidAmount"
  586. @change="refundAmountChange"
  587. ></el-input-number>
  588. </div>
  589. </template>
  590. </el-table-column>
  591. <el-table-column
  592. :label="$t('label.refundReason')"
  593. width="150"
  594. align="center"
  595. >
  596. <template slot-scope="scope">
  597. <div v-if="multipleSelection.indexOf(scope.row) == -1"></div>
  598. <div v-else>
  599. <el-select
  600. v-model="scope.row.refundReason"
  601. :placeholder="$t('place.pleaseSelect')"
  602. clearable
  603. @change="refundChange(scope.row.refundReason, scope.row)"
  604. >
  605. <el-option
  606. v-for="status in scope.row.refundReasonList"
  607. :key="status.id"
  608. :label="status.reasonContentChinese"
  609. :value="String(status.id)"
  610. >
  611. </el-option>
  612. </el-select>
  613. </div>
  614. </template>
  615. </el-table-column>
  616. <el-table-column
  617. :label="$t('label.reasonExplanation')"
  618. width="150"
  619. align="center"
  620. >
  621. <template slot-scope="scope">
  622. <div v-if="multipleSelection.indexOf(scope.row) == -1"></div>
  623. <div v-else>
  624. <el-input
  625. v-if="scope.row.customOpen == '1'"
  626. :placeholder="$t('place.enterReason')"
  627. clearable
  628. style="width: 200px;"
  629. class="filter-item"
  630. v-model="scope.row.otherReason"
  631. />
  632. </div>
  633. </template>
  634. </el-table-column>
  635. <el-table-column
  636. width="55"
  637. :label="$t('label.flashPurchase')"
  638. align="center"
  639. >
  640. <template slot-scope="scope">
  641. <el-checkbox
  642. v-model="scope.row.flashPurchaseFlag == 1"
  643. ></el-checkbox>
  644. </template>
  645. </el-table-column>
  646. <el-table-column
  647. width="55"
  648. :label="$t('label.exchangePurchase')"
  649. align="center"
  650. >
  651. <template slot-scope="scope">
  652. <el-checkbox
  653. v-model="scope.row.exchangePurchaseFlag == 1"
  654. ></el-checkbox>
  655. </template>
  656. </el-table-column>
  657. <el-table-column
  658. :label="$t('label.refundedQuantity')"
  659. width="80"
  660. align="center"
  661. prop="refundQuantity"
  662. ></el-table-column>
  663. <el-table-column
  664. :label="$t('status')"
  665. width="80"
  666. align="center"
  667. prop="status"
  668. >
  669. <template slot-scope="scope">
  670. {{ scope.row.status | statusFilter }}
  671. </template>
  672. </el-table-column>
  673. <el-table-column
  674. :label="$t('label.signedForTheReturn')"
  675. width="80"
  676. align="center"
  677. prop="matchStatus"
  678. >
  679. <template slot-scope="scope">
  680. <span v-if="scope.row.matchStatus == 'unmatch'">
  681. {{ $t("label.notMatched") }}
  682. </span>
  683. <span
  684. v-if="
  685. scope.row.matchStatus == 'order_matched' ||
  686. scope.row.matchStatus == 'matched'
  687. "
  688. >
  689. {{ $t("label.matchedSuccess") }}
  690. </span>
  691. <span v-if="scope.row.matchStatus == null">
  692. {{ $t("label.not") }}
  693. </span>
  694. </template>
  695. </el-table-column>
  696. </el-table>
  697. </div>
  698. </div>
  699. <!-- 多件多折折扣重算 -->
  700. <div class="box" v-has="'priceRule:list'">
  701. <div class="item_title">
  702. {{ $t("multipleDiscountInfo.multipleDiscountReCal") }}
  703. </div>
  704. <div>
  705. <el-table
  706. :key="tableKey"
  707. :data="returnPreviewDatas"
  708. row-key="id"
  709. stripe
  710. border
  711. fit
  712. highlight-current-row
  713. >
  714. <el-table-column type="index" width="40" />
  715. <el-table-column
  716. :label="$t('multipleDiscountInfo.OriginalDiscount')"
  717. align="center"
  718. prop="originTip"
  719. />
  720. <el-table-column
  721. :label="$t('multipleDiscountInfo.OriginalMoneny')"
  722. align="center"
  723. prop="originalOrderAmount"
  724. />
  725. <el-table-column
  726. :label="$t('multipleDiscountInfo.afterReturnDiscount')"
  727. align="center"
  728. prop="currentTip"
  729. />
  730. <el-table-column
  731. :label="$t('multipleDiscountInfo.afterReturnMoney')"
  732. align="center"
  733. prop="currentOrderAmount"
  734. />
  735. <el-table-column
  736. :label="$t('multipleDiscountInfo.returnMoney')"
  737. align="center"
  738. prop="refundAmount"
  739. >
  740. <template slot-scope="scope">
  741. {{ scope.row.refundAmount || 0 }}
  742. </template>
  743. </el-table-column>
  744. <el-table-column
  745. :label="$t('multipleDiscountInfo.needPayMoney')"
  746. align="center"
  747. prop="differenceAmount"
  748. >
  749. <template slot-scope="scope">
  750. {{ scope.row.differenceAmount || 0 }}
  751. </template>
  752. </el-table-column>
  753. </el-table>
  754. </div>
  755. </div>
  756. <div class="box total_box">
  757. <div class="item_title">
  758. {{ $t("view.totalRefund") }}
  759. </div>
  760. <div class="item_box">
  761. {{ $t("view.totalRefund") }}:{{ addRefundForm.refundTotalAmount }}
  762. </div>
  763. </div>
  764. <div class="box btn_box">
  765. <el-button
  766. :style="btnStyle"
  767. class="save_btn"
  768. type="primary"
  769. @click="submit(this)"
  770. v-loading="btnLoading"
  771. >{{ $t("save") }}</el-button
  772. >
  773. <el-button type="danger" class="backbtn" @click="back">{{
  774. $t("back")
  775. }}</el-button>
  776. </div>
  777. </div>
  778. </div>
  779. </div>
  780. </template>
  781. <script>
  782. // import {getRefundReason} from '@/api/oms/refund/refund'
  783. import global from "@/views/oms/global";
  784. import waves from "@/directive/waves";
  785. import { getToken } from "@/utils/auth";
  786. import { dcmSub } from "@/utils/toolUtil";
  787. import { getDetailListForRefund, statusKeyValue } from "@/api/oms/order/order";
  788. import {
  789. validPromotionReq,
  790. warehouseList,
  791. checkSubmitRefund,
  792. backstageSubmitRefund
  793. } from "@/api/oms/refund/refund";
  794. import { BigNumber } from "bignumber.js";
  795. import tableEdit from "./tableEdit";
  796. import i18n from "@/lang";
  797. export default {
  798. name: "createRefundDialog",
  799. directives: {
  800. waves
  801. },
  802. components: {
  803. global,
  804. tableEdit
  805. },
  806. filters: {
  807. statusFilter(key) {
  808. return statusKeyValue[key];
  809. },
  810. quantityFilter(row) {
  811. if (row.refundQuantity > 0) {
  812. return dcmSub(row.oldQuantity, row.refundQuantity);
  813. }
  814. return row.oldQuantity;
  815. }
  816. },
  817. data() {
  818. return {
  819. matchStatus: null,
  820. listLoading: false,
  821. detailLoading: false,
  822. fromLoading: false,
  823. btnLoading: false,
  824. addressInfo: [],
  825. listQuery: {
  826. ormorder: null,
  827. shopify: null,
  828. refundType: null,
  829. idList: null
  830. },
  831. show: false,
  832. tableOrderDeatils: [],
  833. multipleSelection: [],
  834. returnPreviewDatas: [], // 勾选后,退款预览数据
  835. originReturnPreviewDatas: {}, //记录下来的,退款原来预览数据
  836. addRefundForm: {
  837. refundMethod: "system",
  838. refundAccountType: "PayPal",
  839. refundAccount: "",
  840. refundType: "",
  841. refundPostage: "0",
  842. refundAmount: 0.0, //商品退款金额
  843. differenceAmount: 0, // 补款金额
  844. refundPostageAmount: 0.0,
  845. warehouseCode: "",
  846. annexPath: "",
  847. items: [],
  848. oldQuantity: 0,
  849. refundTaxAble: "0", //是否退税
  850. refundTaxAmount: 0.0, //退税金额
  851. refundTotalAmount: 0.0, //总计退款金额 = 商品退款金额 + 退运费金额 + 退税金额 。 实际执行时,refundAmount=商品退款金额 + 退税金额;退运费金额单独计算
  852. // refundReason:'', // 退款原因
  853. // otherReason:'', // 其他退款理由
  854. slUseable: "0", //是否开启ShippingLabel选项
  855. currency: "", //币种
  856. shipmodeId: "", //退货物流公司编号
  857. shippingNo: "", //退货物流单号
  858. notes: ""
  859. },
  860. afterSaleTypes: global.afterSaleType, //售后类型
  861. warehouseItems: [],
  862. queryRefundType: "",
  863. queryOrmorder: "",
  864. queryShopify: "",
  865. btnStyle: "",
  866. imageUrl: "",
  867. uploadPhotos: process.env.VUE_APP_OMS_API + "ordersRefund/uploadPhotos",
  868. reasonListAll: [],
  869. refundReasonAss: "",
  870. refundOtherReasonAss: "",
  871. otherReasonFlag: "",
  872. tableKey: Math.random(),
  873. isRefund: true //是否是退款 true:退款 false:补款
  874. };
  875. },
  876. created() {
  877. //情况清空数据
  878. this.getWarehouseList();
  879. },
  880. computed: {
  881. // 计算属性的 getter
  882. headers: function() {
  883. return {
  884. "X-Token": getToken()
  885. };
  886. }
  887. },
  888. methods: {
  889. getDetail(idList) {
  890. this.ShippingLabelOption();
  891. //非空判断
  892. if (!this.listQuery.ormorder && !this.listQuery.shopify) {
  893. this.$message.error("网店单号和shopify单号不能同时为空");
  894. return;
  895. }
  896. if (!this.listQuery.refundType) {
  897. this.$message.error("请选择售后类型");
  898. return;
  899. }
  900. //初始化数据
  901. this.addRefundForm.refundAmount = 0.0;
  902. this.addRefundForm.differenceAmount = 0.0;
  903. this.addRefundForm.noTaxRefundAmount = 0.0;
  904. this.addRefundForm.noTaxDifferenceAmount = 0.0;
  905. this.addRefundForm.refundPostage = "0";
  906. this.addRefundForm.refundPostageAmount = 0.0;
  907. this.addRefundForm.warehouseCode = "";
  908. this.addRefundForm.annexPath = "";
  909. this.addRefundForm.items = [];
  910. this.addRefundForm.oldQuantity = 0.0;
  911. this.addRefundForm.refundTaxAble = "0"; //是否退税
  912. this.addRefundForm.refundTaxAmount = 0.0; //退税金额
  913. this.addRefundForm.refundTotalAmount = 0.0;
  914. this.addRefundForm.shipmodeId = "";
  915. this.addRefundForm.shippingNo = "";
  916. this.addRefundForm.refundMethod = "system";
  917. this.addRefundForm.refundAccountType = "PayPal";
  918. this.addRefundForm.refundAccount = "";
  919. this.addRefundForm.notes = "";
  920. this.addressInfo = [];
  921. this.listQuery.idList = null;
  922. // this.listQuery.addressId = addressId;
  923. if (idList) {
  924. var addressIds = "";
  925. for (let id in idList) {
  926. addressIds = addressIds + idList[id] + ",";
  927. }
  928. this.listQuery.idList = addressIds.slice(0, addressIds.length - 1);
  929. }
  930. this.reasonListAll = [];
  931. this.refundReasonAss = "";
  932. this.refundOtherReasonAss = "";
  933. this.otherReasonFlag = "";
  934. //查询满足条件的所有订单项
  935. this.listLoading = true;
  936. getDetailListForRefund(this.listQuery).then(res => {
  937. if (200 == res.code) {
  938. if (res.data.isPayment) {
  939. //true:存在未支付订单 ,false:不存在未支付
  940. this.$message.error(i18n.t("label.paidTips"));
  941. this.show = false;
  942. } else {
  943. this.show = true;
  944. //第一次查询的退款类型
  945. this.queryRefundType = res.data.refundType;
  946. this.queryOrmorder = res.data.ormorder;
  947. this.queryShopify = res.data.shopify;
  948. this.tableOrderDeatils = res.data.list;
  949. this.addRefundForm.currency = res.data.currency;
  950. this.addressInfo = res.data.addressList;
  951. this.reasonListAll = res.data.refundReasonList;
  952. let goodsRefundAmount = BigNumber(0);
  953. if (this.tableOrderDeatils) {
  954. for (let ind in this.tableOrderDeatils) {
  955. if (this.tableOrderDeatils[ind].refundFlag == "0") {
  956. this.tableOrderDeatils[ind].refundQuantity = 0;
  957. }
  958. this.tableOrderDeatils[
  959. ind
  960. ].oldQuantity = this.tableOrderDeatils[ind].quantity;
  961. }
  962. //退商品金额计算
  963. this.refundAmount = goodsRefundAmount.toFixed(2);
  964. this.$nextTick(() => {
  965. this.tableOrderDeatils.forEach(row => {
  966. if (row.selectedRow == 1) {
  967. this.$refs.multipleTable.toggleRowSelection(row, true);
  968. }
  969. });
  970. });
  971. }
  972. }
  973. } else {
  974. this.$message.error(res.msg);
  975. this.show = false;
  976. }
  977. this.listLoading = false;
  978. });
  979. },
  980. //获取退货仓库信息
  981. getWarehouseList() {
  982. warehouseList().then(res => {
  983. if (200 == res.code) {
  984. this.warehouseItems = res.data;
  985. }
  986. });
  987. },
  988. //计算退款总额 商品退款金额 + 退运费金额 +退税金额
  989. calculateRefundAmount() {
  990. //如果没选择退税
  991. if (this.addRefundForm.refundTaxAble != "1") {
  992. this.addRefundForm.refundTaxAmount = BigNumber(0)
  993. .toNumber()
  994. .toFixed(2);
  995. }
  996. //如果没选择退运费
  997. if (this.addRefundForm.refundPostage != "1") {
  998. this.addRefundForm.refundPostageAmount = BigNumber(0)
  999. .toNumber()
  1000. .toFixed(2);
  1001. }
  1002. var taxAndShippingAmount = BigNumber(this.addRefundForm.refundTaxAmount)
  1003. .plus(BigNumber(this.addRefundForm.refundPostageAmount))
  1004. .toNumber()
  1005. .toFixed(2);
  1006. let price =
  1007. this.addRefundForm.noTaxRefundAmount !== "NaN" &&
  1008. this.addRefundForm.noTaxRefundAmount > 0
  1009. ? BigNumber(this.addRefundForm.noTaxRefundAmount)
  1010. : BigNumber(this.addRefundForm.noTaxDifferenceAmount).negated();
  1011. this.addRefundForm.refundTotalAmount = BigNumber(taxAndShippingAmount)
  1012. .plus(BigNumber(price))
  1013. .toNumber()
  1014. .toFixed(2);
  1015. },
  1016. // 重新计算退款的金额
  1017. reCalReturn() {
  1018. const data = this.multipleSelection;
  1019. const formData = {
  1020. ormOrderId: this.queryOrmorder,
  1021. promotionRefundDetails: data.map(item => {
  1022. return {
  1023. soOrderId: item.ordersId,
  1024. orderItemId: item.orderitemId,
  1025. ormOrderItemId: item.ormOrderItemId,
  1026. quantity: item.quantity
  1027. };
  1028. })
  1029. };
  1030. this.listLoading = true;
  1031. checkSubmitRefund(formData)
  1032. .then(res => {
  1033. if (res.code === 200) {
  1034. const { orderPreviewVO, ordersRefund } = res.data;
  1035. const { isRefund, titleAmount } = orderPreviewVO;
  1036. const refundAmount = isRefund ? titleAmount : 0;
  1037. const differenceAmount = isRefund ? 0 : titleAmount;
  1038. this.returnPreviewDatas = [
  1039. { ...orderPreviewVO, refundAmount, differenceAmount }
  1040. ];
  1041. this.originReturnPreviewDatas = orderPreviewVO;
  1042. this.isRefund = orderPreviewVO.isRefund;
  1043. const totalPrice = this.multipleSelection.reduce((prev, cur) => {
  1044. return prev + cur.totalFee;
  1045. }, 0);
  1046. for (let k in this.multipleSelection) {
  1047. let row = this.multipleSelection[k];
  1048. let data = ordersRefund.items.find(
  1049. item => item.ormOrderItemId === row.ormOrderItemId
  1050. );
  1051. if (orderPreviewVO.isRefund) {
  1052. // 退款
  1053. row.refundAmount = data.refundAmount;
  1054. row.originRefundAmount = data.refundAmount;
  1055. row.differenceAmount = 0;
  1056. } else {
  1057. // 补差价
  1058. const val = this.calNeedPaidMoney(
  1059. k,
  1060. row,
  1061. orderPreviewVO.titleAmount,
  1062. totalPrice
  1063. );
  1064. row.originPaidAmount = val;
  1065. row.differenceAmount = val;
  1066. row.refundAmount = 0;
  1067. }
  1068. }
  1069. this.jisuan();
  1070. } else {
  1071. this.$message.error(res.msg);
  1072. }
  1073. })
  1074. .finally(() => {
  1075. this.listLoading = false;
  1076. });
  1077. },
  1078. // 计算补差价的金额
  1079. calNeedPaidMoney(i, row, differenceAmount, totalPrice) {
  1080. let data = 0;
  1081. if (this.multipleSelection.length === 1) {
  1082. data = differenceAmount;
  1083. } else if (i === String(this.multipleSelection.length - 1)) {
  1084. const price = this.multipleSelection.reduce((prev, cur) => {
  1085. const amont = cur.differenceAmount || 0;
  1086. return prev + amont;
  1087. }, 0);
  1088. // 最后一个的时候,需要用减法
  1089. data = (differenceAmount - price).toFixed(2);
  1090. } else {
  1091. data = ((row.totalFee / totalPrice) * differenceAmount).toFixed(2);
  1092. }
  1093. return Number(data);
  1094. },
  1095. // 当前选中的 退款金额
  1096. handleSelectionChange(val) {
  1097. this.refundAmount = 0;
  1098. this.differenceAmount = 0;
  1099. this.multipleSelection = val;
  1100. if (this.multipleSelection && this.multipleSelection.length > 0) {
  1101. // 如果是退款新版本,包含多件多折 需要重算退款金额
  1102. this.reCalReturn();
  1103. } else {
  1104. this.refundAmount = 0;
  1105. this.addRefundForm.refundAmount = 0;
  1106. this.addRefundForm.differenceAmount = 0;
  1107. this.addRefundForm.noTaxRefundAmount = 0;
  1108. this.addRefundForm.noTaxDifferenceAmount = 0;
  1109. this.differenceAmount = 0;
  1110. this.returnPreviewDatas = [];
  1111. this.addRefundForm.refundTotalAmount = 0;
  1112. }
  1113. },
  1114. refundAmountChange() {
  1115. this.jisuan();
  1116. },
  1117. jisuan() {
  1118. this.taxAndShippingAmount = BigNumber(this.addRefundForm.refundTaxAmount)
  1119. .plus(BigNumber(this.addRefundForm.refundPostageAmount))
  1120. .toNumber();
  1121. let refundAmount = BigNumber(0); // 退款金额
  1122. let differenceAmount = BigNumber(0); // 补款单金额
  1123. if (this.multipleSelection && this.multipleSelection.length > 0) {
  1124. for (let uy in this.multipleSelection) {
  1125. var row = this.multipleSelection[uy];
  1126. refundAmount = refundAmount.plus(BigNumber(row.refundAmount));
  1127. differenceAmount = differenceAmount.plus(
  1128. BigNumber(row.differenceAmount)
  1129. );
  1130. }
  1131. this.refundAmount = refundAmount.toNumber().toFixed(2);
  1132. this.differenceAmount = differenceAmount.toNumber().toFixed(2);
  1133. }
  1134. this.$set(this.addRefundForm, "noTaxRefundAmount", this.refundAmount);
  1135. this.$set(
  1136. this.addRefundForm,
  1137. "noTaxDifferenceAmount",
  1138. this.differenceAmount
  1139. );
  1140. const refundNewAmount =
  1141. this.refundAmount === "NaN" ? 0 : this.refundAmount;
  1142. const differenceNewAmount =
  1143. this.differenceAmount === "NaN" ? 0 : this.differenceAmount;
  1144. this.returnPreviewDatas[0].refundAmount = refundNewAmount;
  1145. this.returnPreviewDatas[0].differenceAmount = differenceNewAmount;
  1146. let total = 0;
  1147. let price =
  1148. refundNewAmount > 0 ? refundAmount : differenceAmount.negated();
  1149. console.log(
  1150. refundNewAmount,
  1151. differenceNewAmount,
  1152. " price",
  1153. refundNewAmount > 0
  1154. );
  1155. // 退款
  1156. total = price
  1157. .plus(BigNumber(this.taxAndShippingAmount))
  1158. .toNumber()
  1159. .toFixed(2);
  1160. this.$set(this.addRefundForm, "refundTotalAmount", total);
  1161. },
  1162. checkSelectable(row) {
  1163. // 虚拟商品不可选
  1164. // if (row.skuCode === "108C4G1V000BXS") return false;
  1165. if (row.refundQuantity > 0) {
  1166. var refcount = dcmSub(row.oldQuantity, row.refundQuantity);
  1167. //发生退款
  1168. if (refcount <= 0 && this.queryRefundType != "1") {
  1169. return false; //不可选择
  1170. }
  1171. row["maxq"] = refcount;
  1172. } else {
  1173. row["maxq"] = row.oldQuantity;
  1174. }
  1175. // if( row.status == "delivery" && (row.exchangePurchaseFlag == 1)){
  1176. // return false; //不可选择
  1177. // }
  1178. // if (row.quantity != 0) {
  1179. // row.quantity = row["maxq"];
  1180. // }
  1181. //未发货
  1182. if (
  1183. this.queryRefundType == "2" &&
  1184. (row.status == "delivery" ||
  1185. row.status == "off" ||
  1186. row.status == "partdelivery")
  1187. ) {
  1188. return false; //不可选择
  1189. }
  1190. //退货退款
  1191. else if (
  1192. this.queryRefundType == "3" &&
  1193. (row.status == "unchecked" ||
  1194. row.status == "check" ||
  1195. row.status == "undelivery")
  1196. ) {
  1197. return false; //不可选择
  1198. }
  1199. // 促销赠品
  1200. // if (row.isGift === "1" && row.isPromotion === 1) {
  1201. // return false; //不可选择
  1202. // }
  1203. return true;
  1204. },
  1205. refundChange(id, arr) {
  1206. if (id) {
  1207. arr.refundReasonList.forEach(item => {
  1208. if (item.id == id) {
  1209. arr.customOpen = item.custom;
  1210. if (arr.customOpen && arr.customOpen != 1) {
  1211. arr.otherReason = "";
  1212. }
  1213. }
  1214. });
  1215. } else {
  1216. arr.customOpen = "";
  1217. }
  1218. },
  1219. writeReason(otherReason) {
  1220. if (this.multipleSelection && this.multipleSelection.length > 0) {
  1221. for (let uy in this.multipleSelection) {
  1222. var row = this.multipleSelection[uy];
  1223. if (row.customOpen == 1) {
  1224. row.otherReason = otherReason;
  1225. }
  1226. ``;
  1227. }
  1228. }
  1229. },
  1230. chooseReason(id, arr) {
  1231. if (id) {
  1232. arr.forEach(item => {
  1233. if (item.id == id) {
  1234. this.otherReasonFlag = item.custom;
  1235. }
  1236. });
  1237. } else {
  1238. this.otherReasonFlag = "";
  1239. }
  1240. if (this.multipleSelection && this.multipleSelection.length > 0) {
  1241. for (let uy in this.multipleSelection) {
  1242. var row = this.multipleSelection[uy];
  1243. row.refundReason = String(id);
  1244. row.customOpen = this.otherReasonFlag;
  1245. if (row.customOpen != 1) {
  1246. row.otherReason = "";
  1247. }
  1248. }
  1249. }
  1250. },
  1251. changeQuantity() {
  1252. this.reCalReturn();
  1253. },
  1254. handleAvatarSuccess(res, file) {
  1255. this.imageUrl = res.accessUrl;
  1256. if (this.imageUrl) {
  1257. this.addRefundForm.annexPath = this.imageUrl;
  1258. }
  1259. },
  1260. beforeAvatarUpload(file) {
  1261. const isJPG = file.type === "image/jpeg";
  1262. const isLt2M = file.size / 1024 / 1024 < 2;
  1263. if (!isJPG) {
  1264. this.$message.error("上传头像图片只能是 JPG 格式!");
  1265. }
  1266. if (!isLt2M) {
  1267. this.$message.error("上传头像图片大小不能超过 2MB!");
  1268. }
  1269. return isJPG && isLt2M;
  1270. },
  1271. chooseClick(idList) {
  1272. this.getDetail(idList);
  1273. },
  1274. //创建退款单
  1275. submit() {
  1276. if (this.multipleSelection.some(it => it.matchStatus == "unmatch")) {
  1277. this.$message.error("已签收退货状态匹配错误,请匹配成功后重试!");
  1278. return false;
  1279. }
  1280. var flag = false;
  1281. var str = "";
  1282. if (this.addressInfo.length != 1) {
  1283. this.$message.error("请确保地址信息为1!");
  1284. return false;
  1285. }
  1286. //验证 ormorder refundType
  1287. if (!this.listQuery.ormorder && !this.listQuery.shopify) {
  1288. str = str + "网店单号shopify单号不能同时为空。";
  1289. flag = true;
  1290. }
  1291. if (this.queryRefundType != this.listQuery.refundType) {
  1292. str = str + "退款类型不匹配。";
  1293. flag = true;
  1294. }
  1295. if (
  1296. this.listQuery.ormorder &&
  1297. this.listQuery.ormorder != this.queryOrmorder
  1298. ) {
  1299. str = str + "网店单号不匹配";
  1300. flag = true;
  1301. }
  1302. if (
  1303. this.listQuery.shopify &&
  1304. this.listQuery.shopify != this.queryShopify
  1305. ) {
  1306. str = str + "shopify单号不匹配";
  1307. flag = true;
  1308. }
  1309. if (flag) {
  1310. this.$message.error(str + ",请点击查询后继续此操作");
  1311. return false;
  1312. }
  1313. //验证通过 保存逻辑
  1314. this.addRefundForm.ormorder = this.queryOrmorder;
  1315. this.addRefundForm.refundType = this.queryRefundType;
  1316. //退货退款仓库验证
  1317. if (
  1318. this.addRefundForm.refundType == 3 &&
  1319. !this.addRefundForm.warehouseCode
  1320. ) {
  1321. this.$message.error("请选择收退货仓库!");
  1322. return false;
  1323. }
  1324. if (this.multipleSelection.length == 0) {
  1325. this.$message.error("请选择要退的货品!");
  1326. return false;
  1327. }
  1328. var items = [];
  1329. // this.btnLoading = true;
  1330. this.$confirm(
  1331. "退款总计:" + this.addRefundForm.refundTotalAmount + ",是否确认?",
  1332. "提示",
  1333. {
  1334. confirmButtonText: "确定",
  1335. cancelButtonText: "取消",
  1336. type: "warning"
  1337. }
  1338. )
  1339. .then(async () => {
  1340. for (let ind in this.multipleSelection) {
  1341. var obj = this.multipleSelection[ind];
  1342. if (!obj.refundReason) {
  1343. this.$alert(obj.ordersId + ":请选择退款原因");
  1344. this.btnLoading = false;
  1345. return;
  1346. }
  1347. var newobj = {
  1348. productName: obj.productName,
  1349. quantity: obj.quantity,
  1350. ormOrderItemId: obj.ormOrderItemId,
  1351. orderitemId: obj.orderitemId,
  1352. skuCode: obj.skuCode,
  1353. refundAmount: obj.refundAmount,
  1354. differenceAmount: obj.differenceAmount,
  1355. refundReason: obj.refundReason,
  1356. otherReason: obj.otherReason,
  1357. soOrdersId: obj.ordersId,
  1358. isGift: obj.isGift,
  1359. isPromotion: obj.isPromotion
  1360. };
  1361. items.push(newobj);
  1362. }
  1363. this.addRefundForm.items = items;
  1364. //这里默认客服发起
  1365. this.addRefundForm.originatorFlag = 1;
  1366. // 总金额, 正数为退款 负数为补款
  1367. let val = Number(this.addRefundForm.refundTotalAmount);
  1368. if (val < 0) {
  1369. this.addRefundForm.differenceAmount = Math.abs(val);
  1370. this.addRefundForm.refundAmount = 0;
  1371. } else {
  1372. this.addRefundForm.refundAmount = val;
  1373. this.addRefundForm.differenceAmount = 0;
  1374. }
  1375. const saveRefund = () => {
  1376. let query = {
  1377. orderPreviewVO: this.originReturnPreviewDatas,
  1378. ordersRefund: this.addRefundForm
  1379. };
  1380. backstageSubmitRefund(query).then(
  1381. res => {
  1382. if (200 == res.code) {
  1383. this.$message({
  1384. message: this.$t("optSuccess"),
  1385. type: "success"
  1386. });
  1387. items = [];
  1388. this.btnStyle = "display:none";
  1389. }
  1390. },
  1391. error => {
  1392. this.btnLoading = false;
  1393. }
  1394. );
  1395. };
  1396. const validPromotion = async () => {
  1397. // 校验是否包含促销赠品,不包含直接返回true
  1398. if (
  1399. !this.tableOrderDeatils.some(
  1400. item => item.isGift === "1" && item.isPromotion === 1
  1401. )
  1402. ) {
  1403. return true;
  1404. }
  1405. // TODO 解开注释请求校验
  1406. // 校验是否满足促销条件 满足返回true(不提示)
  1407. const { code, data } = await validPromotionReq(this.addRefundForm);
  1408. if (code === 200) {
  1409. return data.valid;
  1410. }
  1411. return false;
  1412. };
  1413. // TODO 存在赠品的订单,在客服创建未发货退款售后单时,需判断扣除已退款明细之后是否还满足促销条件,若不满足,需弹窗提示客服,由客服判断是否继续执行退款。
  1414. if (await validPromotion()) {
  1415. saveRefund();
  1416. } else {
  1417. const res = await this.$confirm(
  1418. "退款后订单将不满足促销条件,是否确认?",
  1419. "提示",
  1420. {
  1421. confirmButtonText: "确定",
  1422. cancelButtonText: "取消",
  1423. type: "warning"
  1424. }
  1425. );
  1426. if (res === "confirm") {
  1427. saveRefund();
  1428. }
  1429. }
  1430. })
  1431. .catch(() => {
  1432. this.btnLoading = false;
  1433. this.$message({
  1434. type: "info",
  1435. message: "已取消操作"
  1436. });
  1437. });
  1438. },
  1439. //TODO 暂时关闭SL
  1440. ShippingLabelOption() {
  1441. this.addRefundForm.slUseable = "0";
  1442. if (
  1443. this.listQuery.refundType == 3 &&
  1444. this.queryRefundType == 3 &&
  1445. this.addressInfo &&
  1446. this.addressInfo.length > 0 &&
  1447. this.addressInfo[0].receiverCountryCode == "US" &&
  1448. (this.addRefundForm.warehouseCode == "PSJ-H0000024" ||
  1449. this.addRefundForm.warehouseCode == "PSJ-H0000019" ||
  1450. this.addRefundForm.warehouseCode == "PSJ-H0000011" ||
  1451. this.addRefundForm.warehouseCode == "PSJ-G001001" ||
  1452. this.addRefundForm.warehouseCode == "PSJ-G001003" ||
  1453. this.addRefundForm.warehouseCode == "PSJ-G001004")
  1454. ) {
  1455. this.addRefundForm.slUseable = "1";
  1456. } else {
  1457. this.addRefundForm.slUseable = "0";
  1458. }
  1459. },
  1460. changeSlradio() {
  1461. if (this.addRefundForm.slUseable == "0") {
  1462. this.addRefundForm.shipmodeId = "";
  1463. this.addRefundForm.shippingNo = "";
  1464. }
  1465. },
  1466. //查询条件等发生变化时触发的方法
  1467. validateParams() {
  1468. //如果退款类型,单号都有
  1469. if (
  1470. (this.listQuery.ormorder || this.listQuery.shopify) &&
  1471. this.listQuery.refundType
  1472. ) {
  1473. //直接触发一次重新查询
  1474. this.getDetail();
  1475. } else {
  1476. //参数不完整的情况,清空之前的选项 初始化数据
  1477. this.ShippingLabelOption();
  1478. //初始化数据
  1479. this.addRefundForm.refundAmount = 0.0;
  1480. this.addRefundForm.noTaxRefundAmount = 0.0;
  1481. this.addRefundForm.noTaxDifferenceAmount = 0.0;
  1482. this.addRefundForm.differenceAmount = 0.0;
  1483. this.addRefundForm.refundPostage = "0";
  1484. this.addRefundForm.refundPostageAmount = 0.0;
  1485. this.addRefundForm.warehouseCode = "";
  1486. this.addRefundForm.annexPath = "";
  1487. this.addRefundForm.items = [];
  1488. this.addRefundForm.oldQuantity = 0.0;
  1489. this.addRefundForm.refundTaxAble = "0"; //是否退税
  1490. this.addRefundForm.refundTaxAmount = 0.0; //退税金额
  1491. this.addRefundForm.refundTotalAmount = 0.0;
  1492. this.addRefundForm.shipmodeId = "";
  1493. this.addRefundForm.shippingNo = "";
  1494. this.addRefundForm.refundMethod = "system";
  1495. this.addRefundForm.refundAccountType = "PayPal";
  1496. this.addRefundForm.refundAccount = "";
  1497. this.addRefundForm.notes = "";
  1498. this.addressInfo = [];
  1499. this.listQuery.idList = null;
  1500. this.reasonListAll = [];
  1501. this.refundReasonAss = "";
  1502. this.refundOtherReasonAss = "";
  1503. this.otherReasonFlag = "";
  1504. }
  1505. },
  1506. back() {
  1507. this.$emit("back");
  1508. }
  1509. }
  1510. };
  1511. </script>
  1512. <style lang="scss" scoped>
  1513. .head {
  1514. padding: 0px 20px;
  1515. display: flex;
  1516. justify-content: space-between;
  1517. span:nth-child(1) {
  1518. font-size: 15px;
  1519. line-height: 25px;
  1520. color: #909399;
  1521. font-weight: 600;
  1522. }
  1523. span:nth-child(2) {
  1524. line-height: 25px;
  1525. cursor: pointer;
  1526. color: #ae8878;
  1527. font-size: 13px;
  1528. }
  1529. }
  1530. .avatar-uploader .el-upload {
  1531. border: 1px dashed #d9d9d9;
  1532. border-radius: 6px;
  1533. cursor: pointer;
  1534. position: relative;
  1535. overflow: hidden;
  1536. }
  1537. .avatar-uploader .el-upload:hover {
  1538. border-color: #409eff;
  1539. }
  1540. .avatar-uploader-icon {
  1541. font-size: 28px;
  1542. color: #8c939d;
  1543. width: 82px;
  1544. height: 82px;
  1545. line-height: 82px;
  1546. text-align: center;
  1547. border-radius: 3px;
  1548. border: 1px solid #dcdfe6;
  1549. margin-left: 49px;
  1550. }
  1551. .avatar {
  1552. width: 178px;
  1553. height: 178px;
  1554. display: block;
  1555. }
  1556. .dialog_container {
  1557. position: relative;
  1558. }
  1559. .main {
  1560. margin-top: 15px;
  1561. .box {
  1562. .item_title {
  1563. color: #606266;
  1564. font-size: 16px !important;
  1565. line-height: 16px;
  1566. position: relative;
  1567. padding-left: 8px !important;
  1568. &:before {
  1569. position: absolute;
  1570. left: 0px;
  1571. top: 13px;
  1572. content: "";
  1573. display: inline-block;
  1574. width: 3px;
  1575. height: 13px;
  1576. background: #ae8877;
  1577. border-radius: 0px 0px 0px 0px;
  1578. }
  1579. }
  1580. .box_item {
  1581. padding: 0 20px;
  1582. display: flex;
  1583. .item_title {
  1584. line-height: 40px;
  1585. font-size: 18px;
  1586. text-align: left;
  1587. font-weight: 600;
  1588. }
  1589. .item_list {
  1590. text-align: left;
  1591. font-size: 14px;
  1592. color: #606266;
  1593. display: flex;
  1594. p {
  1595. margin: 10px 0;
  1596. }
  1597. div:nth-child(2) {
  1598. margin-left: 30px;
  1599. }
  1600. }
  1601. }
  1602. .item_title {
  1603. padding-left: 20px;
  1604. line-height: 40px;
  1605. font-size: 18px;
  1606. text-align: left;
  1607. font-weight: 600;
  1608. }
  1609. }
  1610. }
  1611. .ptitle {
  1612. display: flex;
  1613. justify-content: space-between;
  1614. margin: 20px 0px;
  1615. color: #1f2d3d;
  1616. text-align: left;
  1617. font-weight: bold;
  1618. width: 100%;
  1619. /deep/.el-descriptions__title {
  1620. color: #606266;
  1621. }
  1622. }
  1623. .filter-container {
  1624. .filter-item {
  1625. margin-right: 11px;
  1626. }
  1627. }
  1628. .container {
  1629. display: flex; /* 使用 Flexbox 布局 */
  1630. justify-content: space-between; /* 将盒子平均分布在容器中 */
  1631. }
  1632. .row {
  1633. width: 100%;
  1634. display: flex;
  1635. flex-wrap: wrap;
  1636. /deep/.el-form-item {
  1637. display: flex;
  1638. }
  1639. .inputleft {
  1640. margin-right: 42px;
  1641. }
  1642. .row-item {
  1643. margin-right: 10vw;
  1644. &:last-child {
  1645. margin-right: 0px;
  1646. }
  1647. }
  1648. .afertextarea {
  1649. width: 306px;
  1650. }
  1651. }
  1652. .el-table {
  1653. font-size: 12px;
  1654. margin: 20px 0px;
  1655. }
  1656. .itemtable {
  1657. /deep/.has-gutter {
  1658. .el-table__cell {
  1659. background: #f5f0ee;
  1660. padding: 0px;
  1661. }
  1662. }
  1663. }
  1664. .total_box {
  1665. margin-bottom: 20px;
  1666. .item_box {
  1667. margin-top: 15px;
  1668. }
  1669. }
  1670. .btn_box {
  1671. position: absolute;
  1672. right: 0px;
  1673. bottom: -24px;
  1674. .el-button {
  1675. padding: 10px 37px;
  1676. }
  1677. }
  1678. </style>