index.blade.php 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. @extends("layouts.app")
  2. @section('title','处理工单')
  3. @section("content")
  4. <div class="container-fluid d-none" id="list">
  5. <div>
  6. <div class="">
  7. <div id="form_div" style="min-width: 1220px;"></div>
  8. <div class="form-inline mt-1" id="btn">
  9. @can('订单管理-订单问题件生成')
  10. <button type="button"
  11. class="ml-1 btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
  12. @click="createOrderIssue(null,false)" style="background: #dad7e8;">生成问题件
  13. </button>
  14. @endcan
  15. @can('订单管理-订单问题件生成')
  16. <button type="button"
  17. class="ml-1 btn btn-outline-primary btn-sm form-control-sm tooltipTarget"
  18. @click="exportText()">导出文本
  19. </button>
  20. @endcan
  21. @can('订单管理-工单处理-审核')
  22. <button type="button"
  23. class="ml-1 btn btn-outline-success btn-sm form-control-sm tooltipTarget"
  24. @click="batchReview">批量审核
  25. </button>
  26. @endcan
  27. <button type="button"
  28. class="ml-1 btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
  29. @click="copyLogisticNumber()" style="background: #dad7e8;">批量复制单号
  30. </button>
  31. @can('订单管理-工单处理-审核')
  32. <button type="button"
  33. class="ml-1 btn btn-outline-success btn-sm form-control-sm tooltipTarget"
  34. @click="showEditIssueType">批量修改问题件类型
  35. </button>
  36. @endcan
  37. </div>
  38. <div>
  39. <table class="table table-sm table-striped table-hover table-bordered td-min-width-80 " id="table">
  40. <tbody class="">
  41. <template v-for="(item,i) in workOrders">
  42. <tr @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
  43. <td>
  44. <label><input type="checkbox" :value="item.id"></label>
  45. </td>
  46. <td class="text-center">
  47. <span v-text="i+1"></span>
  48. <span v-show="item.is_issue_order" class="badge badge-primary">问题件</span>
  49. </td>
  50. <td class="text-left">
  51. @can('订单管理-订单问题件生成')
  52. <button class="btn btn-sm btn-outline-primary"
  53. v-show="!item.is_issue_order "
  54. @click="createOrderIssue(item,true)">生成问题件
  55. </button>
  56. @endcan
  57. @can('订单管理-工单处理-审核')
  58. <button class="btn btn-sm btn-outline-success"
  59. v-show="item.status !== '已处理'"
  60. @click="review(item,i)">审核
  61. </button>
  62. @endcan
  63. @can('订单管理-工单处理-货主编辑')
  64. <button class="btn btn-sm btn-outline-secondary"
  65. v-if="item['issue_type']['name'] ==='快递丢件'"
  66. @click="showFillModel(item,i)">信息填充
  67. </button>
  68. @endcan
  69. @can('订单管理-工单处理-承运商编辑')
  70. <button class="btn btn-sm btn-outline-secondary"
  71. v-if="['快递丢件','破损'].includes(item['issue_type']['name'])"
  72. @click="showEditLog(item,i,2)">快递处理
  73. </button>
  74. @endcan
  75. @can('订单管理-工单处理-宝时编辑')
  76. <button class="btn btn-sm btn-outline-secondary"
  77. v-if="['快递丢件','破损'].includes(item['issue_type']['name'])"
  78. @click="showEditLog(item,i,1)">宝时处理
  79. </button>
  80. @endcan
  81. </td>
  82. <td class="text-center">
  83. @can('订单管理-工单处理-宝时编辑')
  84. <select class="form-control form-control-sm"
  85. :value="item['work_order_status']"
  86. :disabled="item['work_order_status'] === '工单完成'"
  87. @change="updateWorkOrderStatus(item,$event)">
  88. <option value="">无</option>
  89. <option :value="status" v-for="status in workOrderStatus"
  90. v-text="status"></option>
  91. </select>
  92. @else
  93. @{{ item.work_order_status }}
  94. @endcan
  95. </td>
  96. <td class="text-center">@{{ item.status }}</td>
  97. <td class="text-center">@{{ item.owner ? item.owner.name : '' }}</td>
  98. <td class="text-center">@{{ item.order ? item.order.client_code : ''}}</td>
  99. <td>@{{item.order ? (item.order.logistic ? item.order.logistic.name : '') : '' }}</td>
  100. <td class="text-center">
  101. <div v-if="item.order">
  102. <p v-if="item.order.packages && item.order.packages.length === 1"
  103. v-text="item.order.packages[0].logistic_number">
  104. </p>
  105. <div v-else-if="item.order.packages && item.order.packages.length > 0">
  106. <div v-if="selectOrder === item.order.id">
  107. <p v-for="(package,index) in item.order.packages"
  108. v-text="package.logistic_number"></p>
  109. </div>
  110. <div v-else>
  111. <p v-text="item.order.packages[0].logistic_number"></p>
  112. </div>
  113. <button class="btn btn-sm btn-outline-primary"
  114. v-show="selectOrder === null"
  115. @click="selectOrder = item.order.id">展开
  116. </button>
  117. <button class="btn btn-sm btn-outline-primary"
  118. v-show="selectOrder === item.order.id"
  119. @click="selectOrder = null">收起
  120. </button>
  121. </div>
  122. </div>
  123. </td>
  124. <td>
  125. {{-- 承运商处理日志 --}}
  126. <div v-if="item['logistic_log']" class="alert alert-light">
  127. <div>
  128. <span class="text-muted">承运商处理</span>
  129. <button class="btn btn-sm btn-outline-info float-right"
  130. v-show="selectLogisticLogId === item['logistic_log']['id']"
  131. @click="selectLogisticLogId = null">隐藏
  132. </button>
  133. <button class="btn btn-sm btn-outline-info float-right"
  134. v-show="selectLogisticLogId !== item['logistic_log']['id']"
  135. @click="selectLogisticLogId = item['logistic_log']['id']">显示
  136. </button>
  137. </div>
  138. <transition name="fade">
  139. <div v-show="selectLogisticLogId === item['logistic_log']['id']">
  140. <div>
  141. <span class="mr-2">是否赔偿:</span>
  142. <span class="text-truncate"
  143. v-text="item['logistic_log']['is_indemnity']"></span>
  144. </div>
  145. <div v-if="item['logistic_log']['is_indemnity'] === '是'">
  146. <span class="mr-2">赔偿金额:</span>
  147. <span class="text-truncate"
  148. v-text="item['logistic_log']['indemnity']"></span>
  149. </div>
  150. <div v-if="item['logistic_log']['is_indemnity'] === '否'">
  151. <span class="mr-2">不赔偿理由:</span>
  152. <span v-text="item['logistic_log']['remark']"></span>
  153. </div>
  154. </div>
  155. </transition>
  156. </div>
  157. <div v-if="item['process_log']" class="alert alert-light">
  158. <div>
  159. <span class="text-muted">宝时处理</span>
  160. <button class="btn btn-sm btn-outline-info float-right"
  161. v-if="selectBaoShiLogId === item['process_log']['id']"
  162. @click="selectBaoShiLogId = null">隐藏
  163. </button>
  164. <button class="btn btn-sm btn-outline-info float-right"
  165. v-if="selectBaoShiLogId !== item['process_log']['id']"
  166. @click="selectBaoShiLogId = item['process_log']['id']">显示
  167. </button>
  168. </div>
  169. <transition name="fade">
  170. <div v-show="selectBaoShiLogId === item['process_log']['id']">
  171. <div>
  172. <span class="text-muted">是否赔偿: </span>
  173. <span v-text="item['process_log']['is_indemnity']"
  174. class="ml-2 text-truncate"></span></div>
  175. <div v-if="item['process_log']['is_indemnity'] === '是'">
  176. <span class="text-muted">赔偿方:</span>
  177. <span class="text-truncate"
  178. v-text="item['process_log']['indemnitor']"></span>
  179. </div>
  180. <div v-if="item['process_log']['is_indemnity'] === '是'">
  181. <span class="text-muted">赔偿金额:</span>
  182. <span class="ml-2 text-truncate"
  183. v-text="item['process_log']['indemnity']"></span>
  184. </div>
  185. <div v-if="item['process_log']['is_indemnity'] === '否'">
  186. <span class="text-muted">不赔偿理由:</span>
  187. <span class="ml-2" v-text=" item['process_log']['remark']"></span>
  188. </div>
  189. </div>
  190. </transition>
  191. </div>
  192. </td>
  193. <td>
  194. {{-- 工单详情 --}}
  195. @can('订单管理-工单处理-宝时编辑')
  196. @include('order.workOrder._work_order_details')
  197. @elsecan('订单管理-工单处理-承运商编辑')
  198. <template v-if="item.status === '已处理' && item.is_issue_order">
  199. @include('order.workOrder._work_order_details')
  200. </template>
  201. @elsecan('订单管理-工单处理-货主编辑')
  202. @include('order.workOrder._work_order_details')
  203. @endcan
  204. </td>
  205. <td class="text-center">
  206. @can('订单管理-工单处理-审核')
  207. <select class="form-control form-control-sm"
  208. :disabled="item.review_at || item.is_issue_order"
  209. :value="item.order_issue_type_id"
  210. @change="changeIssueType(item,$event)">
  211. <option value="0"></option>
  212. <option v-for="type in orderIssueTypes"
  213. :value="type.name"
  214. v-text="type.value">
  215. </option>
  216. </select>
  217. @else
  218. <span v-text="item['issue_type'] ? item['issue_type'].name : ''"></span>
  219. @endcan
  220. </td>
  221. <td class="text-center">
  222. <span v-text="item.remark"></span>
  223. </td>
  224. <td class="text-center">
  225. <span v-text="item.result_explain ?item.result_explain : ''"></span>
  226. </td>
  227. <td class="text-center">
  228. <span v-text="item.issue_order_type ?item.issue_order_type : ''"></span>
  229. </td>
  230. <td class="text-center p-0">
  231. <template v-if="item.issue_logs">
  232. <template v-if="item.issue_logs.length === 1">
  233. <table class="table table-sm m-0">
  234. <tr class="table table-sm">
  235. <td v-text="item.issue_logs[0].content"></td>
  236. <td v-text="item.issue_logs[0].username"></td>
  237. <td>@{{ item.issue_logs[0].created_at | dataTime }}</td>
  238. </tr>
  239. </table>
  240. </template>
  241. <template v-else-if="item.issue_logs.length > 1">
  242. <transition name="fade">
  243. <table class="table table-sm m-0" v-if="selectOrderIssue === item.id">
  244. <tr v-for="log in item.issue_logs">
  245. <td v-text="log.content"></td>
  246. <td v-text="log.username"></td>
  247. <td>@{{ log.created_at | dataTime }}</td>
  248. </tr>
  249. </table>
  250. </transition>
  251. <transition name="fade">
  252. <table class="table table-sm m-0" v-if="selectOrderIssue !== item.id">
  253. <tr>
  254. <td v-text="item.issue_logs[0].content"></td>
  255. <td v-text="item.issue_logs[0].username"></td>
  256. <td>@{{ item.issue_logs[0].created_at | dataTime }}</td>
  257. </tr>
  258. </table>
  259. </transition>
  260. <button class="btn btn-sm btn-outline-primary"
  261. v-show="selectOrderIssue !== item.id"
  262. @click="selectOrderIssue = item.id">展开
  263. </button>
  264. <button class="btn btn-sm btn-outline-primary"
  265. v-show="selectOrderIssue === item.id"
  266. @click="selectOrderIssue = null">收起
  267. </button>
  268. </template>
  269. </template>
  270. </td>
  271. <td class="text-center">
  272. <div v-if="item.order && item.order.packages">
  273. <template v-for="package in item.order.packages">
  274. <template
  275. v-if="package.transfer_status && package.transfer_status.length > 0">
  276. <div v-if="selectOrderPackage === package.id">
  277. <template v-for="transfer in package.transfer_status">
  278. <p v-text="transfer['accept_time']+':'+transfer['accept_address']"></p>
  279. </template>
  280. </div>
  281. <div v-else v-text="package.transfer_status[0]['accept_time']+':'+package.transfer_status[0]['accept_address']">
  282. </div>
  283. <button class="btn btn-sm btn-outline-primary"
  284. v-if="selectOrderPackage !== package.id"
  285. @click="selectOrderPackage = package.id">展开
  286. </button>
  287. <button class="btn btn-sm btn-outline-primary" v-else
  288. @click="selectOrderPackage = null">收起
  289. </button>
  290. </template>
  291. </template>
  292. </div>
  293. </td>
  294. <td class="text-center" v-text="item.creator ? item.creator.name : ''"></td>
  295. <td class="text-center" v-text="item.created_at"></td>
  296. <td v-text="item.reviewer ? item.reviewer.name : ''"></td>
  297. <td v-text="item.review_at"></td>
  298. @can('订单管理-工单处理-删除')
  299. <td>
  300. <button class="btn btn-sm btn-outline-danger"
  301. @click="destroy(item,i)">
  302. 删除
  303. </button>
  304. </td>
  305. @endcan
  306. </tr>
  307. </template>
  308. </tbody>
  309. </table>
  310. {{ $workOrders->withQueryString()->links() }}
  311. </div>
  312. </div>
  313. @can('订单管理-工单处理-审核')
  314. @include('order.workOrder._edit_issue_type')
  315. @endcan
  316. @include('order.workOrder._fill_loss_work_order')
  317. @include('order.workOrder._edit_process_log')
  318. </div>
  319. </div>
  320. @endsection()
  321. @section("lastScript")
  322. <script type="text/javascript" src="{{asset('js/queryForm/queryForm.js')}}"></script>
  323. <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>
  324. <style>
  325. .fade-enter-active, .fade-leave-active {
  326. transition: opacity .3s;
  327. }
  328. .fade-enter, .fade-leave-to {
  329. opacity: 0;
  330. }
  331. .image-div {
  332. }
  333. .image-w {
  334. width: 100%;
  335. }
  336. </style>
  337. <script>
  338. let list = new Vue({
  339. el: "#list",
  340. data: {
  341. workOrders: {!! $workOrders->toJson() !!}['data'],
  342. form: null,
  343. logistics: [
  344. @foreach($logistics as $logistic)
  345. {
  346. name: {{$logistic->id}}, value: '{{$logistic->name}}'
  347. },
  348. @endforeach
  349. ],
  350. orderIssueTypes: [
  351. @foreach($orderIssueTypes as $type)
  352. {
  353. name: '{{$type->id}}', value: "{{$type->name}}"
  354. },
  355. @endforeach
  356. ],
  357. owners: [
  358. @foreach($owners as $owner)
  359. {
  360. name: '{{$owner->id}}', value: '{{$owner->name}}'
  361. },
  362. @endforeach
  363. ],
  364. workOrder: {
  365. id: null,
  366. index: null,
  367. reissue_logistic_number: null, // 补发单号
  368. logistic_number: null, // 丢件快递单号
  369. refundImages: [], // 退款图
  370. dealImages: [], // 交易图
  371. },
  372. processLog: {
  373. id: null, // log->id
  374. index: '', // 下标
  375. work_order_id: null, // work_order_id
  376. type: null, // 类型
  377. is_indemnity: null, // 是否赔偿
  378. indemnity: null, // 金额
  379. remark: null,
  380. indemnitor: null, // 赔偿方
  381. },
  382. workOrderStatus: ['信息未填写', '信息已填写', '快递已处理', '工单完成'],
  383. selectTr: null,
  384. selectOrderPackage: null,
  385. selectOrder: null,
  386. selectLogisticLogId: null,
  387. selectBaoShiLogId: null,
  388. selectDetailId: null,
  389. selectOrderIssue: null,
  390. selectIssueType: '',
  391. filePrefix: "{{asset("/storage")}}",
  392. },
  393. mounted() {
  394. let data = [[
  395. {name: 'created_at_start', type: 'time', tip: ['工单创建开始日期', '时间']},
  396. {name: 'created_at_end', type: 'time', tip: ['工单创建结束日期', '时间']},
  397. {
  398. name: 'logistic',
  399. type: 'select_multiple_select',
  400. data: this.logistics,
  401. tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的承运商'],
  402. placeholder: ['承运商', '定位或多选承运商']
  403. },
  404. @can('订单管理-订单问题件生成')
  405. {
  406. name: 'owner',
  407. type: 'select_multiple_select',
  408. data: this.owners,
  409. tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的货主'],
  410. placeholder: ['货主', '定位或多选货主']
  411. },
  412. @endcan
  413. {
  414. name: 'logistic_number', type: 'input', placeholder: '快递单号'
  415. },
  416. {
  417. name: 'is_issue_order',
  418. type: 'select',
  419. placeholder: '问题件',
  420. data: [{name: 'true', value: '有'}, {name: 'false', value: '无'}]
  421. },
  422. {name: 'creator', type: 'input', placeholder: '创建人'},
  423. ], [{name: 'review_at_start', type: 'time', tip: ['工单审核开始日期', '时间']},
  424. {name: 'review_at_end', type: 'time', tip: ['工单审核结束日期', '时间']},
  425. {name: 'order_issue_type', type: 'select', placeholder: '问题件类型', data: this.orderIssueTypes},
  426. {name: 'client_code', type: 'input', placeholder: '客户订单号'},
  427. {name: 'is_review', type: 'checkbox', tip: '是否审核', data: [{name: 'true', value: '已审核'}]},
  428. ]];
  429. this.form = new query({
  430. el: '#form_div',
  431. condition: data,
  432. });
  433. this.form.init();
  434. let column = [
  435. {name: 'no', value: '序号', neglect: true},
  436. {name: 'operation', value: '操作', neglect: true},
  437. {name: 'work_order_status', value: '工单状态', neglect: true},
  438. {name: 'status', value: '状态', neglect: true},
  439. {name: 'owner', value: '货主', neglect: true},
  440. {name: 'client_code', value: '订单号', neglect: true},
  441. {name: 'logisticName', value: '承运商', neglect: true},
  442. {name: 'logisticNumber', value: '快递单号'},
  443. {name: 'processLog', value: '处理日志'},
  444. {name: 'workOrderDetails', value: '工单详情'},
  445. {name: 'issueType', value: '问题件类型'},
  446. {name: 'workOrderInfo', value: '问题描述', neglect: true},
  447. {name: 'result_explain', value: '情况说明', neglect: true},
  448. {name: 'orderIssueType', value: '问题件类别'},
  449. {
  450. name: 'orderIssueProcessLogs', type: 'multi', title: "处理结果", rows: [
  451. {value: "内容", col: "4"},
  452. {value: "操作人", col: "4"},
  453. {value: "时间", col: "4"},
  454. ], neglect: true
  455. },
  456. {name: 'Info', value: '物流跟踪信息', neglect: true},
  457. {name: 'creator', value: '创建人', neglect: true},
  458. {name: 'submit_at', value: '提交时间', neglect: true},
  459. {name: 'reviewer', value: '审核人', neglect: true},
  460. {name: 'review_at', value: '审核时间', neglect: true},
  461. @can('订单管理-工单处理-删除')
  462. {name: 'delete_operation', value: '其他操作', neglect: true}
  463. @endcan
  464. ];
  465. new Header({
  466. el: "table",
  467. name: "workOrders",
  468. column: column,
  469. data: this.workOrders,
  470. fixedTop: ($('#form_div').height()) + 2,
  471. }).init();
  472. $("#list").removeClass("d-none");
  473. },
  474. created() {
  475. this.workOrders.forEach(item => {
  476. if (!item.order) return;
  477. if (!item.order.packages) return;
  478. this.sortOrder(item);
  479. });
  480. },
  481. filters: {
  482. dataTime: function (value) {
  483. if (value !== null) {
  484. return moment(value).format('yyyy-MM-DD');
  485. }
  486. return value
  487. },
  488. },
  489. methods: {
  490. sortOrder(workOrder) {
  491. if (!workOrder.order) return;
  492. if (workOrder['order_issue']) {
  493. workOrder.result_explain = workOrder['order_issue'].result_explain;
  494. if (workOrder['order_issue']['issue_type']) {
  495. workOrder.issue_order_type = workOrder['order_issue']['issue_type']['name'];
  496. }
  497. if (workOrder['order_issue'].logs) {
  498. workOrder.issue_logs = this.mapLogs(workOrder['order_issue'].logs);
  499. }
  500. }
  501. if (!workOrder.order.packages) return;
  502. workOrder.order.packages.forEach(item => {
  503. this.sortTransfer(item)
  504. })
  505. },
  506. mapLogs(logs) {
  507. return logs.map(item => {
  508. return {
  509. username: item.user ? item.user.name : '',
  510. content: item.content,
  511. created_at: item.created_at
  512. };
  513. });
  514. },
  515. sortTransfer(item) {
  516. if (!("transfer_status" in item)) return;
  517. if (item.transfer_status == null || !(item.transfer_status instanceof Array)) return;
  518. item.transfer_status.sort(function (item1, item2) {
  519. let date1 = new Date(item1['accept_time']);
  520. let date2 = new Date(item2['accept_time']);
  521. if (date1 - date2 > 0) return -1;
  522. if (date1 - date2 < 0) return 1;
  523. return 0;
  524. });
  525. },
  526. review(item, i) {
  527. let url = '{{route('workOrder.reviewApi')}}';
  528. let data = {id: item.id};
  529. window.axios.post(url, data).then(res => {
  530. if (res.data.success) {
  531. res.data.data.is_issue_order = item.is_issue_order;
  532. this.sortOrder(res.data.data);
  533. this.$set(this.workOrders, i, res.data.data);
  534. window.tempTip.showSuccess("审核完成");
  535. } else {
  536. window.tempTip.show(res.data.message ? res.data.message : '审核异常');
  537. }
  538. }).catch(err => {
  539. window.tempTip.show(err)
  540. })
  541. },
  542. createOrderIssue(item, tag) { // 生成问题件
  543. let url = '{{route('workOrder.buildOrderIssueApi')}}';
  544. let data = {};
  545. if (tag) data.ids = [item.id];
  546. else data.ids = checkData;
  547. if (!confirm('是否生成对应的问题件')) return;
  548. window.tempTip.waitingTip('生成中........');
  549. window.axios.post(url, data).then(res => {
  550. if (res.data.success) {
  551. this.replaceWorkOrder(res.data.data);
  552. this.$forceUpdate();
  553. window.tempTip.cancelWaitingTip();
  554. window.tempTip.showSuccess('已生成对应的问题件');
  555. } else {
  556. window.tempTip.cancelWaitingTip();
  557. window.tempTip.show(res.data.message ? res.data.message : '生成问题件异常');
  558. }
  559. }).catch(err => {
  560. window.tempTip.cancelWaitingTip();
  561. window.tempTip.show(err)
  562. });
  563. },
  564. replaceWorkOrder(workOrders) {
  565. let data = [];
  566. workOrders.forEach(workOrder => {
  567. data[workOrder.id] = workOrder;
  568. });
  569. this.workOrders.forEach((workOrder, i) => {
  570. if (data[workOrder.id]) {
  571. let item = data[workOrder.id];
  572. this.sortOrder(item);
  573. this.$set(this.workOrders, i, item);
  574. }
  575. });
  576. this.$forceUpdate();
  577. },
  578. getMessageWorkOrder() {
  579. let selected = checkData;
  580. if (!selected) {
  581. window.tempTip.show('未选中任何信息');
  582. return null;
  583. }
  584. return this.workOrders.filter((item) => {
  585. if (!item.order) return false;
  586. if (!item.order.packages) return false;
  587. return selected.includes(item.id + '');
  588. });
  589. },
  590. exportText() {
  591. let items = this.getMessageWorkOrder();
  592. if (items == null) return;
  593. let text = '';
  594. items.forEach(item => {
  595. if (item.order) text += this.getExportText(item);
  596. });
  597. this.copyText(text);
  598. },
  599. getExportText(item) {
  600. if (!item.order) return '';
  601. if (!item.order.packages) return '';
  602. let message = '';
  603. let issue_type = item['issue_type'] ? item['issue_type'].name : '';
  604. switch (issue_type) {
  605. case '拦截':
  606. message = this.interceptMessage(item);
  607. break;
  608. case '信息更改':
  609. message = this.modificationMessage(item);
  610. break;
  611. default:
  612. message = this.getMessage(item);
  613. break;
  614. }
  615. return message;
  616. },
  617. interceptMessage(item) {
  618. let message = '';
  619. if (item.order['logistic']['code'].includes('SF') || item.order['logistic'].code.includes('ZTO')) {
  620. item.order.packages.forEach(node => {
  621. message += node.logistic_number + '\n';
  622. });
  623. message = message.trim('\n') + ' ——拦截\n';
  624. } else {
  625. let item_order_logistic_name = item.order['logistic']['name'];
  626. let item_order_adder = item.order['consignee_name'] + ' '
  627. + item.order['consignee_phone'] + ' '
  628. + ' ' + item.order.address;
  629. item.order.packages.forEach(p => {
  630. if (p) message += item_order_logistic_name + ' ' + p.logistic_number + ' ' + item_order_adder + '\n';
  631. });
  632. message = message.trim('\n') + ' ——拦截\n';
  633. }
  634. return message;
  635. },
  636. modificationMessage(item) {
  637. let message = '';
  638. let logistic_code = item.order['logistic']['code'];
  639. let adder = item.order['consignee_name'] + ' ' + item.order['consignee_phone'] + ' '
  640. + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
  641. item.order.packages.forEach(node => {
  642. if (logistic_code.includes('SF')) { // 顺丰订单
  643. message += node['logistic_number'] + ' ——改信息: ' + item.remark + ',运费到付或月结' + '\n';
  644. } else if (logistic_code.includes('ZTO')) {
  645. message += node['logistic_number'] + ' ——改信息:' + item.remark + '\n';
  646. } else {
  647. message += node['logistic_number'] + ' ' + adder + ' ——改地址' + item.remark + '\n';
  648. }
  649. });
  650. return message;
  651. },
  652. getMessage(item) {
  653. let message = '';
  654. if (!item.order.packages) return message;
  655. let adder = item.order['consignee_name'] + ' ' + item.order['consignee_phone'] + ' '
  656. + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
  657. item.order.packages.forEach(p => {
  658. message += p.logistic_number + ' ' + adder + ' ——描述 ' + item.remark + '\n';
  659. });
  660. return message;
  661. },
  662. copyText(text) {
  663. let ele = document.querySelector('#copy_text');
  664. if (ele == null) {
  665. ele = document.createElement("textarea");
  666. ele.setAttribute('id', 'copy_text')
  667. ele.style.opacity = 0;
  668. document.querySelector('body').append(ele);
  669. }
  670. try {
  671. $("#copy_text").text(text).select().focus();
  672. document.execCommand("Copy");
  673. tempTip.showSuccess('复制成功')
  674. } catch (e) {
  675. tempTip.showSuccess('复制失败:' + e)
  676. }
  677. },
  678. batchReview() {
  679. let url = '{{route('workOrder.batchReviewApi')}}';
  680. let data = {ids: checkData};
  681. window.tempTip.setIndex('1999');
  682. if (!confirm('是否对当前选中订单进行审核')) return;
  683. window.tempTip.waitingTip('审核中........');
  684. window.axios.post(url, data).then(res => {
  685. if (res.data.success) {
  686. this.replaceWorkOrder(res.data.data);
  687. this.$forceUpdate();
  688. window.tempTip.cancelWaitingTip();
  689. window.tempTip.showSuccess('审核完成');
  690. } else {
  691. window.tempTip.cancelWaitingTip();
  692. window.tempTip.show(res.data.message ? res.data.message : '审核出现异常');
  693. }
  694. }).catch(err => {
  695. window.tempTip.cancelWaitingTip();
  696. window.tempTip.show(err);
  697. })
  698. },
  699. changeIssueType(item, e) {
  700. let url = '{{route('workOrder.updateIssueTypeApi')}}';
  701. let data = {
  702. id: item.id,
  703. type_id: $(e.target).val()
  704. };
  705. window.tempTip.waitingTip('修改中.........');
  706. window.axios.post(url, data).then(res => {
  707. if (res.data.success) {
  708. window.tempTip.cancelWaitingTip();
  709. window.tempTip.showSuccess('修改成功');
  710. item.order_issue_type_id = data.type_id;
  711. } else {
  712. window.tempTip.cancelWaitingTip();
  713. window.tempTip.show(res.data.message ? res.data.message : '修改异常');
  714. }
  715. }).catch(err => {
  716. window.tempTip.cancelWaitingTip();
  717. window.tempTip.show(err);
  718. });
  719. },
  720. copyLogisticNumber() {
  721. let items = this.getMessageWorkOrder();
  722. let logistic_numbers = '';
  723. items.forEach(item => {
  724. item.order.packages.forEach(node => {
  725. logistic_numbers += node.logistic_number + '\n';
  726. });
  727. })
  728. this.copyText(logistic_numbers);
  729. },
  730. showEditIssueType() {
  731. this.selectIssueType = 0;
  732. $("#edit-issue-type-type-modal").modal('show');
  733. },
  734. editOrderIssueType() {
  735. let url = '{{route('workOrder.batchUpdateIssueTypeApi')}}'
  736. let data = {ids: checkData, type: this.selectIssueType};
  737. window.tempTip.setIndex(1999);
  738. window.axios.post(url, data).then(res => {
  739. if (res.data.success) {
  740. window.tempTip.showSuccess('修改问题件类型成功');
  741. this.replaceWorkOrder(res.data.data);
  742. $("#edit-issue-type-type-modal").modal('hide');
  743. return;
  744. }
  745. window.tempTip.show(res.data.message ? res.data.message : '修改异常');
  746. }).catch(err => {
  747. window.tempTip.show(err)
  748. })
  749. },
  750. destroy(item, i) {
  751. let url = '{{url('apiLocal/workOrder/')}}' + '/' + item.id;
  752. if (!confirm('是否删除当前工单')) return;
  753. window.tempTip.waitingTip('删除.........');
  754. window.axios.delete(url).then(res => {
  755. if (res.data.success) {
  756. this.$delete(this.workOrders, i);
  757. window.tempTip.cancelWaitingTip();
  758. window.tempTip.showSuccess('删除成功');
  759. } else {
  760. window.tempTip.cancelWaitingTip();
  761. window.tempTip.show(res.data.message ? res.data.message : '');
  762. }
  763. }).catch(err => {
  764. window.tempTip.cancelWaitingTip();
  765. window.tempTip.show(err);
  766. })
  767. },
  768. pushImagesAndShow(e, images) {
  769. let map = [];
  770. for (let i = 0; i < e.target.files.length; i++) {
  771. let image = e.target.files[i];
  772. if (this.imageExist(image, images)) {
  773. map.push(image.name);
  774. continue;
  775. }
  776. let src = window.URL.createObjectURL(image);
  777. images.push({src: src, file: image});
  778. }
  779. e.target.value = '';
  780. if (map.length === 0) return;
  781. window.tempTip.setIndex(1999);
  782. window.tempTip.show(map.join('\n,') + '图片重复');
  783. },
  784. spliceImage(i, images) {
  785. if (!confirm('是否取消选择该图片')) return;
  786. images.splice(i, 1);
  787. },
  788. imageExist(image, images) {
  789. let arr = images.filter(item => {
  790. return item.file.name === image.name;
  791. });
  792. return arr.length > 0;
  793. },
  794. showFillModel(item, index) {
  795. this.workOrder.id = item.id;
  796. this.workOrder.index = index;
  797. this.workOrder.reissue_logistic_number = null; // 补发单号
  798. this.workOrder.logistic_number = null; // 补发单号
  799. this.workOrder.dealImages = []; // 交易图
  800. this.workOrder.refundImages = []; // 退款图
  801. $("#fill-loss-work-order-modal").modal('show');
  802. },
  803. updateLossWorkOrder() {
  804. let formData = new FormData();
  805. formData.append('id', this.workOrder.id);
  806. formData.append('reissue_logistic_number', this.workOrder.reissue_logistic_number);
  807. formData.append('logistic_number', this.workOrder.logistic_number);
  808. formData.append('price', this.workOrder.price);
  809. let dealImages = this.getImages(this.workOrder.dealImages);
  810. let refundImages = this.getImages(this.workOrder.refundImages);
  811. this.setFormDataImagePrefix(formData, 'dealImages', dealImages);
  812. this.setFormDataImagePrefix(formData, 'refundImages', refundImages);
  813. this.fillLossWorkOrder(formData);
  814. },
  815. setFormDataImagePrefix(formData, prefix, images) {
  816. images.forEach((item, i) => {
  817. formData.append(`${prefix}[]`, item);
  818. });
  819. },
  820. getImages(images) {
  821. return images.map((item) => {
  822. return item.file;
  823. })
  824. },
  825. fillLossWorkOrder(data) {
  826. let url = "{{route('workOrder.lossApi')}}";
  827. window.tempTip.setIndex(1999);
  828. window.axios.post(url, data, {'Content-Type': 'multipart/form-data'}).then(res => {
  829. if (res.data.success) {
  830. this.sortOrder(res.data.data);
  831. this.$set(this.workOrders, this.workOrder.index, res.data.data);
  832. window.tempTip.showSuccess('工单信息填充成功');
  833. } else {
  834. window.tempTip.show(res.data.message);
  835. }
  836. }).catch(err => {
  837. window.tempTip.show(err);
  838. });
  839. },
  840. showEditLog(item, index, type) {
  841. this.processLog.type = type;
  842. this.processLog.index = index;
  843. this.processLog.work_order_id = item.id;
  844. this.processLog.indemnity = null;
  845. this.processLog.is_indemnity = null;
  846. this.processLog.remark = null;
  847. this.processLog.indemnitor = null;
  848. $("#work-order-process-log-modal").modal('show');
  849. },
  850. storeLogisticProcessLog() {
  851. let url = "{{route('workOrderProcessLog.logisticLogApi')}}";
  852. let data = {
  853. indemnity: this.processLog.indemnity,
  854. work_order_id: this.processLog.work_order_id,
  855. is_indemnity: this.processLog.is_indemnity,
  856. remark: this.processLog.remark,
  857. };
  858. if (!this.verifiedProcessLog()) return;
  859. window.tempTip.setDuration(9999);
  860. window.tempTip.setIndex(1999);
  861. window.tempTip.waitingTip('操作中请稍后');
  862. window.axios.post(url, data).then(res => {
  863. window.tempTip.cancelWaitingTip();
  864. window.tempTip.setIndex(1999);
  865. window.tempTip.setDuration(2000);
  866. if (res.data.success) {
  867. window.tempTip.showSuccess('创建成功');
  868. this.$set(this.workOrders[this.processLog.index], 'logistic_log', res.data.data);
  869. $('#work-order-process-log-modal').modal('hide');
  870. } else {
  871. window.tempTip.show(res.data.message ? res.data.message : '创建异常,刷新页面重试');
  872. }
  873. }).catch(err => {
  874. window.tempTip.setIndex(1999);
  875. window.tempTip.setDuration(2000);
  876. window.tempTip.show(err);
  877. });
  878. },
  879. storeProcessLog() {
  880. let url = "{{route('workOrderProcessLog.LogApi')}}";
  881. let data = {
  882. indemnity: this.processLog.indemnity,
  883. work_order_id: this.processLog.work_order_id,
  884. is_indemnity: this.processLog.is_indemnity,
  885. remark: this.processLog.remark,
  886. indemnitor: this.processLog.indemnitor,
  887. };
  888. if (!this.verifiedProcessLog()) return;
  889. window.tempTip.setDuration(9999);
  890. window.tempTip.setIndex(1999);
  891. window.tempTip.waitingTip('操作中请稍后');
  892. window.axios.post(url, data).then(res => {
  893. window.tempTip.cancelWaitingTip();
  894. window.tempTip.setDuration(2000);
  895. if (res.data.success) {
  896. window.tempTip.showSuccess('创建成功');
  897. this.$set(this.workOrders[this.processLog.index], 'process_log', res.data.data);
  898. $('#work-order-process-log-modal').modal('hide');
  899. } else {
  900. window.tempTip.show(res.data.message ? res.data.message : '创建异常,刷新页面重试');
  901. }
  902. }).catch(err => {
  903. window.tempTip.setDuration(2000);
  904. window.tempTip.show(err);
  905. });
  906. },
  907. updateWorkOrderStatus(item, e, i) {
  908. let url = "{{route('workOrder.updateWorkOrderStatusApi')}}";
  909. let data = {
  910. id: item.id,
  911. work_order_status: e.target.value
  912. }
  913. window.tempTip.waitingTip('处理中......');
  914. window.tempTip.setDuration('1999');
  915. window.axios.post(url, data).then(res => {
  916. window.tempTip.cancelWaitingTip();
  917. window.tempTip.setDuration('1999');
  918. if (res.data.success) {
  919. item.work_order_status = data.work_order_status;
  920. window.tempTip.showSuccess('修改成功');
  921. return;
  922. }
  923. window.tempTip.show(res.data.message ? res.data.message : '修改失败');
  924. }).catch(err => {
  925. window.tempTip.show('修饰异常:' + err);
  926. });
  927. },
  928. verifiedProcessLog() { // 校验处理信息
  929. window.tempTip.setIndex(1999);
  930. window.tempTip.setDuration(2000);
  931. if (this.processLog.is_indemnity === null) {
  932. window.tempTip.show('选择处理方式');
  933. return false;
  934. }
  935. if (parseInt(this.processLog.type) === 1 && this.processLog.indemnitor == null) {
  936. window.tempTip.show('指定赔偿方');
  937. return false;
  938. }
  939. if (this.processLog.is_indemnity === '1') {
  940. if (!this.processLog.indemnity) {
  941. window.tempTip.show('填写赔偿金额');
  942. return false;
  943. }
  944. } else if (this.processLog.is_indemnity === '2') {
  945. if (this.processLog.remark === null || this.processLog.remark.trim(' ').length === 0) {
  946. window.tempTip.show('填写不赔偿理由');
  947. return false;
  948. }
  949. }
  950. return true;
  951. }
  952. },
  953. });
  954. </script>
  955. @endsection