create.blade.php 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. @extends('layouts.app')
  2. @section('title')录入-退货管理@endsection
  3. @section('content')
  4. <div class="container-fluid d-none" id="editPanel">
  5. <div class="card mb-2">
  6. <div style="position: relative" v-if="status.lockingBillPanel">
  7. <div style="background-color: #aaa; height: 535px; opacity: 0.5;
  8. width:100%;z-index: 9; position: absolute" class="d-flex ">
  9. </div>
  10. <div style="height: 550px;
  11. width:100%;z-index: 10; position: absolute" class="d-flex align-items-center ">
  12. <button class="btn btn-info flex-fill" @click="cancelPackCommitEdit">取消锁定</button>
  13. </div>
  14. </div>
  15. <div class="row">
  16. <div class="col-7">
  17. <div class="card-body">
  18. <div class="list-group" style="max-height: 477px;overflow-y: scroll">
  19. <table class="table table-sm table-striped table-info table-hover table-bordered">
  20. <tr>
  21. <th>创建时间</th>
  22. <th>客户名称</th>
  23. <th>退回单号</th>
  24. <th>退回公司</th>
  25. <th>姓名</th>
  26. <th>电话</th>
  27. <th>到付费用</th>
  28. <th>订单号</th>
  29. <th>原单号</th>
  30. <th>是否入库</th>
  31. {{-- <th>备注</th>--}}
  32. <th>操作</th>
  33. </tr>
  34. <tr :class="[rejectedBill.isEditing?'bg-info':'']"
  35. v-for="rejectedBill in rejectedBills" :data-id="rejectedBill.id" @click="editBill">
  36. <td>@{{rejectedBill.created_at | dateNoYear}}</td>
  37. <td>@{{rejectedBill.owner_name }}</td>
  38. <td>@{{rejectedBill.logistic_number_return }}</td>
  39. <td>@{{rejectedBill.logistic_name}}</td>
  40. <td>@{{rejectedBill.sender}}</td>
  41. <td>@{{rejectedBill.mobile_sender}}</td>
  42. <td>@{{rejectedBill.fee_collected}}</td>
  43. <td>@{{rejectedBill.order_number}}</td>
  44. <td>@{{rejectedBill.logistic_number}}</td>
  45. <td>@{{rejectedBill.is_loaded|isLoaded}}</td>
  46. {{-- <td>@{{rejectedBill.remark}}</td>--}}
  47. @can('退货管理-删除')
  48. <td>
  49. <button class="btn btn-sm btn-outline-danger"
  50. @click.stop="deleteBill(rejectedBill)">删
  51. </button>
  52. </td>@endcan
  53. </tr>
  54. </table>
  55. </div>
  56. </div>
  57. </div>
  58. <div class="col-5 disabled">
  59. <div class="card-body ml-n4">
  60. <table class="table table-striped table-sm table-bordered"
  61. :class="[status.billEditing?'bg-info':'']">
  62. <tr>
  63. <td>
  64. <div class="form-group mb-0">
  65. <label for="id_owner" class="col-form-label text-right">客户名称</label>
  66. <div class="input-group">
  67. <select name="id_owner" id="id_owner" class="form-control"
  68. :class="[errors.id_owner?'is-invalid':'']"
  69. v-model="billInputting.id_owner" required data-focusOrder="1">
  70. <option value=""></option>
  71. <option v-for="owner in owners" :value="owner.id">@{{ owner.name }}
  72. </option>
  73. </select>
  74. <input type="text" class="form-control input-group-prepend"
  75. placeholder="输入关键字定位客户名称"
  76. name="locateOwnerSearch" autocomplete="off" @input="locateIdOwner"
  77. v-model="billInputting.locateOwnerSearch">
  78. <span class="invalid-feedback" v-if="errors.id_owner"><strong>@{{ errors.id_owner[0] }}</strong></span>
  79. </div>
  80. </div>
  81. </td>
  82. <td>
  83. <div class="form-group mb-0">
  84. <label for="sender" class="col-form-label text-right">姓名</label>
  85. <input type="text" class="form-control" :class="[errors.sender?'is-invalid':'']"
  86. data-focusOrder="5"
  87. name="sender" id="sender" autocomplete="off"
  88. v-model="billInputting.sender">
  89. <span class="invalid-feedback" v-if="errors.sender"><strong>@{{errors.sender[0] }}</strong></span>
  90. </div>
  91. </td>
  92. </tr>
  93. <tr>
  94. <td>
  95. <div class="form-group mb-0">
  96. <label for="logistic_number_return"
  97. class="col-form-label text-right">退回单号</label>
  98. <input type="text" class="form-control"
  99. :class="[errors.logistic_number_return?'is-invalid':'']"
  100. data-focusOrder="2"
  101. name="logistic_number_return" id="logistic_number_return"
  102. autocomplete="off" v-model="billInputting.logistic_number_return"
  103. @change="logistic_number_returnChange"
  104. required>
  105. <span class="invalid-feedback" v-if="errors.logistic_number_return"><strong>@{{errors.logistic_number_return[0] }}</strong></span>
  106. </div>
  107. </td>
  108. <td>
  109. <div class="form-group mb-0">
  110. <label for="fee_collected" class="col-form-label text-right">到付费用</label>
  111. <input type="text" class="form-control"
  112. :class="[errors.fee_collected?'is-invalid':'']"
  113. data-focusOrder=""
  114. v-model="billInputting.fee_collected" name="fee_collected"
  115. id="fee_collected" autocomplete="off">
  116. <span class="invalid-feedback" v-if="errors.fee_collected"><strong>@{{errors.fee_collected[0] }}</strong></span>
  117. </div>
  118. </td>
  119. </tr>
  120. <tr>
  121. <td>
  122. <div class="form-group mb-0">
  123. <label for="id_logistic_return" class="col-form-label text-right">退回公司</label>
  124. <div class="input-group">
  125. <select name="id_logistic_return" id="id_logistic_return"
  126. class="form-control"
  127. data-focusOrder="3"
  128. :class="[errors.id_logistic_return?'is-invalid':'']"
  129. v-model="billInputting.id_logistic_return" required>
  130. <option value=""></option>
  131. <option v-for="logistic in logistics" :value="logistic.id">
  132. @{{logistic.name}}
  133. </option>
  134. </select>
  135. <input type="text" class="form-control input-group-prepend"
  136. placeholder="输入关键字定位物流公司"
  137. name="locateLogisticSearch" autocomplete="off"
  138. @input="locateLogistic" v-model="billInputting.locateLogisticSearch">
  139. <span class="invalid-feedback" v-if="errors.id_logistic_return"><strong>@{{errors.id_logistic_return[0] }}</strong></span>
  140. </div>
  141. </div>
  142. </td>
  143. <td>
  144. <div class="form-group mb-0">
  145. <label for="order_number" class="col-form-label text-right">订单号</label>
  146. <input type="text" class="form-control"
  147. :class="[errors.order_number?'is-invalid':'']"
  148. data-focusOrder="6"
  149. name="order_number" id="order_number" autocomplete="off"
  150. v-model="billInputting.order_number">
  151. <span class="invalid-feedback" v-if="errors.order_number"><strong>@{{ errors.order_number[0] }}</strong></span>
  152. </div>
  153. </td>
  154. </tr>
  155. <tr>
  156. <td>
  157. <div class="form-group mb-0">
  158. <label for="mobile_sender" class="col-form-label text-right">电话</label>
  159. <input type="text" class="form-control"
  160. :class="[errors.mobile_sender?'is-invalid':'']"
  161. data-focusOrder="4"
  162. name="mobile_sender" id="mobile_sender" autocomplete="off"
  163. v-model="billInputting.mobile_sender" required>
  164. <span class="invalid-feedback" v-if="errors.mobile_sender"><strong>@{{ errors.mobile_sender[0] }}</strong></span>
  165. </div>
  166. </td>
  167. <td>
  168. <div class="form-group mb-0">
  169. <label for="logistic_number" class="col-form-label text-right">原单号</label>
  170. <button class="btn btn-outline-primary btn-sm"
  171. @click="billInputting.logistic_number='原单退回'"
  172. style="transform: scale(0.9)">原单退回
  173. </button>
  174. <input type="text" class="form-control"
  175. :class="[errors.logistic_number?'is-invalid':'']"
  176. data-focusOrder="7"
  177. name="logistic_number" id="logistic_number" autocomplete="off"
  178. v-model="billInputting.logistic_number"
  179. >
  180. <span class="invalid-feedback" v-if="errors.logistic_number"><strong>@{{errors.logistic_number[0] }}</strong></span>
  181. </div>
  182. </td>
  183. </tr>
  184. <tr>
  185. <td>
  186. <div class="form-group mb-0">
  187. <label for="bill_remark" class="col-form-label text-right">备注</label>
  188. <input type="text" class="form-control"
  189. :class="[errors.bill_remark?'is-invalid':'']"
  190. data-focusOrder="9"
  191. name="remark" id="bill_remark" autocomplete="off"
  192. v-model="billInputting.remark" required>
  193. <span class="invalid-feedback" v-if="errors.bill_remark"><strong>@{{ errors.remark[0] }}</strong></span>
  194. </div>
  195. </td>
  196. <td>
  197. <div class="form-group mb-0">
  198. <label for="is_loaded" class="col-form-label text-right">是否入库</label>
  199. <div v-if="status.isLoadSign" class="text-danger">系统标计为入库</div>
  200. <select name="is_loaded" id="is_loaded" class="form-control"
  201. :class="[errors.is_loaded?'is-invalid':'']"
  202. data-focusOrder="8" :disabled="status.lockingIsLoadedInput"
  203. v-model="billInputting.is_loaded" required>
  204. <option value="0">否</option>
  205. <option value="1">是</option>
  206. <option value="null">无需入库</option>
  207. <option value="3">上传异常</option>
  208. </select>
  209. <span class="invalid-feedback" v-if="errors.is_loaded"><strong>@{{errors.is_loaded[0]}}</strong></span>
  210. </div>
  211. </td>
  212. </tr>
  213. <tr v-if="billInputting.id_owner==='94'">
  214. <td>
  215. <div class="form-group mb-0">
  216. <label for="common_01" class="col-form-label text-right">寄件方省</label>
  217. <input type="text" class="form-control"
  218. :class="[errors.common_01?'is-invalid':'']"
  219. data-focusOrder="10"
  220. name="common_01" id="common_01" autocomplete="off"
  221. v-model="billInputting.common_01" required>
  222. <span class="invalid-feedback" v-if="errors.common_01"><strong>@{{ errors.common_01[0] }}</strong></span>
  223. </div>
  224. </td>
  225. <td>
  226. <div class="form-group mb-0">
  227. <label for="common_02" class="col-form-label text-right">重量</label>
  228. <input type="text" class="form-control"
  229. :class="[errors.common_02?'is-invalid':'']"
  230. data-focusOrder="11"
  231. name="common_02" id="common_02" autocomplete="off"
  232. v-model="billInputting.common_02" required>
  233. <span class="invalid-feedback" v-if="errors.common_02"><strong>@{{ errors.common_02[0] }}</strong></span>
  234. </div>
  235. </td>
  236. </tr>
  237. <tr>
  238. <td>
  239. <div class="form-group mb-0 align-items-center row">
  240. <div class="col-2" v-if="status.billEditing">
  241. <button class="btn btn-success btn-sm tooltipOn" @click="shiftToCreate"
  242. title="点击取消编辑,进入新增状态">取消
  243. </button>
  244. </div>
  245. <div class="col-8" :class="[status.billCreating?'offset-2':'']">
  246. <input v-if="status.billCreating" type="button"
  247. class="btn btn-success form-control" value="提交新条目"
  248. @click="commitHeader">
  249. <input v-if="status.billEditing" type="button"
  250. class="btn btn-dark form-control" value="修改"
  251. @click="commitEditHeader">
  252. </div>
  253. </div>
  254. </td>
  255. <td>
  256. </td>
  257. </tr>
  258. </table>
  259. </div>
  260. </div>
  261. </div>
  262. </div>
  263. <div class="card" v-if="status.editingBill">
  264. <div class="row">
  265. <div class="col-7">
  266. <div class="card-body">
  267. <div class="list-group">
  268. <table class="table table-sm table-striped table-warning table-hover table-bordered">
  269. <tr>
  270. <th class="text-center">序号</th>
  271. <th class="text-center">商品条码</th>
  272. <th class="text-center">商品名称</th>
  273. <th class="text-center">数量</th>
  274. <th class="text-center">是否正品</th>
  275. <th class="text-center">生产日期</th>
  276. <th class="text-center">效期</th>
  277. <th class="text-center">批次号</th>
  278. <th class="text-center">备注</th>
  279. <th class="text-center">照片</th>
  280. @can('退货管理-删除')
  281. <th class="text-center">操作</th>@endcan
  282. </tr>
  283. <tr :class="[item.isEditing?'bg-warning':'']"
  284. v-for="(item,i) in items" :data-id="item.id" @click="editItem">
  285. <td>@{{i+1}}</td>
  286. <td>@{{item.barcode_goods }}</td>
  287. <td>@{{item.name_goods }}</td>
  288. <td>@{{item.amount}}</td>
  289. <td>@{{item.quality_label}}</td>
  290. <td>@{{item.made_at}}</td>
  291. <td>@{{item.validity_at}}</td>
  292. <td>@{{item.batch_number}}</td>
  293. <td>@{{item.remark}}</td>
  294. <td>
  295. <div align="center" @mouseleave="removeCommonImg('common_img_'+item.id)" @mouseenter="commonImg('img_'+item.id,item.upload_files)">
  296. <button class="btn btn-outline-secondary btn-sm" @click="takePhoto(item.id,i)">拍照上传</button>
  297. <div :id="'img_'+item.id">
  298. <img v-for="uploadFile in item.upload_files" :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
  299. </div>
  300. </div>
  301. </td>
  302. <td class="text-center">
  303. <button class="btn btn-outline-success btn-sm" @click="enableCamera(true);">开启摄像头</button>
  304. @can('退货管理-删除')<button class="btn btn-outline-danger btn-sm" @click="deleteItem">删</button>@endcan
  305. </td>
  306. </tr>
  307. </table>
  308. </div>
  309. </div>
  310. </div>
  311. <div class="col-5">
  312. <div class="card-body ml-n4">
  313. <table class="table table-striped table-sm table-bordered"
  314. :class="[status.itemEditing?'bg-warning':'']">
  315. <tr>
  316. <td>
  317. <div class="form-group mb-0">
  318. <label for="barcode_goods" class="col-form-label text-right">商品条码</label>
  319. <input type="text" class="form-control"
  320. :class="[errors.barcode_goods?'is-invalid':'']"
  321. data-focusOrder="11"
  322. name="barcode_goods" id="barcode_goods" autocomplete="off"
  323. v-model="itemInputting.barcode_goods"
  324. @change="barcode_goodsChange"
  325. >
  326. <span class="invalid-feedback" v-if="errors.barcode_goods"><strong>@{{errors.barcode_goods[0] }}</strong></span>
  327. </div>
  328. </td>
  329. <td>
  330. <div class="form-group mb-0">
  331. <label for="name_goods" class="col-form-label text-right">商品名称</label>
  332. <input type="text" class="form-control"
  333. :class="[errors.name_goods?'is-invalid':'']"
  334. data-focusOrder="14"
  335. name="name_goods" id="name_goods" autocomplete="off"
  336. v-model="itemInputting.name_goods"
  337. @change="name_goodsChange"
  338. >
  339. <span class="invalid-feedback" v-if="errors.name_goods"><strong>@{{errors.name_goods[0] }}</strong></span>
  340. </div>
  341. </td>
  342. </tr>
  343. <tr>
  344. <td>
  345. <div class="form-group mb-0">
  346. <label for="amount" class="col-form-label text-right">数量</label>
  347. <input type="" class="form-control" :class="[errors.amount?'is-invalid':'']"
  348. data-focusOrder="12"
  349. name="amount" id="amount" autocomplete="off"
  350. v-model="itemInputting.amount" required>
  351. <span class="invalid-feedback" v-if="errors.amount"><strong>@{{errors.amount[0] }}</strong></span>
  352. </div>
  353. </td>
  354. <td>
  355. <div class="form-group mb-0">
  356. <label for="qualityLabel.name" class="col-form-label text-right">是否正品</label>
  357. <div class="form-control" :class="[errors.id_quality_label?'is-invalid':'']">
  358. <span><input id="id_quality_label_space" type="radio"
  359. name="id_quality_label"
  360. data-focusOrder="13" required="required" checked><label
  361. for="id_quality_label_space">留空</label>&nbsp;</span>
  362. <span v-for="qualityLabel in qualityLabels">
  363. <input type="radio" name="id_quality_label" :value="qualityLabel.id"
  364. data-focusOrder="13"
  365. :id="'id_quality_label_'+qualityLabel.id"
  366. v-model="itemInputting.id_quality_label" required><label
  367. for="'id_quality_label_'+qualityLabel.id">@{{qualityLabel.name}}</label>&nbsp;</span>
  368. </div>
  369. <span class="invalid-feedback" v-if="errors.id_quality_label"><strong>@{{errors.id_quality_label[0] }}</strong></span>
  370. </div>
  371. </td>
  372. </tr>
  373. <tr>
  374. <td>
  375. <div class="form-group mb-0">
  376. <label for="made_at" class="col-form-label text-right">生产日期</label>
  377. <input type="date" class="form-control"
  378. :class="[errors.made_at?'is-invalid':'']"
  379. data-focusOrder="16"
  380. name="made_at" id="made_at" autocomplete="off"
  381. v-model="itemInputting.made_at">
  382. <span class="invalid-feedback" v-if="errors.made_at"><strong>@{{errors.made_at[0] }}</strong></span>
  383. </div>
  384. </td>
  385. <td>
  386. <div class="form-group mb-0">
  387. <label for="validity_at" class="col-form-label text-right">效期</label>
  388. <input type="date" class="form-control"
  389. :class="[errors.validity_at?'is-invalid':'']"
  390. data-focusOrder="17"
  391. name="validity_at" id="validity_at" autocomplete="off"
  392. v-model="itemInputting.validity_at">
  393. <span class="invalid-feedback" v-if="errors.validity_at"><strong>@{{errors.validity_at[0] }}</strong></span>
  394. </div>
  395. </td>
  396. </tr>
  397. <tr>
  398. <td>
  399. <div class="form-group mb-0">
  400. <label for="batch_number" class="col-form-label text-right">批次号</label>
  401. <input type="text" class="form-control"
  402. :class="[errors.batch_number?'is-invalid':'']"
  403. data-focusOrder="15"
  404. name="batch_number" id="batch_number" autocomplete="off"
  405. v-model="itemInputting.batch_number"
  406. >
  407. <span class="invalid-feedback" v-if="errors.batch_number"><strong>@{{errors.batch_number[0] }}</strong></span>
  408. </div>
  409. </td>
  410. <td>
  411. <div class="form-group mb-0">
  412. <label for="remark" class="col-form-label text-right">备注</label>
  413. <input type="text" class="form-control" :class="[errors.remark?'is-invalid':'']"
  414. data-focusOrder="15"
  415. name="remark" id="remark" autocomplete="off"
  416. v-model="itemInputting.remark">
  417. <span class="invalid-feedback" v-if="errors.remark"><strong>@{{errors.remark[0] }}</strong></span>
  418. </div>
  419. </td>
  420. </tr>
  421. <tr>
  422. <td>
  423. <div class="form-group mb-0 align-items-center row">
  424. <div class="col-2" v-if="status.itemEditing">
  425. <button class="btn btn-success btn-sm tooltipOn" @click="shiftToCreateItem"
  426. title="点击取消编辑,进入新增状态">取消
  427. </button>
  428. </div>
  429. <div class="col-8" :class="[status.itemCreating?'offset-2':'']">
  430. <button v-if="status.itemCreating" class="btn btn-success form-control"
  431. @click="commitItem">添加明细
  432. </button>
  433. <input v-if="status.itemEditing" type="button"
  434. class="btn btn-dark form-control" value="修改" @click="commitEditItem">
  435. </div>
  436. </div>
  437. </td>
  438. <td>
  439. </td>
  440. </tr>
  441. <tr>
  442. <td colspan="2">
  443. <div class="form-group mb-0">
  444. <div class="col-8 offset-2 mt-2 mb-2">
  445. <button class="btn btn-dark form-control" @click="endAndPackCommitEdit">
  446. 结束添加并提交
  447. </button>
  448. </div>
  449. </div>
  450. </td>
  451. </tr>
  452. </table>
  453. </div>
  454. </div>
  455. </div>
  456. </div>
  457. <div id="drag" class="col-4 p-0" style="position:fixed;bottom: 30px;left: 10px;">
  458. <div class="text-left text-success">连接摄像头拍照</div>
  459. <video id="photo" width="50%" height="auto" controls></video>
  460. <canvas id='canvas'width='400' height='300' hidden></canvas>
  461. </div>
  462. </div>
  463. @endsection
  464. @section('lastScript')
  465. <script>
  466. //鼠标拖动 drag
  467. $(function() {
  468. let posX,posY;
  469. let drag = document.getElementById("drag");
  470. drag.onmousedown = function(e) {
  471. posX = event.x - drag.offsetLeft; //获得横坐标x
  472. posY = event.y - drag.offsetTop; //获得纵坐标y
  473. document.onmousemove = mousemove; //调用函数,只要一直按着按钮就能一直调用
  474. }
  475. document.onmouseup = function() {
  476. document.onmousemove = null; //鼠标举起,停止
  477. }
  478. function mousemove(ev) {
  479. if (ev == null) ev = window.event;
  480. let left= (ev.clientX - posX);
  481. let top= (ev.clientY - posY);
  482. let pageWidth=document.body.scrollWidth;//网页正文宽度
  483. let pageHeight=window.screen.availHeight;//屏幕工作区高度
  484. //限定拖动区域
  485. if (left <0)left=0;
  486. if (left >pageWidth)left=pageWidth;
  487. if (top <0)top=0;
  488. if (top >pageHeight)top=pageHeight;
  489. drag.style.left = left + "px";
  490. drag.style.top = top + "px";
  491. }
  492. })
  493. let MediaUtils = {
  494. /**
  495. * 获取用户媒体设备(处理兼容的问题)
  496. * @param videoEnable {boolean} - 是否启用摄像头
  497. * @param audioEnable {boolean} - 是否启用麦克风
  498. * @param callback {Function} - 处理回调
  499. */
  500. getUserMedia: function (videoEnable, audioEnable, callback) {
  501. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia
  502. || navigator.msGetUserMedia || window.getUserMedia;
  503. let constraints = {video: videoEnable, audio: audioEnable};
  504. if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
  505. navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
  506. callback(false, stream);
  507. })['catch'](function (err) {
  508. callback(err);
  509. });
  510. } else if (navigator.getUserMedia) {
  511. navigator.getUserMedia(constraints, function (stream) {
  512. callback(false, stream);
  513. }, function (err) {
  514. callback(err);
  515. });
  516. } else {
  517. callback(new Error('Not support userMedia'));
  518. }
  519. },
  520. /**
  521. * 关闭媒体流
  522. * @param stream {MediaStream} - 需要关闭的流
  523. */
  524. closeStream: function (stream) {
  525. if (typeof stream.stop === 'function') {
  526. stream.stop();
  527. } else {
  528. let trackList = [stream.getAudioTracks(), stream.getVideoTracks()];
  529. for (let i = 0; i < trackList.length; i++) {
  530. let tracks = trackList[i];
  531. if (tracks && tracks.length > 0) {
  532. for (let j = 0; j < tracks.length; j++) {
  533. let track = tracks[j];
  534. if (typeof track.stop === 'function') {
  535. track.stop();
  536. }
  537. }
  538. }
  539. }
  540. }
  541. }
  542. };
  543. let vueList = new Vue({
  544. el: "#editPanel",
  545. data: {
  546. imgPrefix:"{{asset("/storage")}}",
  547. // 用于存放 MediaRecorder 对象和音频Track,关闭录制和关闭媒体设备需要用到
  548. recorder:'',
  549. mediaStream:'',
  550. // 用于存放录制后的音频文件对象和录制结束回调
  551. recorderFile:'',
  552. stopRecordCallback:'',
  553. // 用于存放是否开启了视频录制
  554. videoEnabled:false,
  555. status: {
  556. billCreating: true,
  557. billEditing: false,
  558. itemCreating: true,
  559. itemEditing: false
  560. ,
  561. editingBill: null,
  562. editingBillId: '',
  563. editingItem: null,
  564. editingItemId: ''
  565. ,
  566. inputtingId_owner: '',
  567. endAndPackCommitEdited: false,
  568. lockingBillPanel: false,
  569. lockingIsLoadedInput: false,
  570. existItemsBeforeAdd: 0
  571. },
  572. itemInputting: {
  573. barcode_goods: "", name_goods: "", amount: "1", id_quality_label: "",
  574. batch_number: "", validity_at: "", remark: "", made_at: "",
  575. },
  576. billInputting: {
  577. id_owner: "", mobile_sender: "", sender: "", order_number: "", remark: "",
  578. logistic_number_return: "", logistic_number: "", id_logistic_return: "",
  579. fee_collected: "", is_loaded: "0", locateLogisticSearch: "", locateOwnerSearch: "",
  580. isLoadSign: false,
  581. },
  582. errors: {
  583. id_owner: "", mobile_sender: "", sender: "", bill_remark: "",
  584. logistic_number_return: "", logistic_number: "", id_logistic_return: "",
  585. fee_collected: "", is_loaded: "",
  586. barcode_goods: "", name_goods: "", amount: "", id_quality_label: "",
  587. batch_number: "", validity_at: "", remark: "", made_at: "",
  588. },
  589. rejectedBills: {!! $rejectedBills??[] !!},
  590. items: [],
  591. owners: [
  592. @foreach($owners as $owner)
  593. {
  594. id: '{{$owner->id}}', name: '{{$owner->name}}', code: '{{$owner->code}}'
  595. },
  596. @endforeach
  597. ],
  598. logistics: [
  599. @foreach($logistics as $logistic)
  600. {
  601. id: '{{$logistic->id}}', name: '{{$logistic->name}}', code: '{{$logistic->code}}'
  602. },
  603. @endforeach
  604. ],
  605. qualityLabels: [
  606. @foreach($qualityLabels as $qualityLabel)
  607. {
  608. id: '{{$qualityLabel->id}}', name: '{{$qualityLabel->name}}'
  609. },
  610. @endforeach
  611. ],
  612. commodityOwnerId: '',
  613. },
  614. mounted: function () {
  615. let _this = this;
  616. $('#editPanel').removeClass('d-none');
  617. $('.tooltipOn').tooltip({'trigger': 'hover'});
  618. $(document).on('keypress', function (e) {
  619. if (_this.itemInputting.barcode_goods) {
  620. if (e.key === '*') {
  621. _this.commitItem();
  622. return false;
  623. }
  624. }
  625. });
  626. this.listenEnterAndJump();
  627. },
  628. methods: {
  629. logistic_number_returnChange: function (e) {
  630. let _this = this;
  631. let number = $(e.target).val();
  632. if (!number) return;
  633. let url = '{{"/apiLocal/logistic/numberFeatures/computeLogisticByNumber"}}';
  634. axios.post(url, {logistic_number_return: number}).then(function (response) {
  635. _this.cleanError();
  636. if (response.data.success === 'true') {
  637. if (response.data.logistic) {
  638. _this.billInputting.id_logistic_return = response.data.logistic.id;
  639. }
  640. }
  641. }).catch(function (response) {
  642. console.log(response);
  643. });
  644. if (_this.status.editingBill) return;
  645. let url_isUnique = '{{"/apiLocal/logistic/logisticNumberReturnIsUnique"}}';
  646. axios.post(url_isUnique, {logistic_number_return: number}).then(function (response) {
  647. _this.cleanError();
  648. if (response.data.success === 'true') {
  649. if (response.data.result === 'true') {
  650. tempTip.okWindow('该退回单号"' + number + '"已有录入其他单', '知道了')
  651. } else _this.seek_order();
  652. }
  653. }).catch(function (response) {
  654. console.log(response);
  655. });
  656. },
  657. barcode_goodsChange: function (e) {
  658. let _this = this;
  659. let barcode = $(e.target).val();
  660. let url = '{{"/apiLocal/commodity/getCommodityByBarcode"}}';
  661. axios.post(url, {
  662. barcode: barcode,
  663. owner_id: _this.billInputting.id_owner
  664. }).then(function (response) {
  665. _this.cleanError();
  666. if (response.data.success === 'true') {
  667. if (response.data.commodity) {
  668. // _this.itemInputting.name_goods=response.data.name;
  669. _this.itemInputting.name_goods = response.data.commodity.name;
  670. _this.commodityOwnerId = response.data.commodity.owner_id;
  671. }
  672. } else {
  673. tempTip.setDuration(3000);
  674. tempTip.show('查找商品条码错误:' + response.data.fail_info)
  675. }
  676. }).catch(function (response) {
  677. tempTip.setDuration(3000);
  678. tempTip.show('未连接至商品表,检查网络');
  679. });
  680. },
  681. name_goodsChange: function (e) {
  682. let _this = this;
  683. let name = $(e.target).val();
  684. this.items.forEach(function (item) {
  685. if (item.barcode_goods + '' === _this.itemInputting.barcode_goods + '') {
  686. item.name_goods = name;
  687. }
  688. });
  689. },
  690. listenEnterAndJump: function () {
  691. let targets = $('select,input');
  692. targets.off('keypress');
  693. targets.on('keypress', function (e) {
  694. if (e.key !== "Enter") return;
  695. let target = $(e.target);
  696. let currentOrder = target.attr('data-focusOrder');
  697. if (currentOrder) {
  698. targets.each(function ($i, $val) {
  699. let checkingTarget = $($val);
  700. let checkingOrder = checkingTarget.attr('data-focusOrder');
  701. if (parseInt(currentOrder) + 1 === parseInt(checkingOrder)) {
  702. checkingTarget.focus();
  703. }
  704. })
  705. }
  706. });
  707. targets.off('change');
  708. targets.on('change', function (e) {
  709. let target = $(e.target);
  710. let currentOrder = target.attr('data-focusOrder');
  711. if (currentOrder) {
  712. targets.each(function ($i, $val) {
  713. let checkingTarget = $($val);
  714. let checkingOrder = checkingTarget.attr('data-focusOrder');
  715. if (parseInt(currentOrder) + 1 === parseInt(checkingOrder)) {
  716. checkingTarget.focus();
  717. }
  718. })
  719. }
  720. })
  721. },
  722. cleanHeader: function () {
  723. for (let key in this.billInputting) {
  724. this.billInputting[key] = '';
  725. }
  726. this.billInputting.id_owner = this.status.inputtingId_owner;
  727. this.billInputting.is_loaded = "0";
  728. this.billInputting.isLoadSign = false;
  729. },
  730. cleanItem: function () {
  731. for (let key in this.itemInputting) {
  732. this.itemInputting[key] = '';
  733. }
  734. this.itemInputting['amount'] = '1';
  735. },
  736. cleanError: function () {
  737. for (let key in this.errors) {
  738. this.errors[key] = '';
  739. }
  740. },
  741. setEditingBill: function (id) {
  742. let _this = this;
  743. this.status.editingBillId = id;
  744. this.rejectedBills.forEach(function (bill) {
  745. if (bill.id + '' === id + '') {
  746. _this.status.editingBill = bill;
  747. bill.isEditing = true;
  748. } else {
  749. bill.isEditing = false
  750. }
  751. });
  752. this.$forceUpdate();
  753. },
  754. setEditingItem: function (id) {
  755. let _this = this;
  756. this.status.editingItemId = id;
  757. this.items.forEach(function (item) {
  758. if (item.id + '' === id + '') {
  759. _this.status.editingItem = item;
  760. item.isEditing = true;
  761. } else {
  762. item.isEditing = false
  763. }
  764. });
  765. this.$forceUpdate();
  766. },
  767. commitHeader: function () {
  768. let _this = this;
  769. let url = '{{url('apiLocal/rejectedBill/store')}}';
  770. tempTip.setDuration(99999);
  771. tempTip.waitingTip('提交中')
  772. axios.post(url, _this.billInputting).then(function (response) {
  773. tempTip.cancelWaitingTip();
  774. _this.cleanError();
  775. if (response.data.success === 'true') {
  776. tempTip.setDuration(1000);
  777. tempTip.showSuccess('成功录入退单号:' + _this.billInputting.logistic_number_return);
  778. _this.status.inputtingId_owner = _this.billInputting.id_owner;
  779. _this.setEditingBill(response.data.id);
  780. _this.getItemsUnderBill(response.data.id);
  781. _this.cleanHeader();
  782. _this.getRecentRejectedBills();
  783. _this.lockBillPanel();
  784. _this.status.existItemsBeforeAdd = 0;
  785. $('#barcode_goods').focus();
  786. } else {
  787. if (response.data.error_fields) {
  788. tempTip.setDuration(3000);
  789. tempTip.show('录入失败,字段填写错误');
  790. _this.errors = response.data.error_fields;
  791. if (_this.errors.remark) {
  792. _this.errors.bill_remark = _this.errors.remark;
  793. _this.errors.remark = '';
  794. }
  795. } else {
  796. tempTip.setDuration(3000);
  797. tempTip.show('录入失败:' + response.data.fail_info)
  798. }
  799. }
  800. }).catch(function (response) {
  801. tempTip.setDuration(3000);
  802. tempTip.show('提交失败,请重试:' + response.data.fail_info)
  803. alert('连接错误:' + response)
  804. });
  805. },
  806. commitEditItem: function () {
  807. let _this = this;
  808. if (!confirm("确定要提交修改吗?")) {
  809. return;
  810. }
  811. let url = '{{url('apiLocal/rejectedBillItem/update')}}';
  812. axios.post(url, _this.itemInputting).then(function (response) {
  813. _this.cleanError();
  814. if (response.data.success === 'true') {
  815. tempTip.setDuration(1000);
  816. tempTip.showSuccess('成功修改商品:' + _this.itemInputting.barcode_goods);
  817. _this.cleanItem();
  818. _this.getItemsUnderBill(_this.status.editingBillId);
  819. _this.shiftToCreateItem();
  820. } else {
  821. if (response.data.error_fields) {
  822. tempTip.setDuration(3000);
  823. tempTip.show('修改失败,字段填写错误');
  824. _this.errors = response.data.error_fields;
  825. if (_this.errors.remark) {
  826. _this.errors.bill_remark = _this.errors.remark;
  827. _this.errors.remark = '';
  828. }
  829. } else {
  830. tempTip.show('修改失败:' + response.data.fail_info)
  831. }
  832. }
  833. }).catch(function (response) {
  834. tempTip.setDuration(3000);
  835. tempTip.show('提交失败,请重试:' + response.data.fail_info)
  836. alert('连接错误:' + response)
  837. });
  838. },
  839. commitEditHeader: function () {
  840. let _this = this;
  841. if (!confirm("确定要提交修改吗?")) {
  842. return;
  843. }
  844. let url = '{{url('apiLocal/rejectedBill/update')}}';
  845. tempTip.setDuration(99999);
  846. tempTip.waitingTip('提交中')
  847. axios.post(url, _this.billInputting).then(function (response) {
  848. tempTip.cancelWaitingTip();
  849. _this.cleanError();
  850. if (response.data.success === 'true') {
  851. tempTip.setDuration(1000);
  852. tempTip.showSuccess('成功修改退单号:' + _this.billInputting.logistic_number_return);
  853. _this.cleanHeader();
  854. _this.getRecentRejectedBills();
  855. _this.shiftToCreate();
  856. } else {
  857. if (response.data.error_fields) {
  858. tempTip.setDuration(3000);
  859. tempTip.show('修改失败,字段填写错误');
  860. _this.errors = response.data.error_fields;
  861. } else {
  862. tempTip.show('修改失败:' + response.data.fail_info)
  863. }
  864. }
  865. }).catch(function (response) {
  866. tempTip.setDuration(3000);
  867. tempTip.show('提交失败,请重试:' + response.data.fail_info)
  868. alert('连接错误:' + response)
  869. });
  870. },
  871. commitItem: function () {
  872. let _this = this;
  873. let url = '{{url('apiLocal/rejectedBillItem/store')}}';
  874. _this.itemInputting.id_rejected_bill = _this.status.editingBill.id;
  875. if (_this.items.length < 1) {
  876. let baoShiBuFaOwnerId = '';
  877. _this.owners.forEach(function (owner) {
  878. if (owner.name === '宝时补发') baoShiBuFaOwnerId = owner.id;
  879. });
  880. if (_this.commodityOwnerId != _this.billInputting.id_owner && _this.billInputting.id_owner != baoShiBuFaOwnerId) {
  881. _this.isChangeOwner(_this.itemInputting.id_rejected_bill);
  882. }
  883. }
  884. axios.post(url, _this.itemInputting).then(function (response) {
  885. _this.cleanError();
  886. if (response.data.success === 'true') {
  887. tempTip.setDuration(1000);
  888. tempTip.showSuccess('成功录入退单商品:' + _this.itemInputting.name_goods);
  889. _this.status.endAndPackCommitEdited = false;
  890. _this.lockBillPanel();
  891. _this.getItemsUnderBill(_this.status.editingBill.id);
  892. _this.cleanItem();
  893. $('#barcode_goods').focus();
  894. } else {
  895. if (response.data.error_fields) {
  896. tempTip.setDuration(3000);
  897. tempTip.show('录入失败,字段填写错误');
  898. _this.errors = response.data.error_fields;
  899. } else {
  900. tempTip.show('录入失败:' + response.data.fail_info)
  901. }
  902. }
  903. }).catch(function (response) {
  904. tempTip.setDuration(3000);
  905. tempTip.show('提交失败,请重试:' + response.data.fail_info)
  906. alert('连接错误:' + response)
  907. });
  908. },
  909. isChangeOwner(id_rejected_bill) {
  910. let _this = this;
  911. let url = '{{url('apiLocal/rejectedBillItem/reviseOwner')}}';
  912. window.tempTip.confirm('当前退货记录货主名与录入商品的货主不匹配! ' + '确定校正退货记录货主名吗?', () => {
  913. window.axios.post(url, {
  914. commodityOwnerId: _this.commodityOwnerId,
  915. id_rejected_bill: id_rejected_bill
  916. }).then(res => {
  917. if (res.data.success === 'true') {
  918. let owner_name = '';
  919. _this.owners.forEach(function (owner) {
  920. if (owner.id == _this.commodityOwnerId) {
  921. owner_name = owner.name;
  922. }
  923. })
  924. _this.billInputting.id_owner = _this.commodityOwnerId;
  925. _this.rejectedBills.forEach(function (rejectedBill) {
  926. if (id_rejected_bill == rejectedBill.id) rejectedBill.owner_name = owner_name;
  927. })
  928. } else {
  929. tempTip.setDuration(3000);
  930. tempTip.show(res.data.message);
  931. return;
  932. }
  933. }).catch(err => {
  934. window.tempTip.setDuration(3000);
  935. window.tempTip.show("网络错误:" + err);
  936. return;
  937. });
  938. });
  939. },
  940. endAndPackCommitEdit: function () {
  941. let _this = this;
  942. if (_this.items.length === 0) {
  943. if (confirm('没有填加明细项,确定要退出详细编辑模式吗?')) {
  944. _this.cancelPackCommitEdit();
  945. }
  946. return;
  947. } else {
  948. if (!confirm('确定要提交填加的明细项吗?提交后即不可修改')) {
  949. return;
  950. }
  951. }
  952. let ids = [];
  953. _this.items.forEach(function (item) {
  954. ids.push(item.id);
  955. });
  956. let url = '{{url('apiLocal/rejectedBillItem/packConfirm')}}';
  957. tempTip.setDuration(5000);
  958. tempTip.waitingTip('与外部交互中,请稍候');
  959. axios.post(url, {'ids': ids}).then(function (response) {
  960. _this.cleanError();
  961. tempTip.cancelWaitingTip();
  962. if (response && response.data && response.data.success !== 'false') {
  963. if (response.data.success == 'exception') {
  964. _this.status.lockingIsLoadedInput = true;
  965. _this.billInputting.is_loaded = 3;
  966. tempTip.show('富勒入库异常,请手动校对');
  967. } else if (typeof (response.data.bill_is_loaded) != 'undefined') {
  968. if (response.data.bill_is_loaded === true) {
  969. _this.status.editingBill.is_loaded = 1;
  970. _this.billInputting.is_loaded = 1;
  971. _this.billInputting.isLoadSign = true;
  972. // _this.status.lockingIsLoadedInput=true;
  973. tempTip.okWindow('该批商品状态已改为“入库”', '已处理');
  974. }
  975. }
  976. tempTip.setDuration(5000);
  977. switch (response.data.remote_result) {
  978. case 'fail':
  979. tempTip.show('与客户服务器通讯异常,明细未被外部处理,请联系系统相关同事');
  980. break;
  981. case 'none':
  982. tempTip.show('客户未返回明细处理信息,请联系系统相关同事检查');
  983. break;
  984. case 'received':
  985. tempTip.show('该单之前已提交过给客户服务器');
  986. break;
  987. case 'storable':
  988. tempTip.showSuccess('WMS尚未推单,客户返回可以入库,所以状态为“待推单”', '已处理该待推单');
  989. break;
  990. default:
  991. tempTip.showSuccess('成功录入所有退单商品并已上传至外部');
  992. break;
  993. }
  994. _this.status.endAndPackCommitEdited = true;
  995. _this.cancelPackCommitEdit();
  996. } else {
  997. tempTip.setDuration(4000);
  998. let fail_info = '';
  999. if (response.data)
  1000. fail_info = response.data.fail_info;
  1001. tempTip.show('录入明细列表失败,请重试:' + fail_info)
  1002. }
  1003. }).catch(function (response) {
  1004. tempTip.cancelWaitingTip();
  1005. tempTip.setDuration(3000);
  1006. let fail_info = '';
  1007. if (response.data)
  1008. fail_info = response.data.fail_info;
  1009. tempTip.show('提交失败,请重试:' + fail_info);
  1010. alert('连接错误:' + response)
  1011. });
  1012. },
  1013. cancelPackCommitEdit: function () {
  1014. let _this = this;
  1015. if (_this.items.length === 0 && !_this.status.endAndPackCommitEdited) {
  1016. _this.unlockBillPanel();
  1017. return;
  1018. } else {
  1019. if (_this.status.endAndPackCommitEdited) {
  1020. _this.unlockBillPanel();
  1021. return;
  1022. } else {
  1023. if (!confirm('已填加的明细尚未提交,回到表头编辑将取消已填加明细,是否确定?')) {
  1024. return;
  1025. }
  1026. }
  1027. }
  1028. let ids = [];
  1029. for (let i = _this.status.existItemsBeforeAdd; i < _this.items.length; i++) {
  1030. ids.push(_this.items[i].id);
  1031. }
  1032. if (ids.length === 0) {
  1033. _this.unlockBillPanel();
  1034. return;
  1035. }
  1036. let url = '{{url('apiLocal/rejectedBillItem/packDestroy')}}';
  1037. axios.post(url, {'ids': ids}).then(function (response) {
  1038. _this.cleanError();
  1039. if (response.data.success === 'true') {
  1040. _this.status.editingBill = null;
  1041. _this.unlockBillPanel();
  1042. } else {
  1043. tempTip.show('数据操作失败,请重试:' + response.data.fail_info)
  1044. }
  1045. }).catch(function (response) {
  1046. tempTip.setDuration(3000);
  1047. tempTip.show('提交失败,请重试:' + response.data.fail_info)
  1048. alert('连接错误:' + response)
  1049. });
  1050. },
  1051. lockBillPanel: function () {
  1052. this.status.lockingBillPanel = true;
  1053. $('input,select').blur();
  1054. },
  1055. unlockBillPanel: function () {
  1056. this.status.lockingBillPanel = false;
  1057. this.status.editingBill = null;
  1058. this.status.editingBillId = '';
  1059. this.shiftToCreate();
  1060. },
  1061. getRecentRejectedBills: function () {
  1062. let _this = this;
  1063. let url = '{{url('apiLocal/rejectedBill/apiGetRecent')}}';
  1064. axios.post(url).then(function (response) {
  1065. if (response.data.success === 'true') {
  1066. _this.rejectedBills = response.data.rejectedBills;
  1067. _this.setEditingBill(_this.status.editingBillId)
  1068. } else {
  1069. tempTip.show('加载新增内容失败,可尝试刷新页面');
  1070. }
  1071. }).catch(function (response) {
  1072. alert('连接错误:' + response);
  1073. tempTip.show('加载新增内容失败,可尝试刷新页面!');
  1074. });
  1075. },
  1076. getItemsUnderBill: function (billId, func) {
  1077. let _this = this;
  1078. let url = '{{url('apiLocal/rejectedBillItem/apiGet')}}';
  1079. axios.post(url, {id_rejected_bill: billId}).then(function (response) {
  1080. if (response.data.success === 'true') {
  1081. response.data.items.forEach(function (item) {
  1082. item.isEditing = false;
  1083. });
  1084. _this.items = response.data.items;
  1085. if (typeof func !== 'undefined') {
  1086. func()
  1087. }
  1088. _this.listenEnterAndJump();
  1089. setTimeout(function () {
  1090. $('#barcode_goods').focus();
  1091. }, 500)
  1092. } else {
  1093. tempTip.show('加载相关明细失败,可尝试刷新页面');
  1094. }
  1095. }).catch(function (response) {
  1096. alert('连接错误:' + response);
  1097. tempTip.show('加载相关明细失败,可尝试刷新页面!');
  1098. });
  1099. },
  1100. deleteBill: function (rejectedBill) {
  1101. if (!confirm('确定要删除退货信息“' + rejectedBill.owner_name + ':' + rejectedBill.logistic_number_return + '”吗?')) {
  1102. return;
  1103. }
  1104. let _this = this;
  1105. let url = "{{url('rejectedBill')}}/" + rejectedBill.id;
  1106. axios.delete(url, {id: rejectedBill.id})
  1107. .then(function (response) {
  1108. if (response.data.success) {
  1109. for (let i = 0; i < _this.rejectedBills.length; i++) {
  1110. if (_this.rejectedBills[i].id === rejectedBill.id) {
  1111. _this.rejectedBills.splice(i, 1);
  1112. break;
  1113. }
  1114. }
  1115. tempTip.setDuration(1000);
  1116. tempTip.showSuccess('删除退货信息"' + rejectedBill.owner_name + ':' + rejectedBill.logistic_number_return + '"成功!')
  1117. } else {
  1118. tempTip.setDuration(1000);
  1119. tempTip.show('删除退货信息"' + rejectedBill.owner_name + ':' + rejectedBill.logistic_number_return + '"失败!')
  1120. }
  1121. })
  1122. .catch(function (err) {
  1123. tempTip.setDuration(3000);
  1124. tempTip.show('删除退货信息失败!' + '网络错误:' + err);
  1125. });
  1126. },
  1127. deleteItem: function (e) {
  1128. if (!confirm('确定要删除该明细吗?不可恢复')) {
  1129. return
  1130. }
  1131. let _this = this;
  1132. let id = $(e.target).parents('tr').attr('data-id');
  1133. let url = '{{url('apiLocal/rejectedBillItem/apiDelete')}}';
  1134. axios.post(url, {id: id}).then(function (response) {
  1135. if (response.data.success === 'true') {
  1136. _this.items.forEach(function (item, i) {
  1137. if (item.id + '' === id + '') {
  1138. _this.items.splice(i, 1);
  1139. }
  1140. });
  1141. } else {
  1142. tempTip.show('删除失败,可尝试刷新页面再操作');
  1143. }
  1144. }).catch(function (response) {
  1145. alert('连接错误:' + response);
  1146. tempTip.show('删除失败,可尝试刷新页面!');
  1147. });
  1148. },
  1149. editBill: function (e) {
  1150. let _this = this;
  1151. let billId = $(e.target).parent('tr').attr('data-id');
  1152. let billTarget = '';
  1153. this.rejectedBills.every(function (bill) {
  1154. if (bill.id + '' === billId + '') {
  1155. billTarget = bill;
  1156. return false;
  1157. }
  1158. return true;
  1159. });
  1160. if (billTarget) {
  1161. this.billInputting = JSON.parse(JSON.stringify(billTarget));
  1162. this.shiftToEdit();
  1163. this.setEditingBill(billTarget.id)
  1164. }
  1165. this.getItemsUnderBill(billTarget.id, function () {
  1166. _this.status.existItemsBeforeAdd = _this.items.length;
  1167. });
  1168. },
  1169. editItem: function (e) {
  1170. let _this = this;
  1171. let itemId = $(e.target).parent('tr').attr('data-id');
  1172. let itemTarget = '';
  1173. this.items.every(function (item) {
  1174. if (item.id + '' === itemId + '') {
  1175. itemTarget = item;
  1176. return false;
  1177. }
  1178. return true;
  1179. });
  1180. if (itemTarget) {
  1181. this.itemInputting = JSON.parse(JSON.stringify(itemTarget));
  1182. this.shiftToEditItem();
  1183. this.setEditingItem(itemTarget.id)
  1184. }
  1185. // this.getItemsUnderBill(this.status.editingBillId,function () {});
  1186. },
  1187. shiftToEditItem: function () {
  1188. this.cleanError();
  1189. this.status.itemCreating = false;
  1190. this.status.itemEditing = true;
  1191. setTimeout(function () {
  1192. $('.tooltipOn').tooltip({'trigger': 'hover'});
  1193. }, 50)
  1194. },
  1195. shiftToEdit: function () {
  1196. this.cleanError();
  1197. this.status.billCreating = false;
  1198. this.status.billEditing = true;
  1199. setTimeout(function () {
  1200. $('.tooltipOn').tooltip({'trigger': 'hover'});
  1201. }, 50)
  1202. },
  1203. shiftToCreateItem: function () {
  1204. this.cleanError();
  1205. this.cleanItem();
  1206. this.status.itemCreating = true;
  1207. this.status.itemEditing = false;
  1208. this.items.forEach(function (item) {
  1209. item.isEditing = false;
  1210. });
  1211. $('.tooltipOn').tooltip('hide').tooltip({'trigger': 'hover'});
  1212. },
  1213. shiftToCreate: function () {
  1214. this.cleanError();
  1215. this.cleanHeader();
  1216. this.status.billCreating = true;
  1217. this.status.billEditing = false;
  1218. this.status.editingBill = null;
  1219. this.rejectedBills.forEach(function (rejectedBill) {
  1220. if (rejectedBill.isEditing === true) {
  1221. rejectedBill.isEditing = false;
  1222. return false;
  1223. }
  1224. });
  1225. $('.tooltipOn').tooltip('hide').tooltip({'trigger': 'hover'});
  1226. },
  1227. locateIdOwner: function (e) {
  1228. let _this = this;
  1229. let $target = $(e.target);
  1230. this.owners.forEach(function (owner) {
  1231. if (owner.name.includes($target.val())) {
  1232. _this.billInputting.id_owner = owner.id;
  1233. }
  1234. });
  1235. },
  1236. locateLogistic: function (e) {
  1237. let _this = this;
  1238. let $target = $(e.target);
  1239. this.logistics.forEach(function (logistic) {
  1240. if (logistic.name.includes($target.val())) {
  1241. _this.billInputting.id_logistic_return = logistic.id;
  1242. }
  1243. });
  1244. },
  1245. //根据退回单寻找WMS订单填充已有字段
  1246. seek_order() {
  1247. let _this = this;
  1248. let logistic_number_return = this.billInputting.logistic_number_return;
  1249. if (!logistic_number_return) return;
  1250. axios.post('{{url('apiLocal/rejectedBill/seekOrder')}}', {logistic_number_return: logistic_number_return})
  1251. .then(function (response) {
  1252. if (response.data.success) {
  1253. if (response.data.data.owner_id) _this.billInputting.id_owner = response.data.data.owner_id;
  1254. if (response.data.data.logistic_id) _this.billInputting.id_logistic_return = response.data.data.logistic_id;
  1255. if (response.data.data.consignee_name) _this.billInputting.sender = response.data.data.consignee_name;
  1256. if (response.data.data.consignee_phone) _this.billInputting.mobile_sender = response.data.data.consignee_phone;
  1257. if (response.data.data.client_code) _this.billInputting.order_number = response.data.data.client_code;
  1258. if (response.data.data.logistic_number) _this.billInputting.logistic_number = response.data.data.logistic_number;
  1259. tempTip.setDuration(2000);
  1260. tempTip.showSuccess('原单信息已填充');
  1261. return;
  1262. }
  1263. tempTip.setDuration(2000);
  1264. tempTip.show('没有找到对应的数据,可手动填写 ');
  1265. });
  1266. },
  1267. // 开启摄像头
  1268. enableCamera(enableVideo) {
  1269. this.videoEnabled = enableVideo;
  1270. MediaUtils.getUserMedia(enableVideo, false, function (err, stream) {
  1271. if (err) {
  1272. throw err;
  1273. } else {
  1274. let photo=document.getElementById('photo');
  1275. photo.srcObject = stream;
  1276. photo.play();
  1277. }
  1278. });
  1279. },
  1280. // 关闭摄像头
  1281. closeCamera() {
  1282. let stream = document.getElementById('photo').srcObject;
  1283. let tracks = stream.getTracks();
  1284. tracks.forEach(function(track) {
  1285. track.stop();
  1286. });
  1287. document.getElementById('photo').srcObject = null;
  1288. },
  1289. //拍照
  1290. takePhoto(id,index){
  1291. let photo=document.getElementById('photo');
  1292. let canvas=document.getElementById('canvas');
  1293. //绘制canvas图形
  1294. canvas.getContext('2d').drawImage(photo, 0, 0, 400, 300);
  1295. let img = document.getElementById('canvas').toDataURL();
  1296. // 这里的img就是得到的图片
  1297. this.closeCamera();
  1298. let blob=this.dataUrlToBlob(img);
  1299. this.submitFile(blob,id,index);
  1300. },
  1301. dataUrlToBlob(imgDataUrl) {
  1302. let imgUrl = window.atob(imgDataUrl.split(',')[1])
  1303. let ab = new ArrayBuffer(imgUrl.length)
  1304. let ia = new Uint8Array(ab)
  1305. for (let i = 0; i < imgUrl.length; i++) {
  1306. ia[i] = imgUrl.charCodeAt(i)
  1307. }
  1308. return new Blob([ab],{type:'image/jpeg'})
  1309. },
  1310. submitFile(blob,id,index){
  1311. window.tempTip.setDuration(3000);
  1312. let formData=new FormData();
  1313. formData.append('files[]', blob,'rejected_bill_item'+id+'.jpg')
  1314. formData.append("id",id);
  1315. window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiUpload')}}',formData,res=>{
  1316. if (this.items[index].upload_files.length===0) this.$set(this.items[index],'upload_files',res);
  1317. else this.$set(this.items[index],'upload_files',this.items[index].upload_files.concat(res));
  1318. return "上传成功";
  1319. },false,true);
  1320. },
  1321. removeCommonImg(id){
  1322. $('#'+id).remove();
  1323. },
  1324. commonImg(id,uploadFiles){
  1325. let div = "";
  1326. let isBtn = '@can('运输管理-运单-图片删除') true @endcan ';
  1327. for(let i=0;i<uploadFiles.length;i++){
  1328. let btn = isBtn ? "<button type='button' class='btn btn-sm btn-danger' onclick='vueList.btnDeleteImg(this)' data-url='"+uploadFiles[i].url+"' value='"+id+"' style='position: relative;float: right;margin-top: -30px;' >删除</button>" : "";
  1329. let href = this.imgPrefix+uploadFiles[i].url+'-bulky.'+uploadFiles[i].type;
  1330. let src = this.imgPrefix+uploadFiles[i].url+'-common.'+uploadFiles[i].type;
  1331. div += "<div><a target='_blank' href='"+href+"'><img alt='#' src='"+src+"' style='position: relative;' ></a>"+btn+"</div>"
  1332. }
  1333. $('#'+id).after(
  1334. "<div id=\"common_"+id+"\" style='position: absolute;padding-bottom: 2px;z-index: 99'>" +
  1335. "<div style='position:absolute;left: -50px' class='overflow-y-scrollbar-200'>"+div+
  1336. "</div></div>");
  1337. },
  1338. btnDeleteImg(e){
  1339. let idstr = $(e).val();
  1340. let id = idstr.substr( idstr.indexOf('_')+1);
  1341. let url = e.getAttribute("data-url");
  1342. if (!confirm('确定要删除所选图片吗?'))return;
  1343. this.destroyImg(id,url);
  1344. },
  1345. destroyImg(id,url = null){
  1346. window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiDeleteImg')}}',{id:id,url:url},()=>{
  1347. if (url){
  1348. this.items.some((item,i)=>{
  1349. if (item.id==id){
  1350. item.upload_files.some((file,j)=>{
  1351. if (file.url === url){this.$delete(this.items[i].upload_files,j);return true;}
  1352. });
  1353. return true;
  1354. }
  1355. });
  1356. }else{
  1357. this.items.forEach((item,i)=>{
  1358. if (id.includes(item.id))this.$set(this.items[i],'upload_files',[]);
  1359. });
  1360. }
  1361. return "删除成功";
  1362. });
  1363. },
  1364. },
  1365. filters: {
  1366. isLoaded: function (value) {
  1367. return value == 1 ? '是' : '否';
  1368. },
  1369. dateNoYear: function (value) {
  1370. if (!value) return '';
  1371. return value.substr(5, 11);
  1372. }
  1373. },
  1374. });
  1375. </script>
  1376. @endsection