index.blade.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  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. <span class="ml-1">
  11. <button type="button" class="btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
  12. @click="createOrderIssue(null,false)" style="background: #dad7e8;">生成问题件</button>
  13. </span>
  14. @endcan
  15. @can('订单管理-订单问题件生成')
  16. <span class="ml-1">
  17. <button type="button" class="btn btn-outline-primary btn-sm form-control-sm tooltipTarget"
  18. @click="interceptMessage()">拦截导出</button>
  19. </span>
  20. @endcan
  21. @can('订单管理-订单问题件生成')
  22. <span class="ml-1">
  23. <button type="button" class="btn btn-outline-primary btn-sm form-control-sm tooltipTarget"
  24. @click="modificationMessage()">信息修改导出</button>
  25. </span>
  26. @endcan
  27. @can('订单管理-工单处理-审核')
  28. <span class="ml-1">
  29. <button type="button" class="btn btn-outline-success btn-sm form-control-sm tooltipTarget"
  30. @click="batchReview">
  31. 批量审核
  32. </button>
  33. </span>
  34. @endcan
  35. </div>
  36. <div>
  37. <table class="table table-sm table-striped table-hover table-bordered td-min-width-80" id="table">
  38. <tbody class="">
  39. <template v-for="(item,i) in workOrders">
  40. <tr @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
  41. <td>
  42. <label><input type="checkbox" :value="item.id"></label>
  43. </td>
  44. <td class="text-center">
  45. <span>@{{ i+1 }}</span>
  46. <span v-show="item.is_issue_order" class="badge badge-primary">问题件</span>
  47. </td>
  48. <td class="text-center">
  49. <template v-if="item.status === '已处理'">
  50. <h5><span class="badge badge-secondary"
  51. style="opacity: 0.7">@{{ item.grad }}</span></h5>
  52. </template>
  53. <template v-else>
  54. <h5><span class="badge badge-light" style="opacity: 0.7"
  55. v-if="item.grad === '一般'">@{{ item.grad }}</span></h5>
  56. <h5><span class="badge badge-primary" style="opacity: 0.7"
  57. v-if="item.grad === '重要'">@{{ item.grad }}</span></h5>
  58. <h5><span class="badge badge-warning" style="opacity: 0.7"
  59. v-if="item.grad === '紧急'">@{{ item.grad }}</span></h5>
  60. <h5><span class="badge badge-danger" style="opacity: 0.7"
  61. v-if="item.grad === '重要且紧急'">@{{ item.grad }}</span></h5>
  62. </template>
  63. </td>
  64. <td class="text-center">
  65. @can('订单管理-订单问题件生成')
  66. <button class="btn btn-sm btn-outline-primary" @click="createOrderIssue(item,true)" v-show="!item.is_issue_order ">
  67. 生成问题件
  68. </button>
  69. @endcan
  70. @can('订单管理-工单处理-审核')
  71. <button class="btn btn-sm btn-outline-success" v-show="item.status !== '已处理'" @click="review(item,i)">
  72. 审核
  73. </button>
  74. @endcan
  75. </td>
  76. <td>@{{item.type ? item.type.name : '' }}</td>
  77. <td>@{{item.order ? (item.order.logistic ? item.order.logistic.name : '') : '' }}</td>
  78. <td class="text-center">
  79. <template v-if="item.order">
  80. <template v-if="item.order.packages && item.order.packages.length === 1">
  81. <p>@{{ item.order.packages[0].logistic_number }}</p>
  82. </template>
  83. <template v-else-if="item.order.packages && item.order.packages.length > 0">
  84. <template v-if="selectOrder === item.order.id">
  85. <template v-for="(package,index) in item.order.packages">
  86. @{{ package.logistic_number }}
  87. </template>
  88. </template>
  89. <template v-else>
  90. <p>@{{ item.order.packages[0].logistic_number }}</p>
  91. </template>
  92. <button class="btn btn-sm btn-outline-primary" v-show="selectOrder === null"
  93. @click="selectOrder = item.order.id">
  94. 展开
  95. </button>
  96. <button class="btn btn-sm btn-outline-primary"
  97. v-show="selectOrder === item.order.id"
  98. @click="selectOrder = null">
  99. 收起
  100. </button>
  101. </template>
  102. </template>
  103. </td>
  104. <td class="text-center">
  105. @can('订单管理-工单处理-审核')
  106. <select class="form-control form-control-sm"
  107. :disabled="item.review_at || item.is_issue_order"
  108. :value="item.order_issue_type_id"
  109. @change="changeIssueType(item,$event)" >
  110. <option value="0"></option>
  111. <option v-for="type in orderIssueTypes" :value="type.name">@{{ type.value }}</option>
  112. </select>
  113. @else
  114. @{{ item.issue_type ? item.issue_type.name : '' }}
  115. @endcan
  116. </td>
  117. <td class="text-center">@{{ item.remark }}</td>
  118. <td class="text-center">@{{ item.status }}</td>
  119. <td class="text-center">
  120. <template v-if="item.review_at">
  121. <div v-if="item.order && item.order.packages">
  122. <template v-for="package in item.order.packages">
  123. <template
  124. v-if="package.transfer_status && package.transfer_status.length > 0">
  125. <div v-if="selectOrderPackage === package.id">
  126. <template v-for="transfer in package.transfer_status">
  127. <p>@{{
  128. transfer['accept_time']+':'+transfer['accept_address']
  129. }}</p>
  130. </template>
  131. </div>
  132. <div v-else>
  133. @{{
  134. package.transfer_status[0]['accept_time']+':'+package.transfer_status[0]['accept_address']
  135. }}
  136. </div>
  137. <button class="btn btn-sm btn-outline-primary"
  138. v-if="selectOrderPackage !== package.id"
  139. @click="selectOrderPackage = package.id">展开
  140. </button>
  141. <button class="btn btn-sm btn-outline-primary" v-else
  142. @click="selectOrderPackage = null">收起
  143. </button>
  144. </template>
  145. </template>
  146. </div>
  147. </template>
  148. </td>
  149. <td class="text-center">@{{ item.creator.name }}</td>
  150. <td class="text-center">@{{ item.created_at }}</td>
  151. <td>@{{ item.reviewer ? item.reviewer.name : ''}}</td>
  152. <td>@{{ item.review_at }}</td>
  153. </tr>
  154. </template>
  155. </tbody>
  156. </table>
  157. {{ $workOrders->withQueryString()->links() }}
  158. </div>
  159. </div>
  160. </div>
  161. </div>
  162. @endsection()
  163. @section("lastScript")
  164. <script type="text/javascript" src="{{asset('js/queryForm/queryForm.js')}}"></script>
  165. <script type="text/javascript" src="{{asset('js/queryForm/header.js')}}"></script>
  166. <script>
  167. let list = new Vue({
  168. el: "#list",
  169. data: {
  170. workOrders: {!! $workOrders->toJson() !!}['data'],
  171. selectTr: null,
  172. form: null,
  173. logistics: [
  174. @foreach($logistics as $logistic)
  175. {
  176. name: {{$logistic->id}}, value: '{{$logistic->name}}'
  177. },
  178. @endforeach
  179. ],
  180. orderIssueTypes:[
  181. @foreach($orderIssueTypes as $type)
  182. {name:'{{$type->id}}',value:"{{$type->name}}"},
  183. @endforeach
  184. ],
  185. selectOrderPackage: null,
  186. selectOrder: null,
  187. },
  188. mounted() {
  189. console.log();
  190. let data = [[
  191. {name: 'created_at_start', type: 'time', tip: ['工单创建开始日期', '时间']},
  192. {name: 'created_at_end', type: 'time', tip: ['工单创建结束日期', '时间']},
  193. {
  194. name: 'logistic',
  195. type: 'select_multiple_select',
  196. data: this.logistics,
  197. tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的承运商'],
  198. placeholder: ['承运商', '定位或多选承运商']
  199. },
  200. {name: 'logistic_number', type: 'input', placeholder: '快递单号'},
  201. {
  202. name: 'grad',
  203. type: 'select',
  204. placeholder: '工单等级',
  205. data: [{name: 1, value: '一般'}, {name: 2, value: '重要'}, {name: 3, value: '紧急'}, {
  206. name: 4,
  207. value: '重要且紧急'
  208. },]
  209. },
  210. {
  211. name: 'is_issue_order',
  212. type: 'select',
  213. placeholder: '问题件',
  214. data: [{name: 'true', value: '有'}, {name: 'false', value: '无'}]
  215. },
  216. ], [{name: 'review_at_start', type: 'time', tip: ['工单审核开始日期', '时间']},
  217. {name: 'review_at_end', type: 'time', tip: ['工单审核结束日期', '时间']},
  218. {name: 'is_review', type: 'checkbox', tip: '是否审核', data: [{name: 'true', value: '已审核'}]},
  219. ]];
  220. this.form = new query({
  221. el: '#form_div',
  222. condition: data,
  223. });
  224. this.form.init();
  225. let column = [
  226. {name: 'no', value: '序号', neglect: true},
  227. {name: 'grad', value: '工单等级'},
  228. {name: 'operation', value: '操作', neglect: true},
  229. {name: 'type', value: '相关类型'},
  230. {name: 'logisticName', value: '承运商'},
  231. {name: 'logisticNumber', value: '快递单号'},
  232. {name: 'orderIssueType', value: '问题件类型'},
  233. {name: 'workOrderInfo', value: '问题描述'},
  234. {name: 'status', value: '状态', neglect: true},
  235. {name: 'Info', value: '物流跟踪信息', neglect: true},
  236. {name: 'creator', value: '创建人'},
  237. {name: 'submit_at', value: '提交时间'},
  238. {name: 'reviewer', value: '审核人'},
  239. {name: 'review_at', value: '审核时间'},
  240. ];
  241. new Header({
  242. el: "table",
  243. name: "area",
  244. column: column,
  245. data: this.workOrders,
  246. fixedTop: ($('#form_div').height()) + 2,
  247. }).init();
  248. $("#list").removeClass("d-none");
  249. },
  250. created() {
  251. let self = this;
  252. $.each(this.workOrders, function (index, workOrder) {
  253. if (!workOrder.order) return;
  254. if (!workOrder.order.packages) return;
  255. self.sortOrder(workOrder);
  256. });
  257. },
  258. methods: {
  259. sortOrder(workOrder) {
  260. let self = this;
  261. if (!workOrder.order) return;
  262. if (!workOrder.order.packages) return;
  263. $.each(workOrder.order.packages, function (i, item) {
  264. self.sortTransfer(item);
  265. })
  266. },
  267. sortTransfer(item) {
  268. if (!("transfer_status" in item)) return;
  269. if (item.transfer_status == null || !(item.transfer_status instanceof Array)) return;
  270. item.transfer_status.sort(function (item1, item2) {
  271. let date1 = new Date(item1['accept_time']);
  272. let date2 = new Date(item2['accept_time']);
  273. if (date1 - date2 > 0) return -1;
  274. if (date1 - date2 < 0) return 1;
  275. return 0;
  276. });
  277. },
  278. review(item, i) {
  279. let url = '{{route('workOrder.reviewApi')}}';
  280. let data = {id: item.id};
  281. window.axios.post(url, data).then(res => {
  282. if (res.data.success) {
  283. res.data.data.is_issue_order = item.is_issue_order;
  284. this.$set(this.workOrders, i, res.data.data);
  285. this.sortOrder(res.data.data);
  286. window.tempTip.showSuccess("审核完成");
  287. } else {
  288. window.tempTip.show(res.data.message ? res.data.message : '审核异常');
  289. }
  290. }).catch(err => {
  291. window.tempTip.show(err)
  292. })
  293. },
  294. createOrderIssue(item, tag) { // 生成问题件
  295. let url = '{{route('workOrder.buildOrderIssueApi')}}';
  296. let data = {};
  297. if (tag) data.ids = [item.id];
  298. else data.ids = checkData;
  299. if (!confirm('是否生成对应的问题件')) return;
  300. let _this =this;
  301. window.axios.post(url, data).then(res => {
  302. if (res.data.success) {
  303. res.data.data.forEach(item=>{
  304. this.workOrders.forEach((workOrder,i)=>{
  305. if (item.id === workOrder.id){
  306. _this.sortOrder(item);
  307. _this.$set(_this.workOrders,i,item);
  308. }
  309. });
  310. });
  311. this.$forceUpdate();
  312. window.tempTip.showSuccess('已生成对应的问题件');
  313. } else {
  314. window.tempTip.show(res.data.message ? res.data.message : '生成问题件异常');
  315. }
  316. }).catch(err => {
  317. window.tempTip.show(err)
  318. });
  319. },
  320. getMessageWorkOrder() {
  321. let selected = checkData;
  322. if (!selected) {
  323. window.tempTip.show('未选中任何信息');
  324. return null;
  325. }
  326. return this.workOrders.filter((item) => {
  327. return selected.includes(item.id + '');
  328. });
  329. },
  330. interceptMessage() {
  331. let selectItems = this.getMessageWorkOrder();
  332. if (selectItems === null) return;
  333. let zto_and_sf = '';
  334. let rest_logistic = '';
  335. selectItems.forEach(item => {
  336. // 中通、顺丰
  337. if (item.order.logistic.code.includes('SF') || item.order.logistic.code.includes('ZTO')) {
  338. item.order.packages.forEach(node => {
  339. zto_and_sf += node.logistic_number + '\n';
  340. });
  341. } else {
  342. let item_order_logistic_name = item.order.logistic.name;
  343. let item_order_adder = item.order.consignee_name + ' '
  344. + item.order.consignee_phone + ' '
  345. // + item.order.province + ' ' + item.order.city + ' ' + item.order.district
  346. + ' ' + item.order.address;
  347. item.order.packages.forEach(node => {
  348. rest_logistic += item_order_logistic_name + ' ' + node.logistic_number + ' ' + item_order_adder + ' ——拦截\n';
  349. });
  350. }
  351. });
  352. let text = zto_and_sf.trim('\n') + ' ——拦截' + '\n';
  353. text += rest_logistic;
  354. this.copyText(text);
  355. },
  356. modificationMessage() {
  357. let selectItems = this.getMessageWorkOrder();
  358. if (selectItems === null) return;
  359. let zto = '';
  360. let sf = '';
  361. let rest_logistic = '';
  362. selectItems.forEach(item => {
  363. let logistic_code = item.order.logistic.code;
  364. let adder = item.order.consignee_name + ' ' + item.order.consignee_phone + ' '
  365. + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
  366. item.order.packages.forEach(node => {
  367. if (logistic_code.includes('SF')) { // 顺丰订单
  368. sf += node.logistic_number + ' ——改信息: ' + item.remark + ',运费到付或月结' + '\n';
  369. } else if (logistic_code.includes('ZTO')) {
  370. zto += node.logistic_number + ' ——改信息:' + item.remark + '\n';
  371. } else {
  372. rest_logistic += node.logistic_number + ' ' + adder + ' ——改地址' + item.remark + '\n';
  373. }
  374. });
  375. });
  376. let text = sf + zto + rest_logistic;
  377. this.copyText(text);
  378. },
  379. copyText(text) {
  380. let ele = document.querySelector('#copy_text');
  381. if (ele == null) {
  382. ele = document.createElement("textarea");
  383. ele.setAttribute('id', 'copy_text')
  384. ele.style.opacity = 0;
  385. document.querySelector('body').append(ele);
  386. }
  387. try {
  388. $("#copy_text").text(text).select().focus();
  389. document.execCommand("Copy");
  390. tempTip.showSuccess('复制成功')
  391. } catch (e) {
  392. tempTip.showSuccess('复制失败:' + e)
  393. }
  394. },
  395. batchReview() {
  396. let url = '{{route('workOrder.batchReviewApi')}}';
  397. let data = {ids: checkData};
  398. let _this = this;
  399. window.tempTip.setIndex('1999');
  400. if (!confirm('是否对当前选中订单进行审核')) return;
  401. window.axios.post(url, data).then(res => {
  402. if (res.data.success) {
  403. $.each(res.data.data, (i, data) => {
  404. $.each(_this.workOrders, (index, item) => {
  405. if (item.id === data.id) {
  406. _this.$set(this.workOrders, index, data);
  407. }
  408. });
  409. });
  410. this.$forceUpdate();
  411. window.tempTip.showSuccess('审核完成');
  412. } else {
  413. window.tempTip.show(res.data.message ? res.data.message : '审核出现异常');
  414. }
  415. }).catch(err => {
  416. window.tempTip.show(err);
  417. })
  418. },
  419. changeIssueType(item,e){
  420. let url = '{{route('workOrder.updateIssueTypeApi')}}';
  421. let data = {
  422. id:item.id,
  423. type_id: $(e.target).val()
  424. };
  425. window.axios.post(url,data).then(res=>{
  426. if (res.data.success){
  427. window.tempTip.showSuccess('修改成功');
  428. item.order_issue_type_id = data.type_id;
  429. }else{
  430. window.tempTip.show(res.data.message ? res.data.message : '修改异常');
  431. }
  432. }).catch(err=>{
  433. window.tempTip.show(err);
  434. });
  435. }
  436. },
  437. });
  438. </script>
  439. @endsection