voyageList.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. <template>
  2. <div class="line-container-p24">
  3. <div class="df jcsb aic">
  4. <div class="df aic">
  5. <div
  6. @click="changeVoyageType(0)"
  7. :class="
  8. status == 0
  9. ? 'currentbtn radio-btns left-radius'
  10. : 'radio-btns left-radius'
  11. "
  12. >
  13. 全部航次
  14. </div>
  15. <div
  16. style="border-left: none"
  17. @click="changeVoyageType(1)"
  18. :class="status == 1 ? 'currentbtn radio-btns' : 'radio-btns'"
  19. >
  20. 装货中
  21. </div>
  22. <div
  23. style="border-left: none"
  24. @click="changeVoyageType(2)"
  25. :class="status == 2 ? 'currentbtn radio-btns' : 'radio-btns'"
  26. >
  27. 运输中
  28. </div>
  29. <div
  30. style="border-left: none"
  31. @click="changeVoyageType(3)"
  32. :class="status == 3 ? 'currentbtn radio-btns' : 'radio-btns'"
  33. >
  34. 卸货中
  35. </div>
  36. <div
  37. @click="changeVoyageType(4)"
  38. :class="
  39. status == 4
  40. ? 'currentbtn radio-btns right-radius'
  41. : 'radio-btns right-radius '
  42. "
  43. style="margin-right: 40px; border-left: none"
  44. >
  45. 历史航次
  46. </div>
  47. <!-- <div style="color: #333; margin-right: 10px; font-size: 14px">
  48. 预计到港时间:
  49. </div>
  50. <el-radio-group v-model="sortradio">
  51. <el-radio :label="-1">默认排序</el-radio>
  52. <el-radio :label="0">降序</el-radio>
  53. <el-radio :label="1">升序</el-radio>
  54. </el-radio-group> -->
  55. <el-input
  56. placeholder="请输入船名/MMSI"
  57. prefix-icon="el-icon-search"
  58. v-model="term"
  59. clearable
  60. style="width: 240px"
  61. @keyup.enter.native="getVoyageList()"
  62. ></el-input>
  63. <div class="search-btn" @click="getVoyageList()">查询</div>
  64. </div>
  65. <!-- <div class="cargo-owner-add" @click="voyageAddDialogVisible = true">
  66. 添加航次
  67. </div> -->
  68. <div>
  69. <el-button
  70. type="primary"
  71. size="small"
  72. @click="showExportModal('航次列表')"
  73. >导出航次列表</el-button
  74. >
  75. <el-button
  76. type="primary"
  77. size="small"
  78. v-auth="'MULTDOWNLOADSHIPTRACK'"
  79. @click="showExportModal('航次跟踪')"
  80. >导出航次跟踪</el-button
  81. >
  82. <el-button
  83. type="primary"
  84. size="small"
  85. @click="showExportModal('卸货记录')"
  86. v-auth="'MULTDOWNLOADDISCHARGE'"
  87. >导出卸货记录</el-button
  88. >
  89. <el-button
  90. v-auth="'DOWNLOADFYDI'"
  91. type="primary"
  92. size="small"
  93. @click="downloadFYDI"
  94. >下载FYDI指数</el-button
  95. >
  96. </div>
  97. </div>
  98. <el-dialog
  99. v-model="exportModalVisable"
  100. :title="exportModalTitle"
  101. width="200px"
  102. >
  103. <div class="df aic jcsb">
  104. <div class="df aic">
  105. <div class="mr20">请选择月份:</div>
  106. <el-date-picker
  107. v-model="currentMonth"
  108. type="month"
  109. placeholder="请选择年月"
  110. value-format="YYYYMM"
  111. :disabled="isLoadingZip"
  112. />
  113. </div>
  114. <el-button type="primary" @click="exportZip" :loading="isLoadingZip"
  115. >导出{{ exportModalTitle }}</el-button
  116. >
  117. </div>
  118. </el-dialog>
  119. <el-dialog v-model="voyageAddDialogVisible" title="添加航次">
  120. <el-form
  121. :rules="rules"
  122. label-position="right"
  123. label-width="80px"
  124. ref="addVoyageForm"
  125. :model="voyageForm"
  126. :before-close="resetAddVoyageForm"
  127. >
  128. <div class="df ffw">
  129. <!-- <el-form-item prop="voyageName" label="航次名称">
  130. <el-input v-model="voyageForm.voyageName"></el-input>
  131. </el-form-item>
  132. <el-form-item label=""></el-form-item> -->
  133. <el-form-item prop="shipName" label="船舶">
  134. <!-- <el-input v-model="voyageForm.shipOwnerId"></el-input> -->
  135. <el-autocomplete
  136. v-model="voyageForm.shipName"
  137. :fetch-suggestions="searchShip"
  138. placeholder="选择船舶"
  139. @blur="clear('shipId')"
  140. @select="selectShip"
  141. />
  142. </el-form-item>
  143. <el-form-item prop="cargoOwnerName" label="货主">
  144. <el-autocomplete
  145. v-model="voyageForm.cargoOwnerName"
  146. :fetch-suggestions="searchCargoOwner"
  147. @blur="clear('cargoOwnerId')"
  148. placeholder="选择货主"
  149. @select="selectCargoOwner"
  150. />
  151. </el-form-item>
  152. <el-form-item prop="startTime" label="开始时间">
  153. <el-date-picker
  154. v-model="voyageForm.startTime"
  155. type="date"
  156. value-format="YYYY/MM/DD"
  157. placeholder="航次开始时间"
  158. ></el-date-picker>
  159. </el-form-item>
  160. <el-form-item prop="endTime" label="结束时间">
  161. <el-date-picker
  162. v-model="voyageForm.endTime"
  163. type="date"
  164. value-format="YYYY/MM/DD"
  165. placeholder="航次结束时间"
  166. disabled
  167. ></el-date-picker>
  168. </el-form-item>
  169. <el-form-item prop="loadPort" label="装货港">
  170. <el-autocomplete
  171. v-model="voyageForm.loadPort"
  172. :fetch-suggestions="getCol"
  173. @blur="clear('loadPort')"
  174. placeholder="选择装货港"
  175. @select="selectLoadPort"
  176. />
  177. </el-form-item>
  178. <el-form-item prop="dischargeProt" label="卸货港">
  179. <el-autocomplete
  180. v-model="voyageForm.dischargeProt"
  181. :fetch-suggestions="getCol"
  182. @blur="clear('dischargeProt')"
  183. placeholder="选择卸货港"
  184. @select="selectDischargeProt"
  185. />
  186. </el-form-item>
  187. <el-form-item prop="cargo" label="货种">
  188. <el-input v-model="voyageForm.cargo"></el-input>
  189. </el-form-item>
  190. <el-form-item prop="tons" label="吨位">
  191. <el-input v-model="voyageForm.tons"></el-input>
  192. </el-form-item>
  193. </div>
  194. </el-form>
  195. <template #footer>
  196. <span class="dialog-footer">
  197. <el-button @click="resetAddVoyageForm">取消</el-button>
  198. <el-button type="primary" @click="addVoyage">确定</el-button>
  199. </span>
  200. </template>
  201. </el-dialog>
  202. <el-table
  203. :data="tableData"
  204. stripe
  205. style="width: 100%; margin-top: 24px"
  206. :row-style="rowStyle"
  207. >
  208. <!-- <el-table-column
  209. type="index"
  210. label="序号"
  211. min-width="80"
  212. align="center"
  213. ></el-table-column> -->
  214. <el-table-column
  215. prop="voyageName"
  216. label="航次名称"
  217. min-width="140"
  218. align="center"
  219. ></el-table-column>
  220. <el-table-column
  221. prop="loadDiscPort"
  222. label="装货港-卸货港"
  223. min-width="160"
  224. align="center"
  225. ></el-table-column>
  226. <!-- <el-table-column
  227. prop="setSailTime"
  228. label="开航时间"
  229. min-width="100"
  230. align="center"
  231. ></el-table-column> -->
  232. <el-table-column
  233. prop="expectedArrivalTime"
  234. label="预计到港时间"
  235. sortable
  236. min-width="100"
  237. align="center"
  238. >
  239. <template v-slot="scope">
  240. {{ scope.row.arrived ? "已到港" : scope.row.expectedArrivalTime }}
  241. </template>
  242. </el-table-column>
  243. <el-table-column
  244. prop="abnormalStatus"
  245. label="航次状态"
  246. min-width="80"
  247. align="center"
  248. >
  249. <template v-slot="scope">
  250. {{ scope.row.abnormalStatus == 0 ? "正常" : "异常" }}
  251. </template>
  252. </el-table-column>
  253. <el-table-column
  254. prop="daysInPort"
  255. label="在港天数"
  256. sortable
  257. min-width="70"
  258. align="center"
  259. ></el-table-column>
  260. <el-table-column
  261. prop="todayPhotoCount"
  262. label="今日照片"
  263. min-width="70"
  264. align="center"
  265. ></el-table-column>
  266. <el-table-column
  267. prop="cargo"
  268. label="货种"
  269. min-width="70"
  270. align="center"
  271. ></el-table-column>
  272. <el-table-column
  273. prop="actualLoadTons"
  274. label="装载吨位"
  275. min-width="80"
  276. align="center"
  277. ></el-table-column>
  278. <el-table-column
  279. prop="unloadedtons"
  280. label="已卸货吨位"
  281. min-width="80"
  282. align="center"
  283. ></el-table-column>
  284. <el-table-column
  285. prop="remainTons"
  286. label="剩余吨位"
  287. min-width="80"
  288. align="center"
  289. ></el-table-column>
  290. <!-- <el-table-column
  291. prop="waybillStatus"
  292. sortable
  293. label="签单状态"
  294. min-width="100"
  295. align="center"
  296. >
  297. <template v-slot="scope">
  298. {{
  299. scope.row.waybillStatus == 0
  300. ? ""
  301. : scope.row.waybillStatus == 1
  302. ? "未签单"
  303. : "已签单"
  304. }}
  305. </template>
  306. </el-table-column> -->
  307. <!-- <el-table-column
  308. prop="transStatus"
  309. label="船舶状态"
  310. min-width="100"
  311. align="center"
  312. ></el-table-column> -->
  313. <el-table-column
  314. prop="hasInsurance"
  315. label="保险状态"
  316. min-width="70"
  317. align="center"
  318. >
  319. <template v-slot="scope">
  320. {{ scope.row.hasInsurance == 0 ? "未购买" : "已购买" }}
  321. </template>
  322. </el-table-column>
  323. <!-- <el-table-column
  324. sortable
  325. prop="createTime"
  326. label="创建时间"
  327. min-width="100"
  328. align="center"
  329. >
  330. <template v-slot="scope">
  331. {{ subTimeStr(scope.row.createTime) }}
  332. </template>
  333. </el-table-column>
  334. <el-table-column
  335. prop="remark"
  336. label="备注"
  337. min-width="100"
  338. align="center"
  339. ></el-table-column> -->
  340. <el-table-column
  341. v-auth="'VOYAGEDETAIL'"
  342. label="操作"
  343. min-width="80"
  344. align="center"
  345. fixed="right"
  346. >
  347. <template v-slot="scope">
  348. <el-button
  349. @click="voyageDetail(scope.row.id, tableData)"
  350. type="text"
  351. size="small"
  352. >
  353. 查看详情
  354. </el-button>
  355. </template>
  356. </el-table-column>
  357. </el-table>
  358. <div style="width: 100%; text-align: right; margin-top: 43px">
  359. <el-pagination
  360. background
  361. layout="prev, pager, next"
  362. :total="total"
  363. @current-change="pageChange"
  364. ></el-pagination>
  365. </div>
  366. </div>
  367. </template>
  368. <script setup>
  369. import { ref, h, reactive, toRefs, onMounted } from "vue";
  370. import { ElNotification, ElMessageBox, ElMessage } from "element-plus";
  371. import store from "../../store";
  372. import router from "../../router";
  373. import md5 from "md5";
  374. import api from "../../apis/fetch";
  375. import _ from "lodash";
  376. import { subTimeStr } from "../../utils/utils";
  377. import downloadBlobFile from "../../utils/downloadBlobFile";
  378. import url from "../../apis/config";
  379. let currentPage = ref(1);
  380. let term = ref("");
  381. let tableData = ref([]);
  382. let total = ref(0);
  383. let status = ref(0);
  384. async function getVoyageList() {
  385. tableData.value = [];
  386. let res = await api.getVoyageList({
  387. loginAccountId: localStorage.loginAccountId,
  388. cargoOwnerId: localStorage.userId,
  389. shipId: 0,
  390. status: status.value,
  391. term: term.value,
  392. currentPage: currentPage.value,
  393. size: 10,
  394. });
  395. term.value = "";
  396. if (res.data.status == 0) {
  397. tableData.value = res.data.result;
  398. total.value = res.data.total;
  399. } else {
  400. ElNotification({
  401. type: "error",
  402. title: res.data.msg,
  403. });
  404. }
  405. }
  406. function changeVoyageType(s) {
  407. term.value = "";
  408. currentPage.value = 1;
  409. status.value = s;
  410. getVoyageList();
  411. }
  412. async function voyageDetail(id) {
  413. router.push({
  414. path: "/voyage/voyageDetail",
  415. query: {
  416. id,
  417. },
  418. });
  419. }
  420. function pageChange(e) {
  421. currentPage.value = e;
  422. getVoyageList();
  423. }
  424. function goToVoyageAdd() {
  425. router.push({
  426. path: "/voyage/voyageAdd",
  427. });
  428. }
  429. let voyageAddDialogVisible = ref(false);
  430. const rules = reactive({
  431. rules: {
  432. voyageName: [
  433. { required: false, message: "请填写航次名称", trigger: "blur" },
  434. ],
  435. shipName: [{ required: true, message: "请选择船舶", trigger: "blur" }],
  436. cargoOwnerName: [
  437. { required: true, message: "请选择货主", trigger: "blur" },
  438. ],
  439. startTime: [{ required: true, message: "请填写开始时间", trigger: "blur" }],
  440. loadPort: [{ required: true, message: "请填写装货港", trigger: "blur" }],
  441. dischargeProt: [
  442. { required: true, message: "请填写卸货港", trigger: "blur" },
  443. ],
  444. cargo: [{ required: true, message: "请填写货种", trigger: "blur" }],
  445. tons: [{ required: true, message: "请填写吨位", trigger: "blur" }],
  446. },
  447. });
  448. let voyageForm = reactive({
  449. voyageForm: {
  450. voyageName: "",
  451. cargoOwnerId: "",
  452. cargoOwnerName: "",
  453. startTime: "",
  454. endTime: "",
  455. loadPort: "",
  456. dischargeProt: "",
  457. cargo: "",
  458. tons: "",
  459. loadPortId: "",
  460. dischargeProtId: "",
  461. shipId: "",
  462. shipName: "",
  463. },
  464. });
  465. function clear(type) {
  466. setTimeout(() => {
  467. switch (type) {
  468. case "shipId": {
  469. let index = ref(-1);
  470. for (let i in shipsCache.value) {
  471. if (voyageForm.voyageForm.shipName == shipsCache.value[i].shipName) {
  472. index.value = i;
  473. break;
  474. }
  475. }
  476. if (index.value != -1) {
  477. voyageForm.voyageForm.shipId = shipsCache.value[index.value].shipId;
  478. } else {
  479. let b = shipsCache.value.some((item) => {
  480. return (
  481. item.shipId == voyageForm.voyageForm.shipId &&
  482. item.shipName == voyageForm.voyageForm.shipName
  483. );
  484. });
  485. voyageForm.voyageForm["shipId"] = "";
  486. voyageForm.voyageForm["shipName"] = "";
  487. }
  488. break;
  489. }
  490. case "cargoOwnerId": {
  491. let index = ref(-1);
  492. for (let i in cargoOwnersCache.value) {
  493. if (
  494. voyageForm.voyageForm.cargoOwnerName ==
  495. cargoOwnersCache.value[i].userName
  496. ) {
  497. index.value = i;
  498. break;
  499. }
  500. }
  501. if (index.value != -1) {
  502. voyageForm.voyageForm.cargoOwnerId =
  503. cargoOwnersCache.value[index.value].userId;
  504. } else {
  505. let b = cargoOwnersCache.value.some((item) => {
  506. return (
  507. item.userId == voyageForm.voyageForm.cargoOwnerId &&
  508. item.userName == voyageForm.voyageForm.cargoOwnerName
  509. );
  510. });
  511. if (!b) {
  512. voyageForm.voyageForm["cargoOwnerId"] = "";
  513. voyageForm.voyageForm["cargoOwnerName"] = "";
  514. }
  515. }
  516. break;
  517. }
  518. case "loadPort": {
  519. let index = ref(-1);
  520. for (let i in colCache.value) {
  521. if (voyageForm.voyageForm.loadPort == colCache.value[i].value) {
  522. index.value = i;
  523. break;
  524. }
  525. }
  526. if (index.value != -1) {
  527. voyageForm.voyageForm.loadPortId = colCache.value[index.value].key;
  528. } else {
  529. let b = colCache.value.some((item) => {
  530. return (
  531. item.value == voyageForm.voyageForm.loadPort &&
  532. item.key == voyageForm.voyageForm.loadPortId
  533. );
  534. });
  535. if (!b) {
  536. voyageForm.voyageForm["loadPort"] = "";
  537. voyageForm.voyageForm["loadPortId"] = "";
  538. }
  539. }
  540. break;
  541. }
  542. case "dischargeProt": {
  543. let index = ref(-1);
  544. for (let i in colCache.value) {
  545. if (voyageForm.voyageForm.dischargeProt == colCache.value[i].value) {
  546. index.value = i;
  547. break;
  548. }
  549. }
  550. if (index.value != -1) {
  551. voyageForm.voyageForm.dischargeProtId =
  552. colCache.value[index.value].key;
  553. } else {
  554. let b = colCache.value.some((item) => {
  555. return (
  556. item.value == voyageForm.voyageForm.dischargeProt &&
  557. item.key == voyageForm.voyageForm.dischargeProtId
  558. );
  559. });
  560. if (!b) {
  561. voyageForm.voyageForm["dischargeProt"] = "";
  562. voyageForm.voyageForm["dischargeProtId"] = "";
  563. }
  564. }
  565. break;
  566. }
  567. }
  568. }, 200);
  569. }
  570. let addVoyageForm = ref(null);
  571. async function addVoyage() {
  572. addVoyageForm.value.validate(async (valid) => {
  573. if (valid) {
  574. console.log("提交", voyageForm.voyageForm);
  575. let res = await api.addVoyage({
  576. ...voyageForm.voyageForm,
  577. });
  578. if (res.data.status == 0) {
  579. ElNotification({
  580. title: res.data.msg,
  581. type: "success",
  582. });
  583. resetAddVoyageForm();
  584. getVoyageList();
  585. } else {
  586. console.log(res);
  587. ElNotification({
  588. title: res.data.msg,
  589. type: "error",
  590. });
  591. }
  592. } else {
  593. console.log("未提交", voyageForm.voyageForm);
  594. }
  595. });
  596. }
  597. let shipsCache = ref([]);
  598. let colCache = ref([]);
  599. let cargoOwnersCache = ref([]);
  600. const searchShip = _.debounce(
  601. async (queryString, cb) => {
  602. if (!queryString) return;
  603. let res = await api.searchShip({
  604. term: queryString,
  605. });
  606. let ships = [];
  607. if (res.data.status == 0) {
  608. ships = res.data.result;
  609. for (let i of ships) {
  610. i.value = `${i.shipName}`;
  611. }
  612. shipsCache.value = ships;
  613. cb(ships);
  614. }
  615. },
  616. 1000,
  617. { leading: true }
  618. );
  619. const selectShip = (item) => {
  620. voyageForm.voyageForm.shipId = item.shipId;
  621. };
  622. const searchCargoOwner = _.debounce(
  623. async (queryString, cb) => {
  624. if (!queryString) return;
  625. let res = await api.searchUser({
  626. term: queryString,
  627. identity: 2,
  628. });
  629. let cargoOwners = [];
  630. if (res.data.status == 0) {
  631. cargoOwners = res.data.result;
  632. for (let i of cargoOwners) {
  633. i.value = `${i.userName}`;
  634. }
  635. cargoOwnersCache.value = cargoOwners;
  636. cb(cargoOwners);
  637. }
  638. },
  639. 1000,
  640. { leading: true }
  641. );
  642. const selectCargoOwner = (item) => {
  643. voyageForm.voyageForm.cargoOwnerId = item.userId;
  644. };
  645. const getCol = _.debounce(
  646. async (queryString, cb) => {
  647. if (!queryString) return;
  648. let res = await api.getCol({
  649. term: queryString,
  650. });
  651. if (res.data.status == 0) {
  652. colCache.value = [...colCache.value, ...res.data.result];
  653. colCache.value = _.uniqBy(colCache.value, "key");
  654. cb(res.data.result);
  655. }
  656. },
  657. 1000,
  658. { leading: true }
  659. );
  660. const selectLoadPort = (item) => {
  661. voyageForm.voyageForm.loadPortId = item.key;
  662. voyageForm.voyageForm.loadPort = item.value;
  663. };
  664. const selectDischargeProt = (item) => {
  665. voyageForm.voyageForm.dischargeProtId = item.key;
  666. voyageForm.voyageForm.dischargeProt = item.value;
  667. };
  668. function resetAddVoyageForm() {
  669. voyageAddDialogVisible.value = false;
  670. addVoyageForm.value.resetFields();
  671. }
  672. let sortradio = ref(0);
  673. async function downloadFYDI() {
  674. let res0 = await api.getFYFIDownloadUrl({
  675. loginAccountId: localStorage.loginAccountId,
  676. });
  677. let url = res0.data.result;
  678. let a = document.createElement("a");
  679. a.setAttribute("href", url);
  680. a.click();
  681. }
  682. let exportModalVisable = ref(false);
  683. let exportModalTitle = ref("");
  684. let currentMonth = ref("");
  685. function showExportModal(type) {
  686. exportModalVisable.value = true;
  687. exportModalTitle.value = type;
  688. }
  689. let isLoadingZip = ref(false);
  690. async function exportZip() {
  691. if (!currentMonth.value) return;
  692. isLoadingZip.value = true;
  693. let path = "";
  694. let type = "";
  695. switch (exportModalTitle.value) {
  696. case "航次列表": {
  697. path = "/voyage/exportListExcel";
  698. type =
  699. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
  700. break;
  701. }
  702. case "航次跟踪": {
  703. path = "/voyage/exportMultExcel";
  704. type = "application/zip";
  705. break;
  706. }
  707. case "卸货记录": {
  708. path = "/voyage/exportMultDischargeExcel";
  709. type = "application/zip";
  710. break;
  711. }
  712. }
  713. let res = await downloadBlobFile(
  714. `${url.baseurl}${path}`,
  715. { loginAccountId: localStorage.loginAccountId, date: currentMonth.value },
  716. `${exportModalTitle.value}${currentMonth.value}`,
  717. "post",
  718. type
  719. );
  720. ElNotification({
  721. title: "导出成功!",
  722. type: "success",
  723. });
  724. isLoadingZip.value = false;
  725. currentMonth.value = "";
  726. exportModalVisable.value = false;
  727. }
  728. function rowStyle({ row }) {
  729. let rowStyle = {};
  730. if (row.daysInPort >= 30) {
  731. rowStyle.color = "red";
  732. return rowStyle;
  733. }
  734. }
  735. onMounted(() => {
  736. getVoyageList();
  737. });
  738. </script>
  739. <style scoped>
  740. .search-btn {
  741. display: inline-block;
  742. width: 60px;
  743. height: 32px;
  744. background: #0094fe;
  745. border-radius: 2px;
  746. font-size: 14px;
  747. font-family: PingFangSC-Regular, PingFang SC;
  748. font-weight: 400;
  749. color: #ffffff;
  750. text-align: center;
  751. line-height: 32px;
  752. margin-left: 10px;
  753. cursor: pointer;
  754. }
  755. .cargo-owner-add {
  756. width: 80px;
  757. height: 32px;
  758. border-radius: 2px;
  759. border: 1px solid #0094fe;
  760. font-size: 14px;
  761. font-family: PingFangSC-Regular, PingFang SC;
  762. font-weight: 400;
  763. color: #0094fe;
  764. line-height: 32px;
  765. text-align: center;
  766. cursor: pointer;
  767. }
  768. :deep().el-dialog {
  769. width: 560px;
  770. padding: 20px 50px;
  771. border-radius: 6px;
  772. }
  773. :deep() .el-dialog__title {
  774. font-size: 18px;
  775. font-family: PingFangSC-Regular, PingFang SC;
  776. font-weight: 400;
  777. color: #0094fe;
  778. }
  779. .normal-label {
  780. font-size: 14px;
  781. font-family: PingFangSC-Regular, PingFang SC;
  782. font-weight: 400;
  783. color: #353a42;
  784. margin-right: 10px;
  785. }
  786. .show-input {
  787. width: 280px;
  788. height: 32px;
  789. background: #ffffff;
  790. border-radius: 2px;
  791. border: 1px solid #dee0e3;
  792. font-size: 14px;
  793. font-family: PingFangSC-Regular, PingFang SC;
  794. font-weight: 400;
  795. color: #333333;
  796. line-height: 32px;
  797. padding-left: 12px;
  798. margin-right: 40px;
  799. }
  800. .radio-btns {
  801. height: 38px;
  802. width: 70px;
  803. border: 1px solid #1486f9;
  804. line-height: 38px;
  805. text-align: center;
  806. font-size: 14px;
  807. font-family: PingFangSC-Regular, PingFang SC;
  808. font-weight: 400;
  809. color: #0094fe;
  810. cursor: pointer;
  811. }
  812. .left-radius {
  813. border-top-left-radius: 19px;
  814. border-bottom-left-radius: 19px;
  815. width: 80px;
  816. }
  817. .right-radius {
  818. border-top-right-radius: 19px;
  819. border-bottom-right-radius: 19px;
  820. width: 80px;
  821. }
  822. .currentbtn {
  823. background: #1486f9;
  824. color: #fff;
  825. }
  826. .search-btn {
  827. display: inline-block;
  828. width: 60px;
  829. height: 38px;
  830. background: #0094fe;
  831. border-radius: 2px;
  832. font-size: 14px;
  833. font-family: PingFangSC-Regular, PingFang SC;
  834. font-weight: 400;
  835. color: #ffffff;
  836. text-align: center;
  837. line-height: 38px;
  838. margin-left: 10px;
  839. cursor: pointer;
  840. }
  841. .voyage-add {
  842. width: 80px;
  843. height: 36px;
  844. border-radius: 2px;
  845. border: 1px solid #0094fe;
  846. font-size: 14px;
  847. font-family: PingFangSC-Regular, PingFang SC;
  848. font-weight: 400;
  849. color: #0094fe;
  850. line-height: 36px;
  851. text-align: center;
  852. cursor: pointer;
  853. }
  854. :deep() .el-dialog {
  855. width: 800px;
  856. }
  857. :deep() .el-form-item {
  858. margin-right: 22px;
  859. width: 300px;
  860. }
  861. :deep() .el-autocomplete {
  862. width: 220px;
  863. }
  864. .el-radio {
  865. margin-right: 10px;
  866. }
  867. .el-radio:last-child {
  868. margin-right: 20px;
  869. }
  870. </style>