Ver código fonte

更新 航次列表;航次详情

wzh 3 anos atrás
pai
commit
ed86f93dc3

+ 4 - 1
src/apis/config.js

@@ -16,7 +16,10 @@ export const $http = function (url, data) {
   return axios({
     method: data ? "post" : "get",
     url: baseurl + url,
-    data,
+    data: {
+      ...data,
+      loginAccountId: localStorage.loginAccountId,
+    },
     withCredentials: true,
   });
 };

+ 32 - 24
src/apis/fetch.js

@@ -11,22 +11,22 @@ export default {
 
   // 更新航次
   updateVoyage(data) {
-    return $http("/voyage/backstage/update", data);
+    return $http("/voyage/update", data);
   },
 
   // 完成航次
   finishVoyage(data) {
-    return $http("/voyage/backstage/finish", data);
+    return $http("/voyage/finish", data);
   },
 
   // 添加航次
   addVoyage(data) {
-    return $http("voyage/backstage/add", data);
+    return $http("voyage/add", data);
   },
 
   // 获取媒体列表
   getMediaList(data) {
-    return $http("/media/backstage/list", data);
+    return $http("/media/list", data);
   },
   // 导出excel
   exportExcel(data) {
@@ -169,7 +169,7 @@ export default {
 
   // 获取港口列表
   getCol(data) {
-    return $http("/port/backstage/getCol", data);
+    return $http("/port/getCol", data);
   },
 
   // 获取货种下拉
@@ -179,27 +179,27 @@ export default {
 
   // 获取用户列表 货主/船东
   getUserList(data) {
-    return $http("user/backstage/list", data);
+    return $http("user/list", data);
   },
 
   // 添加用户
   addUser(data) {
-    return $http("user/backstage/add", data);
+    return $http("user/add", data);
   },
 
   // 添加船东
   addShipOwner(data) {
-    return $http("user/backstage/saveShipOwner", data);
+    return $http("user/saveShipOwner", data);
   },
 
   // 获取用户详情
   getUserDetail(data) {
-    return $http("user/backstage/details", data);
+    return $http("user/details", data);
   },
 
   // 更新用户详情
   updateUserDetail(data) {
-    return $http("/user/backstage/update", data);
+    return $http("/user/update", data);
   },
 
   // 获取航次详情
@@ -209,52 +209,52 @@ export default {
 
   // 根据船名/MMSI/船东手机号获取船舶用户信息(员工端添加航次选择船)
   getUserInfoAndShipInfo(data) {
-    return $http("ship/backstage/userShipInfo", data);
+    return $http("ship/userShipInfo", data);
   },
 
   // 审核媒体文件
   auditMedia(data) {
-    return $http("/media/backstage/audit", data);
+    return $http("/media/audit", data);
   },
 
   // 标记媒体文件
   markMedia(data) {
-    return $http("/media/backstage/markMedia", data);
+    return $http("/media/markMedia", data);
   },
 
   // 模糊搜索用户
   searchUser(data) {
-    return $http("/user/backstage/search", data);
+    return $http("/user/search", data);
   },
 
   // 获取船舶列表
   getShipList(data) {
-    return $http("/ship/backstage/list", data);
+    return $http("/ship/list", data);
   },
 
   // 更新船舶信息
   updateShip(data) {
-    return $http("/ship/backstage/update", data);
+    return $http("/ship/update", data);
   },
 
   // 更新船东信息
   updateShipOwner(data) {
-    return $http("/user/backstage/update", data);
+    return $http("/user/update", data);
   },
 
   // 获取船舶详情
   getShipDetail(data) {
-    return $http("/ship/backstage/detail", data);
+    return $http("/ship/detail", data);
   },
 
   // 船舶查询
   searchShip(data) {
-    return $http("ship/backstage/search", data);
+    return $http("ship/search", data);
   },
 
   // 根据shipId获取船东列表
   getShipOwnerListByShipId(data) {
-    return $http("/user/backstage/shopOwnerlist", data);
+    return $http("/user/shopOwnerlist", data);
   },
 
   // 添加卸货记录
@@ -274,7 +274,7 @@ export default {
 
   // 获取未拍照航次
   getUnphotographNotice() {
-    return $http("/voyage/backstage/notice");
+    return $http("/voyage/notice");
   },
 
   // 计算预计到港时间
@@ -294,7 +294,7 @@ export default {
 
   // 取消航次
   cancelVoyage(data) {
-    return $http("/voyage/backstage/cancel", data);
+    return $http("/voyage/cancel", data);
   },
 
   // 添加汽车装货记录
@@ -324,7 +324,7 @@ export default {
 
   // 用户选择
   getUserSelect(data) {
-    return $http("/user/backstage/select", data);
+    return $http("/user/select", data);
   },
 
   // 添加提货单
@@ -354,7 +354,7 @@ export default {
 
   // 插入卸货港
   addNewPort(data) {
-    return $http("/voyage/backstage/addNewPort", data);
+    return $http("/voyage/addNewPort", data);
   },
 
   // 代理子账户列表
@@ -366,4 +366,12 @@ export default {
   addAgencySubAccount(data) {
     return $http("/proxy/account/add", data);
   },
+
+  getShipSelect(data) {
+    return $http("/ship/select", data);
+  },
+
+  getCargoOwnerSelect(data) {
+    return $http("/user/cargoOwner/select", data);
+  },
 };

+ 86 - 0
src/components/RemoteSelect.vue

@@ -0,0 +1,86 @@
+<template>
+  <el-select
+    filterable
+    :multiple="multiple"
+    :multiple-limit="multiple ? 0 : 1"
+    remote
+    clearable
+    reserve-keyword
+    :placeholder="placeholder"
+    :remote-method="getSelectList"
+    :loading="loading"
+    @change="selectItem"
+  >
+    <el-option
+      v-for="item in options"
+      :key="item.key"
+      :label="item.value"
+      :value="{ value: item.key, key: item.value }"
+    />
+  </el-select>
+</template>
+
+<script>
+import { onMounted, ref } from "vue";
+import api from "../apis/fetch";
+import _ from "lodash";
+export default {
+  props: {
+    placeholder: {
+      type: String,
+      default: "请填写",
+    },
+    size: {
+      type: String,
+      default: "small",
+    },
+    clearable: {
+      type: Boolean,
+      default: true,
+    },
+    api: String,
+    params: Object,
+    multiple: {
+      type: Boolean,
+      default: false,
+    },
+  },
+
+  emits: ["selectItem"],
+  setup(props, { emit }) {
+    let loading = ref(true);
+    const getSelectList = _.debounce(
+      async (term) => {
+        if (!term) return;
+        loading.value = true;
+        let res = await api[props.api]({
+          ...props.params,
+          term,
+        });
+        if (res.data.status == 0) {
+          options.value = res.data.result;
+        } else {
+          options.value = [];
+        }
+        loading.value = false;
+      },
+      1000,
+      { leading: true }
+    );
+    let options = ref([]);
+    const selectItem = (item) => {
+      emit("selectItem", item);
+    };
+
+    onMounted(() => {});
+    return {
+      getSelectList,
+      selectItem,
+      options,
+      loading,
+    };
+  },
+};
+</script>
+
+<style></style>

+ 2 - 0
src/main.js

@@ -10,8 +10,10 @@ import "./styles/index.css";
 import Uploader from "./components/Uploader.vue";
 import Certs from "./components/Certs.vue";
 import RemoteSearch from "./components/RemoteSearch.vue";
+import RemoteSelect from "./components/RemoteSelect.vue";
 
 const app = createApp(App);
+app.component("RemoteSelect", RemoteSelect);
 app.component("RemoteSearch", RemoteSearch);
 app.component("Certs", Certs);
 app.component("Uploader", Uploader);

+ 7 - 0
src/store/index.js

@@ -6,6 +6,10 @@ import menuData from "../auth/menuData";
 console.log(import.meta.env.VITE_PROJECT_ENV);
 let baseurl = import.meta.env.VITE_BASEURL;
 
+const uploadUrl = `${baseurl}cos/upload`;
+const wayBillUrl = `${baseurl}voyage/uploadVoyageWayBill`;
+const fydi = `${baseurl}fydi/upload`;
+
 const store = createStore({
   state: {
     isLogin: false,
@@ -17,6 +21,9 @@ const store = createStore({
     userPermission: [],
     menuData: [],
     baseParentNodes: [],
+    uploadUrl,
+    wayBillUrl,
+    fydi,
   },
   getters: {},
   mutations: {

Diferenças do arquivo suprimidas por serem muito extensas
+ 799 - 578
src/views/voyage/voyageDetail.vue


+ 274 - 592
src/views/voyage/voyageList.vue

@@ -54,105 +54,106 @@
           <el-radio :label="1">升序</el-radio>
         </el-radio-group> -->
         <el-input
-          placeholder="请输入船名/MMSI"
+          placeholder="请输入货主名称/船名/MMSI"
           prefix-icon="el-icon-search"
           v-model="term"
           clearable
-          style="width: 240px"
-          @keyup.enter.native="getVoyageList()"
+          style="width: 330px"
+          @keydown.enter="getVoyageList()"
         ></el-input>
         <div class="search-btn" @click="getVoyageList()">查询</div>
       </div>
-      <!-- <div class="cargo-owner-add" @click="voyageAddDialogVisible = true">
-        添加航次
-      </div> -->
-      <div>
-        <el-button
-          type="primary"
-          size="small"
-          v-auth="'DOWNLOADVOYAGELIST'"
-          @click="showExportModal('航次列表')"
-          style="margin-left: 10px; margin-bottom: 10px"
-          >导出航次列表</el-button
-        >
-        <el-button
-          type="primary"
-          size="small"
-          v-auth="'MULTDOWNLOADSHIPTRACK'"
-          @click="showExportModal('航次跟踪')"
-          >导出航次跟踪</el-button
-        >
-        <el-button
+      <div class="df aic">
+        <!-- <el-button
+          @click="FYDIModalVisable = true"
+          class="mr20"
+          size="medium"
           type="primary"
-          size="small"
-          @click="showExportModal('卸货记录')"
-          v-auth="'MULTDOWNLOADDISCHARGE'"
-          >导出卸货记录</el-button
+          >上传FYDI指数</el-button
+        > -->
+
+        <el-dialog
+          title="上传FYDI指数"
+          v-model="FYDIModalVisable"
+          @close="FYDIModalClose"
         >
+          <template v-slot:default>
+            <div class="df aic jcsa">
+              <!-- <RemoteSearch
+                api="getUserSelect"
+                v-model="cargoOwnerCompanyStr"
+                placeholder="公司名称/联系人/手机号"
+                :params="{
+                  identity: 2,
+                }"
+                @selectItem="selectCargoOwnerUpload($event)"
+                class="mb10"
+              ></RemoteSearch> -->
+              <RemoteSelect
+                api="getCargoOwnerSelect"
+                v-model="cargoOwnerCompanyStr"
+                placeholder="公司名称/联系人/手机号"
+                @selectItem="selectCargoOwnerUpload($event)"
+                class="mb10"
+              ></RemoteSelect>
+              <el-upload
+                v-if="FYDIParams.cargoOwnerId"
+                class="upload-demo"
+                :action="this.$store.state.fydi"
+                :show-file-list="false"
+                :data="FYDIParams"
+                :on-success="upFYDISuccess"
+                :before-upload="beforeFYDI"
+              >
+                <el-button
+                  class="mr20"
+                  size="medium"
+                  type="primary"
+                  :loading="isUpLoading"
+                  >上传FYDI指数</el-button
+                >
+              </el-upload>
+            </div>
+          </template>
+        </el-dialog>
         <el-button
-          v-auth="'DOWNLOADFYDI'"
+          class="mr20"
+          size="medium"
           type="primary"
-          size="small"
-          @click="downloadFYDI"
-          >下载FYDI指数</el-button
+          @click="voyageAddDialogVisible = true"
+          >添加航次</el-button
         >
       </div>
     </div>
     <el-dialog
-      v-model="exportModalVisable"
-      :title="exportModalTitle"
-      :close-on-click-modal="false"
-      width="200px"
+      v-model="voyageAddDialogVisible"
+      @closed="resetAddVoyageForm"
+      title="添加航次"
     >
-      <div class="df aic jcsb">
-        <div v-if="exportModalTitle != '航次列表'" class="df aic">
-          <div class="mr20">请选择月份:</div>
-          <el-date-picker
-            v-model="currentMonth"
-            type="month"
-            placeholder="请选择年月"
-            value-format="YYYYMM"
-            :disabled="isLoadingZip"
-          />
-        </div>
-        <div></div>
-        <el-button type="primary" @click="exportZip" :loading="isLoadingZip"
-          >导出{{ exportModalTitle }}</el-button
-        >
-      </div>
-    </el-dialog>
-    <el-dialog v-model="voyageAddDialogVisible" title="添加航次">
       <el-form
         :rules="rules"
         label-position="right"
-        label-width="80px"
-        ref="addVoyageForm"
+        label-width="100px"
+        ref="voyageFormRef"
         :model="voyageForm"
-        :before-close="resetAddVoyageForm"
       >
         <div class="df ffw">
-          <!-- <el-form-item prop="voyageName" label="航次名称">
-            <el-input v-model="voyageForm.voyageName"></el-input>
-          </el-form-item>
-          <el-form-item label=""></el-form-item> -->
           <el-form-item prop="shipName" label="船舶">
-            <!-- <el-input v-model="voyageForm.shipOwnerId"></el-input> -->
-            <el-autocomplete
-              v-model="voyageForm.shipName"
-              :fetch-suggestions="searchShip"
-              placeholder="选择船舶"
-              @blur="clear('shipId')"
-              @select="selectShip"
-            />
+            <RemoteSelect
+              api="getShipSelect"
+              v-model="shipStr"
+              @selectItem="selectShip($event)"
+              class="mb10"
+            ></RemoteSelect>
           </el-form-item>
           <el-form-item prop="cargoOwnerName" label="货主">
-            <el-autocomplete
-              v-model="voyageForm.cargoOwnerName"
-              :fetch-suggestions="searchCargoOwner"
-              @blur="clear('cargoOwnerId')"
+            <RemoteSelect
+              api="getCargoOwnerSelect"
+              v-model="cargoOwnerStr"
               placeholder="选择货主"
-              @select="selectCargoOwner"
-            />
+              @selectItem="selectCargoOwner($event)"
+              class="mb10"
+            ></RemoteSelect>
           </el-form-item>
           <el-form-item prop="startTime" label="开始时间">
             <el-date-picker
@@ -172,28 +173,52 @@
             ></el-date-picker>
           </el-form-item>
           <el-form-item prop="loadPort" label="装货港">
-            <el-autocomplete
-              v-model="voyageForm.loadPort"
-              :fetch-suggestions="getCol"
-              @blur="clear('loadPort')"
+            <RemoteSelect
+              api="getCol"
+              v-model="loadPortStr"
               placeholder="选择装货港"
-              @select="selectLoadPort"
-            />
+              @selectItem="selectLoadPort"
+              class="mb10"
+            ></RemoteSelect>
           </el-form-item>
-          <el-form-item prop="dischargeProt" label="卸货港">
-            <el-autocomplete
-              v-model="voyageForm.dischargeProt"
-              :fetch-suggestions="getCol"
-              @blur="clear('dischargeProt')"
+          <el-form-item></el-form-item>
+          <el-form-item
+            v-for="(item, index) in discPorts"
+            prop="dischargeProt"
+            :label="'第 ' + (index + 1) + ' 卸货港'"
+          >
+            <RemoteSelect
+              api="getCol"
+              v-model="discPorts[index].discPort"
               placeholder="选择卸货港"
-              @select="selectDischargeProt"
-            />
+              @selectItem="selectDischargeProt($event, index)"
+              class="mb10"
+            ></RemoteSelect>
           </el-form-item>
+          <el-form-item>
+            <el-button type="primary" size="small" @click="addDiscPort"
+              >添加卸货港</el-button
+            ></el-form-item
+          >
+          <el-form-item v-if="discPorts.length % 2 == 0"></el-form-item>
+
           <el-form-item prop="cargo" label="货种">
-            <el-input v-model="voyageForm.cargo"></el-input>
+            <RemoteSelect
+              api="getCargoSelect"
+              v-model="voyageForm.cargo"
+              placeholder="选择货种"
+              @selectItem="selectCargo"
+              class="mb10"
+            ></RemoteSelect>
           </el-form-item>
           <el-form-item prop="tons" label="吨位">
-            <el-input v-model="voyageForm.tons"></el-input>
+            <el-input style="width: 220px" v-model="voyageForm.tons"></el-input>
+          </el-form-item>
+          <el-form-item prop="pieces" label="件数">
+            <el-input
+              style="width: 220px"
+              v-model="voyageForm.pieces"
+            ></el-input>
           </el-form-item>
         </div>
       </el-form>
@@ -204,204 +229,10 @@
         </span>
       </template>
     </el-dialog>
-    <!-- <div class="mt20">
-      <p class="mr20 df aic" style="font-size: 14px; color: #333">
-        列表筛选:
-        <el-checkbox
-          class="ml20"
-          v-model="selectAllVisable"
-          label="全选"
-          size="default"
-          @change="selectAll"
-        />
-      </p>
-      <el-checkbox
-        v-model="voyageNameVisable"
-        label="航次名称"
-        size="default"
-        @change="selectSingle"
-        disabled
-      />
-      <el-checkbox
-        v-model="loadPortVisable"
-        label="装货港"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="dischargePortVisable"
-        label="卸货港"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="expectedArrivalTimeVisable"
-        label="预计到港时间"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="abnormalStatusVisable"
-        label="航次状态"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="daysInPortVisable"
-        label="在港天数"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="todayPhotoCountVisable"
-        label="今日照片"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="cargoVisable"
-        label="货种"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="actualLoadTonsVisable"
-        label="装载吨位"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="unloadedtonsVisable"
-        label="已卸货吨位"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="remainTonsVisable"
-        label="剩余吨位"
-        size="default"
-        @change="selectSingle"
-      />
-      <el-checkbox
-        v-model="hasInsuranceVisable"
-        label="保险状态"
-        size="default"
-        @change="selectSingle"
-      />
-    </div> -->
-    <div
-      class="df aic jcfs mt20"
-      style="
-        font-size: 14px;
-        color: #333;
-        width: calc(100vw - 300px);
-        flex-wrap: wrap;
-      "
-    >
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">装货港:</div>
-        <el-select
-          style="width: 120px"
-          v-model="voyageListPostData.loadPortId"
-          placeholder="装货港"
-          size="small"
-          @change="getVoyageList"
-          @focus="getPortSelect"
-          filterable
-        >
-          <el-option
-            v-for="item in portOptions"
-            :key="item"
-            :label="item.value"
-            :value="item.key"
-          />
-        </el-select>
-      </div>
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">卸货港:</div>
-        <el-select
-          style="width: 120px"
-          v-model="voyageListPostData.discPortId"
-          placeholder="卸货港"
-          size="small"
-          @change="getVoyageList"
-          @focus="getPortSelect"
-          filterable
-        >
-          <el-option
-            v-for="item in portOptions"
-            :key="item"
-            :label="item.value"
-            :value="item.key"
-          />
-        </el-select>
-      </div>
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">预计到港时间:</div>
-        <el-select
-          style="width: 120px"
-          v-model="voyageListPostData.isArrived"
-          placeholder="到港状态"
-          size="small"
-          @change="getVoyageList"
-        >
-          <el-option label="已到港" :value="0" />
-          <el-option label="未到港" :value="1" />
-        </el-select>
-      </div>
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">航次状态:</div>
-        <el-select
-          style="width: 120px"
-          v-model="voyageListPostData.abnormalStatus"
-          placeholder="航次状态"
-          size="small"
-          @change="getVoyageList"
-        >
-          <el-option label="正常" :value="0" />
-          <el-option label="异常" :value="1" />
-        </el-select>
-      </div>
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">货种:</div>
-        <el-select
-          style="width: 100px"
-          v-model="voyageListPostData.cargo"
-          placeholder="货种"
-          size="small"
-          @change="getVoyageList"
-          @focus="getCargoSelect"
-          filterable
-        >
-          <el-option
-            v-for="item in cargoOptions"
-            :key="item"
-            :label="item.key"
-            :value="item.value"
-          />
-        </el-select>
-      </div>
-      <div class="df jcsb aic mb10 mr20">
-        <div class="mr10">保险状态:</div>
-        <el-select
-          style="width: 120px"
-          v-model="voyageListPostData.hasInsurance"
-          placeholder="保险状态"
-          size="small"
-          @change="getVoyageList"
-        >
-          <el-option label="未购买" :value="0" />
-          <el-option label="已购买" :value="1" />
-        </el-select>
-      </div>
-      <el-button @click="resetFilter" class="mb10" size="small" type="primary"
-        >重置</el-button
-      >
-    </div>
     <el-table
       :data="tableData"
       stripe
-      style="width: 100%; margin-top: 12px"
+      style="width: 100%; margin-top: 24px"
       :row-style="rowStyle"
     >
       <!-- <el-table-column
@@ -413,21 +244,18 @@
       <el-table-column
         prop="voyageName"
         label="航次名称"
-        v-if="voyageNameVisable"
         min-width="140"
         align="center"
       ></el-table-column>
       <el-table-column
         prop="loadPort"
         label="装货港"
-        v-if="loadPortVisable"
         min-width="90"
         align="center"
       ></el-table-column>
       <el-table-column
         prop="dischargePort"
         label="卸货港"
-        v-if="dischargePortVisable"
         min-width="80"
         align="center"
       ></el-table-column>
@@ -440,7 +268,6 @@
       <el-table-column
         prop="expectedArrivalTime"
         label="预计到港时间"
-        v-if="expectedArrivalTimeVisable"
         sortable
         min-width="140"
         align="center"
@@ -452,7 +279,6 @@
       <el-table-column
         prop="abnormalStatus"
         label="航次状态"
-        v-if="abnormalStatusVisable"
         min-width="80"
         align="center"
       >
@@ -463,7 +289,6 @@
       <el-table-column
         prop="daysInPortStr"
         label="在港天数"
-        v-if="daysInPortVisable"
         sortable
         min-width="100"
         align="center"
@@ -471,13 +296,11 @@
       <el-table-column
         prop="todayPhotoCount"
         label="今日照片"
-        v-if="todayPhotoCountVisable"
-        min-width="100"
+        min-width="70"
         align="center"
       ></el-table-column>
       <el-table-column
         prop="cargo"
-        v-if="cargoVisable"
         label="货种"
         min-width="70"
         align="center"
@@ -485,21 +308,18 @@
       <el-table-column
         prop="actualLoadTons"
         label="装载吨位"
-        v-if="actualLoadTonsVisable"
         min-width="80"
         align="center"
       ></el-table-column>
       <el-table-column
         prop="unloadedtons"
         label="已卸货吨位"
-        v-if="unloadedtonsVisable"
-        min-width="100"
+        min-width="80"
         align="center"
       ></el-table-column>
       <el-table-column
         prop="remainTons"
         label="剩余吨位"
-        v-if="remainTonsVisable"
         min-width="80"
         align="center"
       ></el-table-column>
@@ -529,8 +349,7 @@
       <el-table-column
         prop="hasInsurance"
         label="保险状态"
-        v-if="hasInsuranceVisable"
-        min-width="100"
+        min-width="70"
         align="center"
       >
         <template v-slot="scope">
@@ -543,24 +362,14 @@
         label="创建时间"
         min-width="100"
         align="center"
-      >
-        <template v-slot="scope">
-          {{ subTimeStr(scope.row.createTime) }}
-        </template>
-      </el-table-column>
+      ></el-table-column>
       <el-table-column
         prop="remark"
         label="备注"
         min-width="100"
         align="center"
       ></el-table-column> -->
-      <el-table-column
-        v-auth="'VOYAGEDETAIL'"
-        label="操作"
-        min-width="80"
-        align="center"
-        fixed="right"
-      >
+      <el-table-column label="操作" min-width="80" align="center">
         <template v-slot="scope">
           <el-button
             @click="voyageDetail(scope.row.id, tableData)"
@@ -577,6 +386,7 @@
         background
         layout="prev, pager, next"
         :total="total"
+        :page-size="pageSize"
         @current-change="pageChange"
       ></el-pagination>
     </div>
@@ -590,34 +400,27 @@ import router from "../../router";
 import md5 from "md5";
 import api from "../../apis/fetch";
 import _ from "lodash";
-import { subTimeStr } from "../../utils/utils";
-import downloadBlobFile from "../../utils/downloadBlobFile";
-import url from "../../apis/config";
 
 let currentPage = ref(1);
+let pageSize = ref(20);
 let term = ref("");
 let tableData = ref([]);
 let total = ref(0);
 let status = ref(0);
-let loginAccountId = ref("");
-let voyageListPostData = ref({});
 async function getVoyageList() {
   tableData.value = [];
-
   let res = await api.getVoyageList({
-    ...voyageListPostData.value,
-    loginAccountId: localStorage.loginAccountId,
-    cargoOwnerId: localStorage.userId,
-    shipId: 0,
     status: status.value,
     term: term.value,
     currentPage: currentPage.value,
-    size: 10,
+    size: pageSize.value,
   });
   if (res.data.status == 0) {
     tableData.value = res.data.result;
     total.value = res.data.total;
   } else {
+    total.value = 0;
+
     ElNotification({
       type: "error",
       title: res.data.msg,
@@ -648,40 +451,30 @@ function goToVoyageAdd() {
   });
 }
 let voyageAddDialogVisible = ref(false);
-const rules = reactive({
-  rules: {
-    voyageName: [
-      { required: false, message: "请填写航次名称", trigger: "blur" },
-    ],
-    shipName: [{ required: true, message: "请选择船舶", trigger: "blur" }],
-    cargoOwnerName: [
-      { required: true, message: "请选择货主", trigger: "blur" },
-    ],
-    startTime: [{ required: true, message: "请填写开始时间", trigger: "blur" }],
-    loadPort: [{ required: true, message: "请填写装货港", trigger: "blur" }],
-    dischargeProt: [
-      { required: true, message: "请填写卸货港", trigger: "blur" },
-    ],
-    cargo: [{ required: true, message: "请填写货种", trigger: "blur" }],
-    tons: [{ required: true, message: "请填写吨位", trigger: "blur" }],
-  },
+const rules = ref({
+  shipName: [{ required: true, message: "请选择船舶", trigger: "blur" }],
+  cargoOwnerName: [{ required: true, message: "请选择货主", trigger: "blur" }],
+  startTime: [{ required: true, message: "请填写开始时间", trigger: "blur" }],
+  loadPort: [{ required: true, message: "请填写装货港", trigger: "blur" }],
+  // dischargeProt: [{ required: true, message: "请填写卸货港", trigger: "blur" }],
+  cargo: [{ required: true, message: "请填写货种", trigger: "blur" }],
+  tons: [{ required: false, message: "请填写吨位", trigger: "blur" }],
+  pieces: [{ required: false, message: "请填写件数", trigger: "blur" }],
 });
-let voyageForm = reactive({
-  voyageForm: {
-    voyageName: "",
-    cargoOwnerId: "",
-    cargoOwnerName: "",
-    startTime: "",
-    endTime: "",
-    loadPort: "",
-    dischargeProt: "",
-    cargo: "",
-    tons: "",
-    loadPortId: "",
-    dischargeProtId: "",
-    shipId: "",
-    shipName: "",
-  },
+let voyageForm = ref({
+  cargoOwnerId: "",
+  cargoOwnerName: "",
+  startTime: "",
+  endTime: "",
+  loadPort: "",
+  dischargeProt: "",
+  cargo: "",
+  tons: 0,
+  loadPortId: "",
+  dischargeProtId: "",
+  shipId: "",
+  shipName: "",
+  pieces: 0,
 });
 
 function clear(type) {
@@ -690,22 +483,22 @@ function clear(type) {
       case "shipId": {
         let index = ref(-1);
         for (let i in shipsCache.value) {
-          if (voyageForm.voyageForm.shipName == shipsCache.value[i].shipName) {
+          if (voyageForm.value.shipName == shipsCache.value[i].shipName) {
             index.value = i;
             break;
           }
         }
         if (index.value != -1) {
-          voyageForm.voyageForm.shipId = shipsCache.value[index.value].shipId;
+          voyageForm.value.shipId = shipsCache.value[index.value].shipId;
         } else {
           let b = shipsCache.value.some((item) => {
             return (
-              item.shipId == voyageForm.voyageForm.shipId &&
-              item.shipName == voyageForm.voyageForm.shipName
+              item.shipId == voyageForm.value.shipId &&
+              item.shipName == voyageForm.value.shipName
             );
           });
-          voyageForm.voyageForm["shipId"] = "";
-          voyageForm.voyageForm["shipName"] = "";
+          voyageForm.value["shipId"] = "";
+          voyageForm.value["shipName"] = "";
         }
         break;
       }
@@ -713,7 +506,7 @@ function clear(type) {
         let index = ref(-1);
         for (let i in cargoOwnersCache.value) {
           if (
-            voyageForm.voyageForm.cargoOwnerName ==
+            voyageForm.value.cargoOwnerName ==
             cargoOwnersCache.value[i].userName
           ) {
             index.value = i;
@@ -721,18 +514,18 @@ function clear(type) {
           }
         }
         if (index.value != -1) {
-          voyageForm.voyageForm.cargoOwnerId =
+          voyageForm.value.cargoOwnerId =
             cargoOwnersCache.value[index.value].userId;
         } else {
           let b = cargoOwnersCache.value.some((item) => {
             return (
-              item.userId == voyageForm.voyageForm.cargoOwnerId &&
-              item.userName == voyageForm.voyageForm.cargoOwnerName
+              item.userId == voyageForm.value.cargoOwnerId &&
+              item.userName == voyageForm.value.cargoOwnerName
             );
           });
           if (!b) {
-            voyageForm.voyageForm["cargoOwnerId"] = "";
-            voyageForm.voyageForm["cargoOwnerName"] = "";
+            voyageForm.value["cargoOwnerId"] = "";
+            voyageForm.value["cargoOwnerName"] = "";
           }
         }
 
@@ -741,23 +534,23 @@ function clear(type) {
       case "loadPort": {
         let index = ref(-1);
         for (let i in colCache.value) {
-          if (voyageForm.voyageForm.loadPort == colCache.value[i].value) {
+          if (voyageForm.value.loadPort == colCache.value[i].value) {
             index.value = i;
             break;
           }
         }
         if (index.value != -1) {
-          voyageForm.voyageForm.loadPortId = colCache.value[index.value].key;
+          voyageForm.value.loadPortId = colCache.value[index.value].key;
         } else {
           let b = colCache.value.some((item) => {
             return (
-              item.value == voyageForm.voyageForm.loadPort &&
-              item.key == voyageForm.voyageForm.loadPortId
+              item.value == voyageForm.value.loadPort &&
+              item.key == voyageForm.value.loadPortId
             );
           });
           if (!b) {
-            voyageForm.voyageForm["loadPort"] = "";
-            voyageForm.voyageForm["loadPortId"] = "";
+            voyageForm.value["loadPort"] = "";
+            voyageForm.value["loadPortId"] = "";
           }
         }
 
@@ -767,24 +560,23 @@ function clear(type) {
       case "dischargeProt": {
         let index = ref(-1);
         for (let i in colCache.value) {
-          if (voyageForm.voyageForm.dischargeProt == colCache.value[i].value) {
+          if (voyageForm.value.dischargeProt == colCache.value[i].value) {
             index.value = i;
             break;
           }
         }
         if (index.value != -1) {
-          voyageForm.voyageForm.dischargeProtId =
-            colCache.value[index.value].key;
+          voyageForm.value.dischargeProtId = colCache.value[index.value].key;
         } else {
           let b = colCache.value.some((item) => {
             return (
-              item.value == voyageForm.voyageForm.dischargeProt &&
-              item.key == voyageForm.voyageForm.dischargeProtId
+              item.value == voyageForm.value.dischargeProt &&
+              item.key == voyageForm.value.dischargeProtId
             );
           });
           if (!b) {
-            voyageForm.voyageForm["dischargeProt"] = "";
-            voyageForm.voyageForm["dischargeProtId"] = "";
+            voyageForm.value["dischargeProt"] = "";
+            voyageForm.value["dischargeProtId"] = "";
           }
         }
         break;
@@ -792,14 +584,36 @@ function clear(type) {
     }
   }, 200);
 }
-let addVoyageForm = ref(null);
+let voyageFormRef = ref(null);
 
 async function addVoyage() {
-  addVoyageForm.value.validate(async (valid) => {
+  voyageFormRef.value.validate(async (valid) => {
     if (valid) {
-      console.log("提交", voyageForm.voyageForm);
+      console.log("提交", voyageForm.value);
+      discPorts.value = discPorts.value.filter((item) => {
+        return item.discPortId && item.discPort;
+      });
+
+      if (!discPorts.value.length) {
+        ElNotification({
+          title: "请选择至少一个装货港",
+          type: "error",
+        });
+        return;
+      }
+      let discId = [];
+      let discStr = [];
+      console.log(discPorts.value);
+      for (let i of discPorts.value) {
+        discId.push(i.discPortId);
+        discStr.push(i.discPort);
+      }
+      let dischargePortIds = discId.join(",");
+      let dischargePorts = discStr.join(",");
+      voyageForm.value.dischargePortIds = dischargePortIds;
+      voyageForm.value.dischargePorts = dischargePorts;
       let res = await api.addVoyage({
-        ...voyageForm.voyageForm,
+        ...voyageForm.value,
       });
       if (res.data.status == 0) {
         ElNotification({
@@ -816,7 +630,7 @@ async function addVoyage() {
         });
       }
     } else {
-      console.log("未提交", voyageForm.voyageForm);
+      console.log("未提交", voyageForm.value);
     }
   });
 }
@@ -825,7 +639,7 @@ let shipsCache = ref([]);
 let colCache = ref([]);
 let cargoOwnersCache = ref([]);
 
-const searchShip = _.debounce(
+let searchShip = _.debounce(
   async (queryString, cb) => {
     if (!queryString) return;
     let res = await api.searchShip({
@@ -844,37 +658,21 @@ const searchShip = _.debounce(
   1000,
   { leading: true }
 );
-
-const selectShip = (item) => {
-  voyageForm.voyageForm.shipId = item.shipId;
+let shipStr = ref("");
+let cargoOwnerStr = ref("");
+let loadPortStr = ref("");
+let discPortStr = ref("");
+let selectShip = (item) => {
+  voyageForm.value.shipId = item.value;
+  voyageForm.value.shipName = item.key;
 };
 
-const searchCargoOwner = _.debounce(
-  async (queryString, cb) => {
-    if (!queryString) return;
-    let res = await api.searchUser({
-      term: queryString,
-      identity: 2,
-    });
-    let cargoOwners = [];
-    if (res.data.status == 0) {
-      cargoOwners = res.data.result;
-      for (let i of cargoOwners) {
-        i.value = `${i.userName}`;
-      }
-      cargoOwnersCache.value = cargoOwners;
-      cb(cargoOwners);
-    }
-  },
-  1000,
-  { leading: true }
-);
-
-const selectCargoOwner = (item) => {
-  voyageForm.voyageForm.cargoOwnerId = item.userId;
+let selectCargoOwner = (item) => {
+  voyageForm.value.cargoOwnerName = item.key;
+  voyageForm.value.cargoOwnerId = item.value;
 };
 
-const getCol = _.debounce(
+let getCol = _.debounce(
   async (queryString, cb) => {
     if (!queryString) return;
     let res = await api.getCol({
@@ -891,213 +689,97 @@ const getCol = _.debounce(
   { leading: true }
 );
 
-const selectLoadPort = (item) => {
-  voyageForm.voyageForm.loadPortId = item.key;
-  voyageForm.voyageForm.loadPort = item.value;
+let selectLoadPort = (item) => {
+  voyageForm.value.loadPortId = item.value;
+  voyageForm.value.loadPort = item.key;
 };
 
-const selectDischargeProt = (item) => {
-  voyageForm.voyageForm.dischargeProtId = item.key;
-  voyageForm.voyageForm.dischargeProt = item.value;
+let selectDischargeProt = (item, index) => {
+  discPorts.value[index] = { discPortId: item.value, discPort: item.key };
+};
+
+let selectCargo = (item) => {
+  voyageForm.value.cargo = item.key;
 };
 
 function resetAddVoyageForm() {
   voyageAddDialogVisible.value = false;
-  addVoyageForm.value.resetFields();
+  voyageFormRef.value.resetFields();
+  voyageForm.value = {
+    cargoOwnerId: "",
+    cargoOwnerName: "",
+    startTime: "",
+    endTime: "",
+    loadPort: "",
+    dischargeProt: "",
+    cargo: "",
+    tons: 0,
+    loadPortId: "",
+    dischargeProtId: "",
+    shipId: "",
+    shipName: "",
+    pieces: 0,
+  };
+  discPorts.value = [{}];
 }
 
 let sortradio = ref(0);
-async function downloadFYDI() {
-  let res0 = await api.getFYFIDownloadUrl({
-    loginAccountId: localStorage.loginAccountId,
-  });
 
-  if (res0.data.result == 1) {
-    ElNotification({
-      type: "info",
-      title: "更新中",
+let isUpLoading = ref(false);
+function upFYDISuccess(e) {
+  if (e.status == 0) {
+    ElNotification.success({
+      title: "成功",
+      duration: 2000,
+      message: e.msg,
     });
   } else {
-    let url = res0.data.result;
-    let a = document.createElement("a");
-    a.setAttribute("href", url);
-    a.click();
+    ElNotification.error({
+      title: "失败",
+      duration: 2000,
+      message: e.msg,
+    });
   }
+  isUpLoading.value = false;
+  FYDIModalVisable.value = false;
+  FYDIParams.value.cargoOwnerId = "";
+  cargoOwnerCompanyStr.value = "";
 }
 
-let exportModalVisable = ref(false);
-let exportModalTitle = ref("");
-let currentMonth = ref("");
-
-function showExportModal(type) {
-  exportModalVisable.value = true;
-  exportModalTitle.value = type;
+function beforeFYDI() {
+  isUpLoading.value = true;
 }
 
-let isLoadingZip = ref(false);
-
-async function exportZip() {
-  if (!currentMonth.value && exportModalTitle.value != "航次列表") return;
-
-  isLoadingZip.value = true;
-  let path = "";
-  let type = "";
-  let postData = {
-    loginAccountId: localStorage.loginAccountId,
-  };
-  let title = "";
-  switch (exportModalTitle.value) {
-    case "航次列表": {
-      path = "/voyage/exportListExcel";
-      type =
-        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
-      title = `${exportModalTitle.value}`;
-      let arr = [];
-      for (let i of tableData.value) {
-        arr.push(i.id);
-      }
-      postData.voyageIds = arr.join(",");
-      break;
-    }
-    case "航次跟踪": {
-      path = "/voyage/exportMultExcel";
-      type = "application/zip";
-      postData.date = currentMonth.value;
-      title = `${exportModalTitle.value}${currentMonth.value}`;
+let FYDIModalVisable = ref(false);
+let FYDIParams = ref({
+  cargoOwnerId: "",
+});
+let cargoOwnerCompanyStr = ref("");
+function selectCargoOwnerUpload(item) {
+  FYDIParams.value.cargoOwnerId = item.value;
+}
 
-      break;
-    }
-    case "卸货记录": {
-      path = "/voyage/exportMultDischargeExcel";
-      type = "application/zip";
-      postData.date = currentMonth.value;
-      title = `${exportModalTitle.value}${currentMonth.value}`;
-      break;
-    }
-  }
-  try {
-    let res = await downloadBlobFile(
-      `${url.baseurl}${path}`,
-      postData,
-      title,
-      "post",
-      type
-    );
-    if (res.status == 0) {
-      ElNotification({
-        title: "导出成功!",
-        type: "success",
-      });
-    } else {
-      ElNotification({
-        title: "暂无数据",
-      });
-    }
-  } catch (error) {
-    ElNotification({
-      title: "暂无数据",
-    });
-  } finally {
-    isLoadingZip.value = false;
-    currentMonth.value = "";
-    exportModalVisable.value = false;
-  }
+function FYDIModalClose() {
+  isUpLoading.value = false;
+  FYDIModalVisable.value = false;
+  FYDIParams.value.cargoOwnerId = "";
+  cargoOwnerCompanyStr.value = "";
 }
 
 function rowStyle({ row }) {
   let rowStyle = {};
-
-  if (row.daysInPort >= 20 && row.daysInPort < 25) {
-    rowStyle.color = "#f9ca24";
-  } else if (row.daysInPort >= 25 && row.daysInPort < 30) {
-    rowStyle.color = "#f0932b";
-  } else if (row.daysInPort >= 30) {
-    rowStyle.color = "#eb4d4b";
-  }
-
-  return rowStyle;
-}
-
-let voyageNameVisable = ref(true);
-let loadPortVisable = ref(true);
-let dischargePortVisable = ref(true);
-let expectedArrivalTimeVisable = ref(true);
-let abnormalStatusVisable = ref(true);
-let daysInPortVisable = ref(true);
-let todayPhotoCountVisable = ref(true);
-let cargoVisable = ref(true);
-let actualLoadTonsVisable = ref(true);
-let unloadedtonsVisable = ref(true);
-let remainTonsVisable = ref(true);
-let hasInsuranceVisable = ref(true);
-
-let selectAllVisable = ref(true);
-function selectAll(e) {
-  loadPortVisable.value = e;
-  dischargePortVisable.value = e;
-  expectedArrivalTimeVisable.value = e;
-  abnormalStatusVisable.value = e;
-  daysInPortVisable.value = e;
-  todayPhotoCountVisable.value = e;
-  cargoVisable.value = e;
-  actualLoadTonsVisable.value = e;
-  unloadedtonsVisable.value = e;
-  remainTonsVisable.value = e;
-  hasInsuranceVisable.value = e;
-}
-
-function selectSingle(e) {
-  if (!e) {
-    selectAllVisable.value = e;
+  if (row.daysInPort >= 30) {
+    rowStyle.color = "red";
+    return rowStyle;
   }
 }
+let discPorts = ref([{}]);
 
-let loadPortFilterStr = ref("");
-function selectLoadPortFilter(item) {
-  voyageListPostData.value.loadPortId = item.key;
-  getVoyageList();
-}
-let discPortFilterStr = ref("");
-function selectDiscPortFilter(item) {
-  voyageListPostData.value.discPortId = item.key;
-  getVoyageList();
-}
-let cargoFilterStr = ref("");
-function selectCargoFilter(item) {
-  voyageListPostData.value.cargo = item.key;
-  getVoyageList();
+function addDiscPort() {
+  discPorts.value.push({});
 }
-
-function resetFilter() {
-  loadPortFilterStr.value = "";
-  discPortFilterStr.value = "";
-  cargoFilterStr.value = "";
-  voyageListPostData.value = {};
-  getVoyageList();
-}
-let cargoOptions = ref([]);
-async function getCargoSelect() {
-  if (cargoOptions.value.length) return;
-  let res = await api.getCargoSelect({
-    loginAccountId: loginAccountId.value,
-    status: 2,
-    term: "",
-  });
-  cargoOptions.value = res.data.result;
-}
-
-let portOptions = ref([]);
-async function getPortSelect() {
-  if (portOptions.value.length) return;
-  let res = await api.getCol({
-    term: "",
-  });
-  portOptions.value = res.data.result;
-}
-
 onMounted(() => {
   getVoyageList();
-  loginAccountId.value = localStorage.loginAccountId;
 });
 </script>
 <style scoped>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff