index.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. <template>
  2. <el-card class="box-card">
  3. <byTable
  4. :source="sourceList.data"
  5. :pagination="sourceList.pagination"
  6. :config="config"
  7. :loading="loading"
  8. :searchConfig="searchConfig"
  9. highlight-current-row
  10. :defaultExpandAll="true"
  11. :table-events="{
  12. select: selectRow,
  13. 'select-all': selectRow,
  14. }"
  15. :action-list="[
  16. {
  17. text: '拆分包裹',
  18. action: () => clickUnpack(),
  19. },
  20. {
  21. text: '合并订单',
  22. action: () => clickMerge(),
  23. },
  24. {
  25. text: '取消合并',
  26. action: () => clickUnMerge(),
  27. },
  28. {
  29. text: '修改收件信息',
  30. action: () => clickModifyInformation(),
  31. },
  32. {
  33. text: '修改快递',
  34. action: () => clickModifiedExpress(),
  35. },
  36. {
  37. text: '打印快递单',
  38. action: () => clickPrint(),
  39. type: 'warning',
  40. },
  41. // {
  42. // text: '填写线下快递单号',
  43. // action: () => clickFillInExpressCode(),
  44. // },
  45. ]"
  46. @get-list="getList"
  47. @clickReset="clickReset">
  48. <template #typeExpand="{ item }">
  49. <div class="remark" v-html="item.remark"></div>
  50. </template>
  51. <template #code="{ item }">
  52. <div>
  53. <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="clickCode(item)">{{ item.code }}</a>
  54. </div>
  55. </template>
  56. <template #groupOrderCodeList="{ item }">
  57. <div>
  58. <div v-if="item.groupOrderCodeList && item.groupOrderCodeList.length > 0">{{ item.groupOrderCodeList.join(",") }}</div>
  59. </div>
  60. </template>
  61. <template #total="{ item }">
  62. <div>
  63. <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="clickTotal(item)">{{ item.total }}</a>
  64. </div>
  65. </template>
  66. <template #address="{ item }">
  67. <div>{{ item.province }},{{ item.city }},{{ item.county }},{{ item.detailedAddress }}</div>
  68. </template>
  69. </byTable>
  70. <el-dialog title="包裹规格数据" v-if="openTotal" v-model="openTotal" width="90%">
  71. <PackTotal :rowData="rowData" @clickCancel="clickCancel"></PackTotal>
  72. </el-dialog>
  73. <el-dialog title="包裹图片" v-if="openPackagePicture" v-model="openPackagePicture" width="70%">
  74. <div v-loading="loadingPackagePicture">
  75. <el-upload
  76. v-model:file-list="fileList"
  77. action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
  78. list-type="picture-card"
  79. multiple
  80. :data="uploadData"
  81. :before-upload="beforeUpload"
  82. :on-preview="onPreview">
  83. <el-icon><Plus /></el-icon>
  84. </el-upload>
  85. </div>
  86. <template #footer>
  87. <el-button @click="openPackagePicture = false" size="large">取 消</el-button>
  88. <el-button type="primary" @click="submitPicture()" size="large" v-preReClick>提 交</el-button>
  89. </template>
  90. </el-dialog>
  91. <el-dialog title="合并订单" v-if="openMerge" v-model="openMerge" width="500">
  92. <el-form :model="formMerge.data" :rules="rulesMerge" label-width="100px" ref="refMerge">
  93. <el-form-item label="主订单号" prop="id">
  94. <el-select v-model="formMerge.data.id" placeholder="请选择" style="width: 100%">
  95. <el-option v-for="item in selectData" :key="item.id" :label="item.code" :value="item.id"> </el-option>
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item label="合并订单号" prop="mergeIdList">
  99. <el-select v-model="formMerge.data.mergeIdList" placeholder="请选择" style="width: 100%" multiple :disabled="!formMerge.data.id">
  100. <el-option v-for="item in selectData.filter((item) => item.id !== formMerge.data.id)" :key="item.id" :label="item.code" :value="item.id" />
  101. </el-select>
  102. </el-form-item>
  103. </el-form>
  104. <template #footer>
  105. <el-button @click="openMerge = false" size="large">取 消</el-button>
  106. <el-button type="primary" @click="submitMerge()" size="large" v-preReClick>提 交</el-button>
  107. </template>
  108. </el-dialog>
  109. <el-dialog title="修改收件信息" v-if="openInformation" v-model="openInformation" width="600">
  110. <el-form :model="formInformation.data" :rules="rulesInformation" label-width="120px" ref="refInformation">
  111. <el-form-item label="省" prop="province">
  112. <el-input v-model="formInformation.data.province" placeholder="请输入省" />
  113. </el-form-item>
  114. <el-form-item label="市" prop="city">
  115. <el-input v-model="formInformation.data.city" placeholder="请输入市" />
  116. </el-form-item>
  117. <el-form-item label="区/县" prop="county">
  118. <el-input v-model="formInformation.data.county" placeholder="请输入区/县" />
  119. </el-form-item>
  120. <el-form-item label="详细地址" prop="detailedAddress">
  121. <el-input v-model="formInformation.data.detailedAddress" placeholder="请输入详细地址" />
  122. </el-form-item>
  123. <el-form-item label="收货人" prop="consignee">
  124. <el-input v-model="formInformation.data.consignee" placeholder="请输入收货人" />
  125. </el-form-item>
  126. <el-form-item label="收货人电话" prop="consigneeNumber">
  127. <el-input v-model="formInformation.data.consigneeNumber" placeholder="请输入收货人电话" />
  128. </el-form-item>
  129. </el-form>
  130. <template #footer>
  131. <el-button @click="openInformation = false" size="large">取 消</el-button>
  132. <el-button type="primary" @click="submitInformation()" size="large" v-preReClick>保 存</el-button>
  133. </template>
  134. </el-dialog>
  135. <el-dialog title="修改快递" v-if="openExpress" v-model="openExpress" width="500">
  136. <el-form :model="formExpress.data" :rules="rulesExpress" label-width="100px" ref="refExpress">
  137. <el-form-item label="快递" prop="expressDeliveryId">
  138. <el-select v-model="formExpress.data.expressDeliveryId" placeholder="请选择快递" style="width: 100%">
  139. <el-option v-for="item in expressDeliveryList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
  140. </el-select>
  141. </el-form-item>
  142. </el-form>
  143. <template #footer>
  144. <el-button @click="openExpress = false" size="large">取 消</el-button>
  145. <el-button type="primary" @click="submitExpress()" size="large" v-preReClick>保 存</el-button>
  146. </template>
  147. </el-dialog>
  148. <el-dialog title="修改快递单号" v-if="openExpressCode" v-model="openExpressCode" width="500">
  149. <el-form :model="formExpressCode.data" :rules="rulesExpressCode" label-width="100px" ref="refExpressCode">
  150. <el-form-item label="快递单号" prop="trackingNumber">
  151. <el-input v-model="formExpressCode.data.trackingNumber" placeholder="请输入快递单号" />
  152. </el-form-item>
  153. </el-form>
  154. <template #footer>
  155. <el-button @click="openExpressCode = false" size="large">取 消</el-button>
  156. <el-button type="primary" @click="submitExpressCode()" size="large" v-preReClick>保 存</el-button>
  157. </template>
  158. </el-dialog>
  159. <el-dialog title="打印快递面单" v-if="openPrint" v-model="openPrint" width="80%">
  160. <el-table :data="orderEncasementList" :row-style="{ height: '35px' }" :cell-style="{ padding: '0' }" header-row-class-name="tableHeader">
  161. <el-table-column label="订单号" align="center">
  162. <template #default="{}">
  163. <div>
  164. {{ selectData[0].code }}
  165. </div>
  166. </template>
  167. </el-table-column>
  168. <el-table-column label="包裹单号" prop="number" align="center" />
  169. <el-table-column label="快递单号" prop="trackingNumber" align="center" />
  170. <el-table-column label="商品总数" align="center">
  171. <template #default="{ row }">
  172. <div>
  173. <span v-if="row.orderEncasementDetailList && row.orderEncasementDetailList.length > 0">
  174. {{
  175. row.orderEncasementDetailList
  176. .map((item) => item.quantity)
  177. .reduce(function (prev, cur) {
  178. return prev + cur;
  179. }, 0)
  180. }}
  181. </span>
  182. <span v-else>0</span>
  183. </div>
  184. </template>
  185. </el-table-column>
  186. <el-table-column label="净重(kg)" align="center">
  187. <template #default="{ row }">
  188. <div>
  189. {{ row.netWeight / 1000 }}
  190. </div>
  191. </template>
  192. </el-table-column>
  193. <el-table-column label="体积(m³)" align="center">
  194. <template #default="{ row }">
  195. <div>
  196. {{ (row.length * row.width * row.height) / 1000000 }}
  197. </div>
  198. </template>
  199. </el-table-column>
  200. <el-table-column label="操作" align="center" width="220">
  201. <template #default="{ row }">
  202. <div>
  203. <el-button type="primary" @click="clickNewbiePrint(row)" text v-preReClick>打印面单</el-button>
  204. <el-button type="primary" @click="clickFillInExpressCode(row)" text v-preReClick>填写线下快递单号</el-button>
  205. </div>
  206. </template>
  207. </el-table-column>
  208. </el-table>
  209. <template #footer>
  210. <el-button @click="openPrint = false" size="large">关 闭</el-button>
  211. </template>
  212. </el-dialog>
  213. </el-card>
  214. </template>
  215. <script setup>
  216. import byTable from "/src/components/byTable/index";
  217. import { ElMessage } from "element-plus";
  218. import PackTotal from "/src/views/production/shipment/print-order/packTotal.vue";
  219. const { proxy } = getCurrentInstance();
  220. const departmentList = ref([]);
  221. const expressDeliveryList = ref([]);
  222. const sourceList = ref({
  223. data: [],
  224. pagination: {
  225. total: 0,
  226. pageNum: 1,
  227. pageSize: 10,
  228. code: "",
  229. departmentId: "",
  230. printStatus: "",
  231. beginTime: "",
  232. endTime: "",
  233. },
  234. });
  235. const loading = ref(false);
  236. const searchConfig = computed(() => {
  237. return [
  238. {
  239. type: "input",
  240. prop: "code",
  241. label: "订单号",
  242. },
  243. {
  244. type: "select",
  245. prop: "departmentId",
  246. data: departmentList.value,
  247. label: "事业部",
  248. },
  249. {
  250. type: "select",
  251. prop: "printStatus",
  252. data: [
  253. {
  254. dictKey: "1",
  255. dictValue: "是",
  256. },
  257. {
  258. dictKey: "0",
  259. dictValue: "否",
  260. },
  261. ],
  262. label: "打印状态",
  263. },
  264. {
  265. type: "date",
  266. propList: ["beginTime", "endTime"],
  267. label: "交期",
  268. },
  269. ];
  270. });
  271. const config = computed(() => {
  272. return [
  273. {
  274. type: "expand",
  275. attrs: {
  276. label: " ",
  277. slot: "typeExpand",
  278. width: 50,
  279. },
  280. },
  281. {
  282. type: "selection",
  283. attrs: {
  284. checkAtt: "isCheck",
  285. },
  286. },
  287. // {
  288. // attrs: {
  289. // label: "日期",
  290. // slot: "backupDateStr",
  291. // width: 220,
  292. // align: "center",
  293. // },
  294. // },
  295. {
  296. attrs: {
  297. label: "主订单号",
  298. slot: "code",
  299. width: 160,
  300. },
  301. },
  302. {
  303. attrs: {
  304. label: "合并订单号",
  305. slot: "groupOrderCodeList",
  306. width: 160,
  307. },
  308. },
  309. {
  310. attrs: {
  311. label: "总包裹数",
  312. slot: "total",
  313. width: 90,
  314. },
  315. },
  316. {
  317. attrs: {
  318. label: "事业部",
  319. prop: "departmentName",
  320. width: 130,
  321. },
  322. },
  323. {
  324. attrs: {
  325. label: "快递",
  326. prop: "expressDeliveryName",
  327. width: 130,
  328. },
  329. },
  330. {
  331. attrs: {
  332. label: "店铺来源",
  333. prop: "sourcePlatform",
  334. width: 120,
  335. },
  336. },
  337. {
  338. attrs: {
  339. label: "店铺名称",
  340. prop: "shopName",
  341. width: 140,
  342. },
  343. },
  344. {
  345. attrs: {
  346. label: "下单时间",
  347. prop: "createTime",
  348. width: 160,
  349. align: "center",
  350. },
  351. },
  352. {
  353. attrs: {
  354. label: "交期",
  355. prop: "deliveryTime",
  356. width: 160,
  357. align: "center",
  358. },
  359. },
  360. {
  361. attrs: {
  362. label: "收货人",
  363. prop: "consignee",
  364. width: 120,
  365. },
  366. },
  367. {
  368. attrs: {
  369. label: "收货人电话",
  370. prop: "consigneeNumber",
  371. width: 160,
  372. },
  373. },
  374. {
  375. attrs: {
  376. label: "收货地址",
  377. slot: "address",
  378. width: 300,
  379. },
  380. },
  381. {
  382. attrs: {
  383. label: "总净重(kg)",
  384. prop: "totalNetWeight",
  385. width: 120,
  386. fixed: "right",
  387. },
  388. render(val) {
  389. if (val) {
  390. return val / 1000;
  391. }
  392. },
  393. },
  394. {
  395. attrs: {
  396. label: "总体积(m³)",
  397. prop: "totalVolume",
  398. width: 120,
  399. fixed: "right",
  400. },
  401. },
  402. {
  403. attrs: {
  404. label: "操作",
  405. width: 100,
  406. align: "center",
  407. fixed: "right",
  408. },
  409. renderHTML(row) {
  410. return [
  411. {
  412. attrs: {
  413. label: "包裹图片",
  414. type: "primary",
  415. text: true,
  416. },
  417. el: "button",
  418. click() {
  419. clickPackagePicture(row);
  420. },
  421. },
  422. ];
  423. },
  424. },
  425. ];
  426. });
  427. const getDemandData = () => {
  428. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  429. if (res.rows && res.rows.length > 0) {
  430. departmentList.value = res.rows.map((item) => {
  431. return {
  432. dictKey: item.id,
  433. dictValue: item.name,
  434. };
  435. });
  436. }
  437. });
  438. proxy.post("/expressDelivery/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  439. if (res.rows && res.rows.length > 0) {
  440. expressDeliveryList.value = res.rows.map((item) => {
  441. return {
  442. ...item,
  443. dictKey: item.id,
  444. dictValue: item.expressage,
  445. };
  446. });
  447. }
  448. });
  449. };
  450. getDemandData();
  451. const selectData = ref([]);
  452. const selectRow = (data) => {
  453. selectData.value = data;
  454. };
  455. const getList = async (req, status) => {
  456. selectData.value = [];
  457. if (status) {
  458. sourceList.value.pagination = {
  459. pageNum: sourceList.value.pagination.pageNum,
  460. pageSize: sourceList.value.pagination.pageSize,
  461. };
  462. } else {
  463. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  464. }
  465. loading.value = true;
  466. proxy.post("/issueBill/page", sourceList.value.pagination).then((res) => {
  467. if (res.rows && res.rows.length > 0) {
  468. sourceList.value.data = res.rows.map((item) => {
  469. return {
  470. ...item,
  471. isCheck: true,
  472. };
  473. });
  474. } else {
  475. sourceList.value.data = [];
  476. }
  477. sourceList.value.pagination.total = res.total;
  478. setTimeout(() => {
  479. loading.value = false;
  480. }, 200);
  481. });
  482. };
  483. getList();
  484. const clickReset = () => {
  485. getList("", true);
  486. };
  487. const clickCode = (row) => {
  488. proxy.$router.replace({
  489. path: "/order-detail",
  490. query: {
  491. detailId: row.id,
  492. text: "订单详情",
  493. random: proxy.random(),
  494. },
  495. });
  496. };
  497. const openTotal = ref(false);
  498. const rowData = ref({});
  499. const clickTotal = (item) => {
  500. rowData.value = item;
  501. openTotal.value = true;
  502. };
  503. const clickCancel = () => {
  504. openTotal.value = false;
  505. };
  506. const openPackagePicture = ref(false);
  507. const loadingPackagePicture = ref(false);
  508. const fileList = ref([]);
  509. const clickPackagePicture = (item) => {
  510. fileList.value = [];
  511. rowData.value = item;
  512. openPackagePicture.value = true;
  513. loadingPackagePicture.value = true;
  514. proxy.post("/fileInfo/getList", { businessIdList: [item.id] }).then(
  515. (fileObj) => {
  516. if (fileObj[item.id] && fileObj[item.id].length > 0) {
  517. let file = fileObj[item.id].filter((item) => item.businessType == "2");
  518. if (file && file.length > 0) {
  519. fileList.value = file.map((item) => {
  520. return {
  521. raw: item,
  522. name: item.fileName,
  523. url: item.fileUrl,
  524. };
  525. });
  526. } else {
  527. fileList.value = [];
  528. }
  529. }
  530. loadingPackagePicture.value = false;
  531. },
  532. (err) => {
  533. console.log(err);
  534. loadingPackagePicture.value = false;
  535. }
  536. );
  537. };
  538. const uploadData = ref({});
  539. const beforeUpload = async (file) => {
  540. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  541. uploadData.value = res.uploadBody;
  542. file.id = res.id;
  543. file.fileName = res.fileName;
  544. file.fileUrl = res.fileUrl;
  545. return true;
  546. };
  547. const onPreview = (file) => {
  548. window.open(file.raw.fileUrl, "_blank");
  549. };
  550. const submitPicture = () => {
  551. let packagePictureList = [];
  552. if (fileList.value && fileList.value.length > 0) {
  553. packagePictureList = fileList.value.map((item) => {
  554. return {
  555. id: item.raw.id,
  556. fileName: item.raw.fileName,
  557. fileUrl: item.raw.fileUrl,
  558. };
  559. });
  560. }
  561. loadingPackagePicture.value = true;
  562. proxy.post("/issueBill/editPackagePicture", { id: rowData.value.id, packagePictureList: packagePictureList }).then(
  563. () => {
  564. openPackagePicture.value = false;
  565. loadingPackagePicture.value = false;
  566. ElMessage({ message: "提交成功", type: "success" });
  567. },
  568. (err) => {
  569. console.log(err);
  570. loadingPackagePicture.value = false;
  571. }
  572. );
  573. };
  574. const clickUnpack = () => {
  575. if (selectData.value && selectData.value.length > 0) {
  576. if (selectData.value.length > 1) {
  577. return ElMessage("每次只能选一个");
  578. }
  579. proxy.$router.replace({
  580. path: "/production/shipment/unpack",
  581. query: {
  582. id: selectData.value[0].id,
  583. },
  584. });
  585. } else {
  586. return ElMessage("请先选择需要拆分包裹的订单");
  587. }
  588. };
  589. const openMerge = ref(false);
  590. const formMerge = reactive({
  591. data: {
  592. id: "",
  593. mergeIdList: [],
  594. },
  595. });
  596. const rulesMerge = ref({
  597. id: [{ required: true, message: "请选择主订单", trigger: "change" }],
  598. mergeIdList: [{ required: true, message: "请选择合并订单", trigger: "change" }],
  599. });
  600. const clickMerge = () => {
  601. if (selectData.value && selectData.value.length > 1) {
  602. for (let i = 0; i < selectData.value.length; i++) {
  603. if (selectData.value[i].groupOrderCodeList && selectData.value[i].groupOrderCodeList.length > 0) {
  604. return ElMessage("请选择未合并订单进行合并");
  605. }
  606. }
  607. formMerge.data = {
  608. id: "",
  609. mergeIdList: [],
  610. };
  611. openMerge.value = true;
  612. } else {
  613. return ElMessage("请选择需要合并的订单");
  614. }
  615. };
  616. const submitMerge = () => {
  617. proxy.$refs.refMerge.validate((valid) => {
  618. if (valid) {
  619. proxy.post("/issueBill/merge", formMerge.data).then(() => {
  620. openMerge.value = false;
  621. ElMessage({ message: "提交成功", type: "success" });
  622. getList();
  623. });
  624. }
  625. });
  626. };
  627. const clickUnMerge = () => {
  628. if (selectData.value && selectData.value.length > 0) {
  629. if (selectData.value.length > 1) {
  630. return ElMessage("每次只能选一个");
  631. }
  632. if (!(selectData.value[0].groupOrderCodeList && selectData.value[0].groupOrderCodeList.length > 0)) {
  633. return ElMessage("该订单没有合并");
  634. }
  635. proxy.post("/issueBill/unmerge", { id: selectData.value[0].id }).then(() => {
  636. ElMessage({ message: "取消合并成功", type: "success" });
  637. getList();
  638. });
  639. } else {
  640. return ElMessage("请先选择需要取消合并的订单");
  641. }
  642. };
  643. const openInformation = ref(false);
  644. const formInformation = reactive({
  645. data: {
  646. id: "",
  647. province: "",
  648. city: "",
  649. county: "",
  650. detailedAddress: "",
  651. consignee: "",
  652. consigneeNumber: "",
  653. },
  654. });
  655. const rulesInformation = ref({
  656. province: [{ required: true, message: "请输入省", trigger: "blur" }],
  657. city: [{ required: true, message: "请输入市", trigger: "blur" }],
  658. county: [{ required: true, message: "请输入县", trigger: "blur" }],
  659. detailedAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
  660. consignee: [{ required: true, message: "请输入收货人", trigger: "blur" }],
  661. consigneeNumber: [{ required: true, message: "请输入收货人电话", trigger: "blur" }],
  662. });
  663. const clickModifyInformation = () => {
  664. if (selectData.value && selectData.value.length > 0) {
  665. if (selectData.value.length > 1) {
  666. return ElMessage("每次只能选一个");
  667. }
  668. formInformation.data = {
  669. id: selectData.value[0].id,
  670. province: selectData.value[0].province,
  671. city: selectData.value[0].city,
  672. county: selectData.value[0].county,
  673. detailedAddress: selectData.value[0].detailedAddress,
  674. consignee: selectData.value[0].consignee,
  675. consigneeNumber: selectData.value[0].consigneeNumber,
  676. };
  677. openInformation.value = true;
  678. } else {
  679. return ElMessage("请先选择需要修改收件信息的订单");
  680. }
  681. };
  682. const submitInformation = () => {
  683. proxy.$refs.refInformation.validate((valid) => {
  684. if (valid) {
  685. proxy.post("/issueBill/editAddress", formInformation.data).then(() => {
  686. openInformation.value = false;
  687. ElMessage({ message: "保存成功", type: "success" });
  688. getList();
  689. });
  690. }
  691. });
  692. };
  693. const openExpress = ref(false);
  694. const formExpress = reactive({
  695. data: {
  696. id: "",
  697. expressDeliveryId: "",
  698. },
  699. });
  700. const rulesExpress = ref({
  701. expressDeliveryId: [{ required: true, message: "请选择快递", trigger: "change" }],
  702. });
  703. const clickModifiedExpress = () => {
  704. if (selectData.value && selectData.value.length > 0) {
  705. if (selectData.value.length > 1) {
  706. return ElMessage("每次只能选一个");
  707. }
  708. formExpress.data = {
  709. id: selectData.value[0].id,
  710. expressDeliveryId: selectData.value[0].expressDeliveryId,
  711. };
  712. openExpress.value = true;
  713. } else {
  714. return ElMessage("请先选择需要修改快递的订单");
  715. }
  716. };
  717. const submitExpress = () => {
  718. proxy.$refs.refExpress.validate((valid) => {
  719. if (valid) {
  720. proxy.post("/issueBill/editExpressDeliveryId", formExpress.data).then(() => {
  721. openExpress.value = false;
  722. ElMessage({ message: "保存成功", type: "success" });
  723. getList();
  724. });
  725. }
  726. });
  727. };
  728. const openPrint = ref(false);
  729. const orderEncasementList = ref([]);
  730. const clickPrint = () => {
  731. if (selectData.value && selectData.value.length > 0) {
  732. if (selectData.value.length > 1) {
  733. return ElMessage("每次只能选一个");
  734. }
  735. getAssemblyDetail();
  736. openPrint.value = true;
  737. } else {
  738. return ElMessage("请先选择需要打印快递单的订单");
  739. }
  740. };
  741. const getAssemblyDetail = () => {
  742. orderEncasementList.value = [];
  743. proxy.post("/issueBill/assemblyDetail", { id: selectData.value[0].id }).then((res) => {
  744. orderEncasementList.value = res.orderEncasementList;
  745. });
  746. };
  747. const ws = ref("");
  748. const initWebSocket = (status, request) => {
  749. ws.value = new WebSocket("ws://localhost:13528");
  750. ws.value.onopen = (e) => {
  751. console.log("建立连接", e);
  752. if (status) {
  753. send(request);
  754. }
  755. };
  756. };
  757. initWebSocket();
  758. const send = (request) => {
  759. ws.value.send(JSON.stringify(request));
  760. };
  761. const getUUID = (len, radix) => {
  762. var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
  763. var uuid = [],
  764. i;
  765. radix = radix || chars.length;
  766. if (len) {
  767. for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
  768. } else {
  769. var r;
  770. uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
  771. uuid[14] = "4";
  772. for (i = 0; i < 36; i++) {
  773. if (!uuid[i]) {
  774. r = 0 | (Math.random() * 16);
  775. uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
  776. }
  777. }
  778. }
  779. return uuid.join("");
  780. };
  781. const getRequestObject = (cmd = "print") => {
  782. var request = new Object();
  783. request.requestID = getUUID(8, 16);
  784. request.version = "1.0";
  785. request.cmd = cmd;
  786. return request;
  787. };
  788. const clickNewbiePrint = (row) => {
  789. let printer = "";
  790. if (selectData.value[0].expressDeliveryId) {
  791. let list = expressDeliveryList.value.filter((item) => item.id === selectData.value[0].expressDeliveryId);
  792. if (list && list.length > 0) {
  793. if (list[0].printer) {
  794. printer = list[0].printer;
  795. } else {
  796. return ElMessage("该快递网点暂未设置打印机");
  797. }
  798. }
  799. } else {
  800. return ElMessage("请先设置快递");
  801. }
  802. proxy.post("/cainiao/takeNum", { id: row.id }).then((res) => {
  803. let request = getRequestObject();
  804. request.task = new Object();
  805. request.task.taskID = getUUID(8, 10);
  806. request.task.preview = false;
  807. request.task.printer = printer;
  808. let documents = [];
  809. if (res.detail || res.customTemplateUrl) {
  810. documents.push({
  811. documentID: res.data.waybillCode,
  812. contents: [
  813. res,
  814. {
  815. data: {
  816. detail: res.detail,
  817. },
  818. templateURL: res.customTemplateUrl,
  819. },
  820. ],
  821. });
  822. } else {
  823. documents.push({
  824. documentID: res.data.waybillCode,
  825. contents: [res],
  826. });
  827. }
  828. request.task.documents = documents;
  829. if (ws.value.readyState !== 1) {
  830. initWebSocket(true, request);
  831. } else {
  832. send(request);
  833. }
  834. });
  835. };
  836. const openExpressCode = ref(false);
  837. const formExpressCode = reactive({
  838. data: {
  839. id: "",
  840. trackingNumber: "",
  841. },
  842. });
  843. const rulesExpressCode = ref({
  844. trackingNumber: [{ required: true, message: "请输入快递单号", trigger: "blur" }],
  845. });
  846. const clickFillInExpressCode = (row) => {
  847. formExpressCode.data = {
  848. id: row.id,
  849. trackingNumber: row.trackingNumber,
  850. };
  851. openExpressCode.value = true;
  852. };
  853. const submitExpressCode = () => {
  854. proxy.$refs.refExpressCode.validate((valid) => {
  855. if (valid) {
  856. proxy.post("/issueBill/editExpressDeliveryCode", formExpressCode.data).then(() => {
  857. openExpressCode.value = false;
  858. ElMessage({ message: "保存成功", type: "success" });
  859. getAssemblyDetail();
  860. });
  861. }
  862. });
  863. };
  864. </script>
  865. <style lang="scss" scoped>
  866. ::v-deep(.remark) {
  867. margin: 0 16px;
  868. p {
  869. margin-block-start: 0 !important;
  870. margin-block-end: 0 !important;
  871. }
  872. }
  873. :deep(.el-dialog) {
  874. margin-top: 10px !important;
  875. margin-bottom: 10px !important;
  876. }
  877. </style>