Browse Source

fix:修改address功能

AmandaG 4 tháng trước cách đây
mục cha
commit
e4e6c8b1db

+ 15 - 1
src/api/module/Delivery.ts

@@ -260,7 +260,6 @@ export const saveDliveryBookingEmail = (params: any, config: any) => {
   )
 }
 
-
 /**
  * 审核delivery_booking
  */
@@ -274,4 +273,19 @@ export const reviewDliveryBooking = (params: any, config: any) => {
     },
     config
   )
+}
+
+/**
+ *  Address List自动补全
+ */
+export const getAddressCountryCityData = (params: any, config: any) => {
+  return HttpAxios.post(
+    `${baseUrl}`,
+    {
+      action: 'destination_delivery_load',
+      operate: 'country_city_load',
+      ...params
+    },
+    config
+  )
 }

+ 1 - 0
src/styles/theme.scss

@@ -14,6 +14,7 @@
   --color-white: #fff;
   --color-success: #00a870;
   --color-warning: #edb82f;
+  --color-warning-2: #E0A100;
   --color-danger: #c9353f;
   --color-grey: #f4f5f5;
 

+ 19 - 30
src/views/DestinationDelivery/src/components/ConfiguRations/src/components/ConfigurationsTable.vue

@@ -1,24 +1,24 @@
 <script setup lang="ts">
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
-import { formatTimezone, formatNumber } from '@/utils/tools'
+import { formatNumber } from '@/utils/tools'
 import { ref, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
-import { useVisitedRowState } from '@/stores/modules/visitedRow'
 import DefaultConfiguration from '../images/default_configuration@2x.png'
 
-const visitedRowState = useVisitedRowState()
 const router = useRouter()
-interface ColumnsListItem {
-  field: String
-  title: String
-  type: String
-  formatter: String
-}
-const props = defineProps({
-  ColumnsList: Array<ColumnsListItem>,
-  height: Number
-})
+
+interface ColumnConfig {
+  field: string
+  title: string
+  type: string
+  width?: number
+  formatter?: string
+}
+const props = defineProps<{
+  ColumnsList: ColumnConfig[]
+  height: number
+}>()
 
 const columnstest = ref(props.ColumnsList)
 
@@ -72,12 +72,11 @@ const getTableColumns = async () => {
 }
 // 获取表格数据
 const getTableData = (isPageChange?: boolean) => {
-  const rc = isPageChange ? pageInfo.value.total : -1
   $api
     .getConfigurationList({
       cp: pageInfo.value.pageNo,
       ps: pageInfo.value.pageSize,
-      rc
+      rc: isPageChange ? pageInfo.value.total : -1
     })
     .then((res: any) => {
       if (res.code === 200) {
@@ -114,25 +113,15 @@ const deleteMoniTable = (row: any) => {
 }
 
 // 编辑表格数据
-const handleedit = ({ row }: any) => {
-  router.push({
-    path: '/destination-delivery/ConfiguRations/CreateNewRule',
-    query: { a: row._serial_no}
-  })
-}
-
-const handleedittow = (row: any) => {
+const handleEdit = (row: any) => {
   router.push({
     path: '/destination-delivery/ConfiguRations/CreateNewRule',
     query: {a: row._serial_no}
   })
 }
-
+// 添加新规则
 const clickAddNewRule = () => {
-  router.push({
-    path: '/destination-delivery/ConfiguRations/CreateNewRule',
-    query: {}
-  })
+  router.push('/destination-delivery/ConfiguRations/CreateNewRule')
 }
 
 onMounted(() => {
@@ -148,7 +137,7 @@ onMounted(() => {
       :style="{ border: 'none'}"
       v-bind="tableData"
       :height="props.height"
-      @cell-dblclick="handleedit"
+      @cell-dblclick="({ row }) => handleEdit(row)"
     >
       <!-- 空数据时的插槽 -->
       <template #empty>
@@ -169,7 +158,7 @@ onMounted(() => {
         </span>
       </template>
       <template #action="{ row }">
-        <el-button class="el-button--blue" style="height: 24px" @click="handleedittow(row)">
+        <el-button class="el-button--blue" style="height: 24px" @click="handleEdit(row)">
           <span class="font_family icon-icon_edit_b"></span>
         </el-button>
         <el-popover trigger="click" :visible="row.visible" placement="left" :width="480">

+ 26 - 51
src/views/DestinationDelivery/src/components/ConfiguRations/src/components/CreateNewRule.vue

@@ -177,34 +177,21 @@ const getKLNList = (): Promise<KLNItem[]> => {
   });
 };
 // 自动查询KLN
-let timeout: ReturnType<typeof setTimeout>
-const isNodata = ref([])
-const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
-  const results = queryString
-    ? KLNLists.value.filter(createFilter(queryString))
-    : KLNLists.value
-  isNodata.value = results
-  clearTimeout(timeout)
-  timeout = setTimeout(() => {
-    if(results.length == 0) {
-      cb([{ 
-        isNoData: true, 
-        value: '无搜索结果' 
-      }]);
-    } else {
-      cb(results)
-    }
-  }, 1000 * Math.random())
-}
-
-const createFilter = (queryString: string) => {
-  return (restaurant: KLNItem) => {
-    return (
-      restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) != -1
-    )
+const loading = ref(false)
+const options = ref<KLNItem[]>([])
+const querySearchAsync = (query: string) => {
+  if (query) {
+    loading.value = true
+    setTimeout(() => {
+      loading.value = false
+      options.value = KLNLists.value.filter((item) => {
+        return item.label.toLowerCase().includes(query.toLowerCase())
+      })
+    }, 1000)
+  } else {
+    options.value = []
   }
 }
-
 // 保存
 const handleSubmitRule = () => {
   const airlist = recommendCheckedAirList.value.map(item => {
@@ -291,7 +278,6 @@ const handleSubmitRule = () => {
 }
 
 onMounted(() => {
-  getKLNList()
   InitRuleData()
 })
 
@@ -463,21 +449,22 @@ onMounted(() => {
               </div>
             </template>
             <div>
-              <el-autocomplete
+              <el-select
                 v-model="KLNPLCvalue"
-                style="width: 400px;margin-bottom: 5px;"
+                filterable
+                remote
                 placeholder="Select Employee Account"
-                :fetch-suggestions="querySearchAsync"
+                :remote-method="querySearchAsync"
+                :loading="loading"
+                style="width: 400px;margin-bottom: 5px;"
               >
-                <template #default="{ item }">
-                  <div :class="[
-                    'suggestion-item',
-                    { 'no-data-item': item.isNoData }
-                  ]">
-                    {{ item.value }}
-                  </div>
-                </template>
-              </el-autocomplete>
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </div>
           </el-collapse-item>
       </el-collapse>
@@ -567,18 +554,6 @@ onMounted(() => {
   box-shadow: none;
   border: 1px solid var(--color-theme);
 }
-.no-data-item {
-  color: var(--color-neutral-2);
-  text-align: center;
-  padding: 20px;
-  cursor: default;
-  &:hover {
-    background-color: transparent !important;
-  }
-}
-.suggestion-item {
-  padding: 5px 20px;
-}
 .cancel_header {
   font-size: 18px;
   font-weight: 700;

+ 587 - 119
src/views/DestinationDelivery/src/components/CreateNewBooking/src/CreateNewbooking.vue

@@ -20,10 +20,19 @@ const CreateNewBOokingSearch = ref('')
 const status = ref('')
 const booking = ref('')
 const DateValue = ref('')
+const DeliveryTime = ref('')
 const bookingTableRef = ref()
 const VesselName = ref([])
 const VesselNametest = ref('')
-const isFocused = ref(false)
+const ShipperValue = ref('')
+const ConsigneeValue = ref('')
+const getAddressListData = ref({})
+// const isFocused = ref(false)
+const isFocused = ref({
+  Shipper: false,
+  Consignee: false,
+  Vessel: false
+})
 const isataFocused = ref(false)
 const isetaFocused = ref(false)
 const ManageVisible = ref(false)
@@ -43,6 +52,10 @@ const Addressradio = ref()
 const LocationName = ref('')
 const AddressLine1 = ref('')
 const AddressLine2 = ref('')
+const AddressLine3 = ref('')
+const AddressLine4 = ref('')
+const CountryCode = ref('')
+const CityCode = ref('')
 const CountryCity = ref('')
 const PostalCode = ref('')
 const ContactPerson = ref('')
@@ -63,8 +76,19 @@ const ModeType = ref([
 ])
 
 // 设置无法点击
+
 const isNotClickAddress = computed(() => {
-  return NoPermissionVisible.value || NoEligibleVisible.value || isDisabled.value
+  if(a == undefined) {
+    if(Object.keys(getAddressListData.value).length == 0) {
+      return true
+    }
+  }
+  
+  if(NoPermissionVisible.value || NoEligibleVisible.value || isDisabled.value) {
+    return true
+  }
+
+  return false
 })
 
 // 设置无法保存
@@ -78,6 +102,7 @@ const isNotSubmit = computed(() => {
       selectedAddressList.value == undefined ||
       modetypeValue.value == '' ||
       DateValue.value == '' ||
+      DeliveryTime.value == '' ||
       Modification.value == null ||
       Modification.value == ''
     ) {
@@ -91,7 +116,8 @@ const isNotSubmit = computed(() => {
     Object.keys(checkShipmentsSubmitInfo.value).length == 0 ||
     selectedAddressList.value == undefined ||
     modetypeValue.value == '' ||
-    DateValue.value == ''
+    DateValue.value == '' ||
+    DeliveryTime.value == ''
   ) {
     return true
   }
@@ -99,6 +125,39 @@ const isNotSubmit = computed(() => {
   return false;
 })
 
+// 控制Address是否超长
+const isShowLimitLine1 = ref(false)
+const isShowLimitLine2 = ref(false)
+const isShowLimitLine3 = ref(false)
+const isShowLimitLine4 = ref(false)
+const isShowLimitLine1Style = computed(() => {
+  return AddressLine1.value.length == 45
+})
+const isShowLimitLine2Style = computed(() => {
+  return AddressLine2.value.length == 45
+})
+const isShowLimitLine3Style = computed(() => {
+  return AddressLine3.value.length == 45
+})
+const isShowLimitLine4Style = computed(() => {
+  return AddressLine4.value.length == 45
+})
+const createInputLimiter = (targetRef, showRef) => {
+  return (val: string) => {
+    if (val.length > 45) {
+      targetRef.value = val.substring(0, 45);
+      showRef.value = true;
+      setTimeout(() => {
+        showRef.value = false;
+      }, 3000);
+    }
+  };
+};
+const handleAddressLine1 = createInputLimiter(AddressLine1, isShowLimitLine1);
+const handleAddressLine2 = createInputLimiter(AddressLine2, isShowLimitLine2);
+const handleAddressLine3 = createInputLimiter(AddressLine3, isShowLimitLine3);
+const handleAddressLine4 = createInputLimiter(AddressLine4, isShowLimitLine4);
+
 const ManageAddressList = ref([])
 // 需要特殊样式的日期列表
 const specialDates = ref([]);
@@ -112,10 +171,12 @@ const DateRangeChangeATA = (val:any) => {
   ATATimeList.value = val.data
 }
 
-const showLabel = computed(() => {
-  // return VesselName.value.length!= 0 || isFocused.value
-  return VesselNametest.value!= '' || isFocused.value
-})
+const createShowLabel = (valueRef, focusKey) => computed(() => 
+  valueRef.value !== '' || isFocused.value[focusKey]
+)
+const showLabelShipper = createShowLabel(ShipperValue, 'Shipper')
+const showLabelConsignee = createShowLabel(ConsigneeValue, 'Consignee')
+const showLabelVessel = createShowLabel(VesselNametest, 'Vessel')
 
 const showataLabel = computed(() => {
   return ATATimeList.value != null || isataFocused.value
@@ -126,11 +187,11 @@ const showETAlabel = computed(() => {
 })
 
 const changeFocus = (val: boolean) => {
-  isFocused.value = val
+  // isFocused.value = val
 }
 
-const changeFocustest = (val: boolean) => {
-  isFocused.value = val
+const changeFocustest = (type: any, val: boolean) => {
+  isFocused.value[type] = val
 }
 
 const DateChangeFocusATA = (val: boolean) => {
@@ -139,7 +200,59 @@ const DateChangeFocusATA = (val: boolean) => {
 const DateChangeFocusETA = (val: boolean) => {
   isetaFocused.value = val
 }
-
+//自动补全查询
+interface CountryItem {
+  value: string
+  label: string
+}
+const countrys = ref<CountryItem[]>([])
+const Countryoptions = ref<CountryItem[]>([])
+const Countryloading = ref(false)
+const city = ref<CountryItem[]>([])
+const Cityoptions = ref<CountryItem[]>([])
+const cityloading = ref(false)
+const getAddressCountryCityData = (type: any) => {
+  $api.getAddressCountryCityData({
+     term: '',
+     term_type: type,
+     limit: type == 'country' ? CityCode.value : CountryCode.value
+  })
+  .then((res: any) => {
+    if (res.code === 200) {
+      if(type == 'country') {
+        countrys.value = res.data
+      } else {
+        city.value = res.data
+      }
+    }
+  })
+}
+const querySearchCountry = (query: string) => {
+  if (query) {
+    Countryloading.value = true
+    setTimeout(() => {
+      Countryloading.value = false
+      Countryoptions.value = countrys.value.filter((item) => {
+        return item.label.toLowerCase().includes(query.toLowerCase())
+      })
+    }, 1000)
+  } else {
+    Countryoptions.value = []
+  }
+}
+const querySearchCity = (query: string) => {
+  if (query) {
+    cityloading.value = true
+    setTimeout(() => {
+      cityloading.value = false
+      Cityoptions.value = city.value.filter((item) => {
+        return item.label.toLowerCase().includes(query.toLowerCase())
+      })
+    }, 1000)
+  } else {
+    Cityoptions.value = []
+  }
+}
 // 特殊日期样式
 const getCurrentStyle = (current: any) => {
   const dateString = current.format('YYYY.MM.DD');
@@ -148,50 +261,122 @@ const getCurrentStyle = (current: any) => {
       background: '#b3e5d4', 
       borderRadius: '6px',
       color: `var(--color-neutral-1)`
-    };
+    }
   }
-  
   // 默认样式
-  return {};
+  return {}
+}
+const submitAddressList = ref([])
+const currentEditAddress = ref<any>(null)
+const updateAddressList = (addressData) => {
+  const { id, contact_type } = addressData;
+  const existingIndex = submitAddressList.value.findIndex(
+    item => item.id === id
+  )
+  if (contact_type === 'Delete') {
+    if (existingIndex !== -1) {
+      submitAddressList.value.splice(existingIndex, 1, {
+        ...submitAddressList.value[existingIndex],
+        contact_type: 'Delete'
+      })
+    } else {
+      submitAddressList.value.push({
+        ...addressData,
+        contact_type: 'Delete'
+      })
+    }
+    return
+  }
+  if (existingIndex !== -1) {
+    submitAddressList.value.splice(existingIndex, 1, {
+      ...submitAddressList.value[existingIndex],
+      ...addressData,
+      contact_type
+    })
+  } else {
+    submitAddressList.value.push(addressData)
+  }
+};
+const isAddNewAddressVisible = ref(false)
+const AddNewAddressDelivery = () => {
+  currentEditAddress.value = null;
+  isAddNewAddressVisible.value = true
+  AddNewAddressVisible.value = true
+  AddressLine1.value = ''
+  AddressLine2.value = ''
+  AddressLine3.value = ''
+  AddressLine4.value = ''
+  CountryCode.value = ''
+  CityCode.value = ''
+  PostalCode.value = ''
+  ContactPerson.value = ''
+  ContactNumber.value = ''
 }
 // 保存新地址
 const SaveNewAddress = () => {
   if(
-    LocationName.value != '' &&
-    AddressLine1.value != '' &&
-    AddressLine2.value != '' &&
-    CountryCity.value != '' &&
+    AddressLine1.value != '' ||
+    AddressLine2.value != '' ||
+    AddressLine3.value != '' ||
+    AddressLine4.value != '' &&
+    CountryCode.value != '' &&
+    CityCode.value != '' &&
     PostalCode.value != '' &&
     ContactPerson.value != '' &&
     ContactNumber.value != ''
   ) {
-    ManageAddressList.value.push({
-      location_name: LocationName.value,
+    const addressData = {
       address_1: AddressLine1.value,
       address_2: AddressLine2.value,
-      country: CountryCity.value,
-      city: CountryCity.value,
+      address_3: AddressLine3.value,
+      address_4: AddressLine4.value,
+      country: CountryCode.value,
+      city: CityCode.value,
       postal_code: PostalCode.value,
       contact_person: ContactPerson.value,
       contact_number: ContactNumber.value,
-      notes: instructions.value,
-      deliver_address_is_new: 'yes'
-    })
+      contact_id: '',
+      sync_key: '',
+      from_station: '',
+      contact_type: 'Add',
+      create_user: 'Online_D_Address',
+      id: `temp_${Date.now()}`
+    }
+    if (currentEditAddress.value) {
+      addressData.id = currentEditAddress.value.id;
+      
+      const index = ManageAddressList.value.findIndex(
+        item => item.id === currentEditAddress.value.id
+      )
+      if (index !== -1) {
+        ManageAddressList.value.splice(index, 1, addressData)
+      }
+      
+      updateAddressList(addressData)
+    } else {
+      ManageAddressList.value.push(addressData)
+      updateAddressList(addressData)
+    }
+    if(isAddNewAddressVisible.value) {
+      handleClickAddress()
+    }
     AddNewAddressVisible.value = false
+    currentEditAddress.value = null
   }
 }
 // 点击按钮
 const handleclickbutton = (val: any) => {
   Requirements.value = Requirements.value + val
 }
-
+let delivery_address = ''
 const changeAddressRadio = () => {
   ManageVisible.value = false
   if(Addressradio.value != undefined) {
     isselectedAddress.value = Addressradio.value
-
   }
   selectedAddressList.value = ManageAddressList.value[Addressradio.value]
+  delivery_address = `${selectedAddressList.value.contact_person}(${selectedAddressList.value.contact_number})\n${selectedAddressList.value.address_1}\n${selectedAddressList.value.address_2}\n${selectedAddressList.value.address_3}\n${selectedAddressList.value.address_4},${selectedAddressList.value.country},${selectedAddressList.value.city},${selectedAddressList.value.postal_code}`
+  console.log(delivery_address)
 }
 // 页面初始化
 let checkShipments = []
@@ -218,9 +403,10 @@ const getInitBookingData = () => {
           Requirements.value = res.data.data.special_requirements
           modetypeValue.value = res.data.data.delivery_mode
           DateValue.value = res.data.data.created_time
+          DeliveryTime.value = res.data.data.delivery_time
           Modification.value = res.data.data.modify_reason
-          const address1 = res.data.data.delivery_address.split('\n')[0]
-          checkShipments = res.data.data.tableData.map(item => ({ consignee_id: item.consignee_id }))
+          const address1 = res.data.data.delivery_address.split('\r\n')[1]
+          checkShipments = res.data.data.tableData.map(item => ({ consignee_id: item.consignee_id, country: item.dc_country}))
           checkShipmentsdata = Object.keys(checkShipments?.[0])
           checkShipmentsSubmit = Object.keys(res.data.data.tableData?.[0])
           checkShipmentsdata.forEach((item) => {
@@ -248,7 +434,8 @@ const getInitBookingData = () => {
             if (res.code === 200) {
               ManageAddressList.value = res.data
               ManageAddressList.value.forEach((item, index) => {
-                if(item.location_name === address1) {
+                if(item.address_1 === address1) {
+                  console.log(address1)
                   selectedAddressList.value = item
                   isselectedAddress.value = index
                   Addressradio.value = index
@@ -321,7 +508,8 @@ const getDateRangeArray = (startDateStr, endDateStr) => {
   }
 }
 const selectChangeEvent = (val: any, date: any, submitInfo: any) => {
-  checkShipmentsSubmitInfo.value = submitInfo
+  getAddressListData.value = {...val}
+  checkShipmentsSubmitInfo.value = {...submitInfo}
   if(date.length != 0) {
     isrecommenddate.value = areAllDateRangesSame(date)
     if(isrecommenddate.value) {
@@ -330,13 +518,28 @@ const selectChangeEvent = (val: any, date: any, submitInfo: any) => {
   } else {
     specialDates.value = []
   }
+}
+
+// 点击 Address Book
+const handleClickAddress = () => {
+  if(!isAddNewAddressVisible.value) {
+    ManageVisible.value = true
+  }
+  const nonDeletedAddresses = ManageAddressList.value.filter(
+    item => item.contact_type !== 'Delete'
+  )
   $api
   .getAddressBookList({
-    ...val,
+    ...getAddressListData.value,
   })
   .then((res: any) => {
     if (res.code === 200) {
-      ManageAddressList.value = res.data
+      const newAddresses = res.data.filter(
+        (apiAddr: any) => 
+          !nonDeletedAddresses.some(localAddr => localAddr.id === apiAddr.id)
+      )
+      ManageAddressList.value = [...nonDeletedAddresses, ...newAddresses]
+      ManageVisible.value = true
     }
   })
 }
@@ -352,23 +555,110 @@ const changeDatePicker = (val:any) => {
       if(!specialDates.value.includes(val)) {
         isRecommendDate.value = true
         recommendateWarning.value = 'This date is outside our recommended period.'
+        isConsistent.value = false
       }
     }
+  } else {
+    isRecommendDate.value = true
+    recommendateWarning.value = 'This date for following shipments is outside recommended period.'
+    isConsistent.value = false
+  }
+}
+// 新增地址
+const handleClickAddNewAddress = () => {
+  currentEditAddress.value = null;
+  AddNewAddressVisible.value = true
+  isAddNewAddressVisible.value = false
+  AddressLine1.value = ''
+  AddressLine2.value = ''
+  AddressLine3.value = ''
+  AddressLine4.value = ''
+  CountryCode.value = ''
+  CityCode.value = ''
+  PostalCode.value = ''
+  ContactPerson.value = ''
+  ContactNumber.value = ''
+}
+// 编辑地址
+const handleClickEditAddress = (val:any) => {
+  currentEditAddress.value = val;
+  AddNewAddressVisible.value = true
+  AddressLine1.value = val.address_1
+  AddressLine2.value = val.address_2
+  AddressLine3.value = val.address_3
+  AddressLine4.value = val.address_4
+  CountryCode.value = val.country
+  CityCode.value = val.city
+  PostalCode.value = val.postal_code
+  ContactPerson.value = val.contact_person
+  ContactNumber.value = val.contact_number
+  const updatedAddress = {
+    ...val,
+    contact_type: val.contact_type == 'Unedit'? 'Modify' : 'Add'
+  };
+  updateAddressList(updatedAddress);
+}
+// 删除地址
+const handleDeleteAddress = (val: any) => {
+  if(val.contact_type === 'Add') {
+    ManageAddressList.value = ManageAddressList.value.filter((item) => item.id !== val.id)
+  } else {
+    updateAddressList({
+      ...val,
+      contact_type: 'Delete'
+    });
+    ManageAddressList.value = ManageAddressList.value.filter((item) => item.id !== val.id)
+  }
+  if (selectedAddressList.value?.id === val.id) {
+    selectedAddressList.value = undefined;
+    isselectedAddress.value = null;
   }
 }
-
 // 保存
 const SubmitBooking = () => {
-  const date = DateValue.value.split('.')
-  const datetwo = date[1] + '/' + date[2] + '/' + date[1]
+  let datetwo = ''
+  if (a != undefined) {
+    const value = DateValue.value;
+    const parts = value.includes(' ') 
+      ? value.split(' ')[0].split('-') 
+      : value.split('.');
+    datetwo = `${parts[1]}/${parts[2]}/${parts[0]}`;
+  } else {
+    const parts = DateValue.value.split('.');
+    datetwo = `${parts[1]}/${parts[2]}/${parts[0]}`;
+  }
+  let result = []
+  if(submitAddressList.value.length != 0) {
+    result = submitAddressList.value.filter(item => 
+      item.id === selectedAddressList.value.id || 
+      item.contact_type === 'Delete'
+    )
+    const objExists = submitAddressList.value.some(item => item.id === selectedAddressList.value.id)
+    if (!objExists) {
+      result.push(selectedAddressList.value)
+    }
+  }else {
+    result.push(selectedAddressList.value)
+  }
+  let addressshipment = []
+  let addressshipmentinfo = {}
+  addressshipment = Object.keys(selectedAddressList.value)
+  addressshipment.forEach((item) => {
+    Object.assign(addressshipmentinfo, {
+      [item]: result.map((row) => row[item] )
+    })
+  })
+  console.log(addressshipmentinfo)
   $api
   .SaveBookingList({
     serial_no: a != undefined ? a : '',
     ...checkShipmentsSubmitInfo.value,
-    ...selectedAddressList.value,
+    ...addressshipmentinfo,
     ...checkShipmentsSubmitInfoData,
+    delivery_time: DeliveryTime.value,
     delivery_mode: modetypeValue.value,
     delivery_date: datetwo,
+    delivery_address: delivery_address,
     special_requirements: Requirements.value,
     modify_reason: Modification.value
   })
@@ -410,11 +700,14 @@ onMounted(() => {
     <el-divider v-if="a != undefined" style="margin: 8px 0" />
     <!-- Select Shipments -->
     <div class="select_shipments">
-      <div style="margin-bottom: 16px;"><span class="stars_red">*</span>Select Shipments</div>
-      <div class="flex shipments_search" v-if="a == undefined">
-        <el-input
+      <div v-if="isNotClickAddress" class="alertIndormation">Please select same consignee with same delivery information </div>
+      <div style="margin-bottom: 16px;"><span class="stars_red">*</span>Select Shipments<span class="title_warning">*Please select items with the same consignee.</span></div>
+      <div class="shipments_search" v-if="a == undefined">
+        <div class="flex">
+          <el-input
           placeholder="Enter Booking/HBL/PO/Carrier Booking No. "
           v-model="CreateNewBOokingSearch"
+          style="width: 34%;"
           class="log_input"
         >
           <template #prefix>
@@ -424,28 +717,59 @@ onMounted(() => {
               </svg>
             </span>
           </template>
-        </el-input>
-        <div class="input-with-label">
-          <CalendarDate style="margin: 0 8px;" :isNeedFooter="false" :isETA="true" @DateRangeChange="DateRangeChangeETA" @DateChangeFocus="DateChangeFocusETA"></CalendarDate>
-          <span v-if="showETAlabel" class="border-label">ETA</span>
-        </div>
-        <div class="input-with-label">
-          <CalendarDate :isNeedFooter="false" @DateRangeChange="DateRangeChangeATA" @DateChangeFocus="DateChangeFocusATA"></CalendarDate>
-          <span v-if="showataLabel" class="border-label">ATA</span>
-        </div>
-        <div class="input-with-label" style="margin: 0 8px;">
-          <!-- <AutoSelect ASPlaceholder="Input Vessel Name" :ASValue="VesselName" @changeFocus="changeFocus"></AutoSelect> -->
-          <el-input
-            placeholder="Input Vessel Name"
-            v-model="VesselNametest"
-            @focus="changeFocustest(true)"
-            @blur="changeFocustest(false)"
-            class="log_input"
-          >
           </el-input>
-          <span v-if="showLabel" class="border-label">Vessel Name</span>
+          <div class="input-with-label" style="margin: 0 8px;">
+            <!-- <AutoSelect ASPlaceholder="Input Vessel Name" :ASValue="VesselName" @changeFocus="changeFocus"></AutoSelect> -->
+            <el-input
+              placeholder="Shipper"
+              v-model="ShipperValue"
+              @focus="changeFocustest('Shipper',true)"
+              @blur="changeFocustest('Shipper',false)"
+              class="log_input"
+            >
+            </el-input>
+            <span v-if="showLabelShipper" class="border-label">Shipper</span>
+          </div>
+          <div class="input-with-label" style="margin-right: 8px;">
+            <!-- <AutoSelect ASPlaceholder="Input Vessel Name" :ASValue="VesselName" @changeFocus="changeFocus"></AutoSelect> -->
+            <el-input
+              placeholder="Consignee"
+              v-model="ConsigneeValue"
+              @focus="changeFocustest('Consignee',true)"
+              @blur="changeFocustest('Consignee',false)"
+              class="log_input"
+            >
+            </el-input>
+            <span v-if="showLabelConsignee" class="border-label">Consignee</span>
+          </div>
+          <el-button style="width: 108px;" class="el-button--dark create-button" @click="SearchShipment">Search</el-button>
+        </div>
+        <div class="flex" style="margin-top: 8px;">
+          <div class="input-with-label">
+            <CalendarDate :isNeedFooter="false" :isETA="true"
+            CalendarWidth="100%"
+            @DateRangeChange="DateRangeChangeETA" @DateChangeFocus="DateChangeFocusETA"></CalendarDate>
+            <span v-if="showETAlabel" class="border-label">ETA</span>
+          </div>
+          <div class="input-with-label" style="margin: 0 8px">
+            <CalendarDate :isNeedFooter="false"
+            CalendarWidth="100%" @DateRangeChange="DateRangeChangeATA" @DateChangeFocus="DateChangeFocusATA"></CalendarDate>
+            <span v-if="showataLabel" class="border-label">ATA</span>
+          </div>
+          <div class="input-with-label" style="margin-right: 8px;">
+            <!-- <AutoSelect ASPlaceholder="Input Vessel Name" :ASValue="VesselName" @changeFocus="changeFocus"></AutoSelect> -->
+            <el-input
+              placeholder="Input Vessel Name"
+              v-model="VesselNametest"
+              @focus="changeFocustest('Vessel',true)"
+              @blur="changeFocustest('Vessel',false)"
+              class="log_input"
+            >
+            </el-input>
+            <span v-if="showLabelVessel" class="border-label">Vessel Name</span>
+          </div>
+          <div style="width: 108px;"></div>
         </div>
-        <el-button class="el-button--dark create-button" @click="SearchShipment">Search</el-button>
       </div>
       <NewbookingTable ref="bookingTableRef" 
         @selectChangeEvent="selectChangeEvent"
@@ -456,30 +780,30 @@ onMounted(() => {
     <div class="delivery_address">
       <div class="deliverty_flex">
         <div><span class="stars_red">*</span>Delivery Address</div>
-        <el-button :disabled="isNotClickAddress" @click="ManageVisible = true" class="el-button--noborder--configuration"><span class="font_family icon-icon_location_b"></span> Address Book</el-button>
+        <el-button :disabled="isNotClickAddress" @click="handleClickAddress" class="el-button--noborder--configuration"><span class="font_family icon-icon_location_b"></span> Address Book</el-button>
       </div>
       <div class="empty_address" v-if="isselectedAddress == null">
         <img :src="AddNewAddress" width="48" style="margin-bottom: 8px;" />
-        <el-button :disabled="isNotClickAddress" class="el-button--main" @click="AddNewAddressVisible = true"> + Add New Address</el-button>
+        <el-button :disabled="isNotClickAddress" class="el-button--main" @click="AddNewAddressDelivery"> + Add New Address</el-button>
       </div>
-      <div v-else class="addressradio">
-        <el-radio>
+      <div v-else class="addressradio" style="padding-bottom: 4px;">
+        <el-radio class="selectedAddress">
           <div>
             <div class="radio_top">
-              <div class="radio_title">{{ selectedAddressList.location_name }}</div>
+              <div class="radio_title">{{ selectedAddressList.contact_person }} ({{ selectedAddressList.contact_number }})</div>
             </div>
             <div class="radio_content">
-              <div class="radio_content_text">{{ selectedAddressList.address_1 }}</div>
-              <div class="radio_content_text">{{ selectedAddressList.country }},{{ selectedAddressList.city }} {{ selectedAddressList.postal_code }}</div>
-            </div>
-            <div class="radio_bottom radio_content_text">
-              Contact: {{ selectedAddressList.contact_person }} {{ selectedAddressList.contact_number }}
+              <div v-if="selectedAddressList.address_1 != null && selectedAddressList.address_1 != ''" class="radio_content_text">{{ selectedAddressList.address_1 }}</div>
+              <div v-if="selectedAddressList.address_2 != null && selectedAddressList.address_2 != ''" class="radio_content_text">{{ selectedAddressList.address_2 }}</div>
+              <div v-if="selectedAddressList.address_3 != null && selectedAddressList.address_3 != ''" class="radio_content_text">{{ selectedAddressList.address_3 }}</div>
+              <div v-if="selectedAddressList.address_4 != null && selectedAddressList.address_4 != ''" class="radio_content_text">{{ selectedAddressList.address_4 }}</div>
+              <div class="radio_content_text">{{ selectedAddressList.country }},{{ selectedAddressList.city }},{{ selectedAddressList.postal_code }}</div>
             </div>
           </div>
         </el-radio>
       </div>
       <div class="delivery_type">
-        <div style="margin-right: 12px;">
+        <div>
           <div class="delivery_type_title"><span class="stars_red">*</span>Mode Type</div>
           <el-select
             v-model="modetypeValue"
@@ -495,28 +819,41 @@ onMounted(() => {
             />
           </el-select>
         </div>
+        <div style="margin: 0 12px;">
+          <div class="delivery_type_title"><span class="stars_red">*</span>Preferred Delivery Date</div>
+          <a-date-picker
+            v-model:value ="DateValue"
+            :disabled="isNotClickAddress"
+            @change="changeDatePicker"
+            :showToday="false"
+            style="width: 240px;"
+            :format="userStore.dateFormat"
+            placeholder="Please Select Date"
+            valueFormat="YYYY.MM.DD"
+          >
+            <template #renderExtraFooter>
+              <div class="recommended"><div class="recommend_color"></div>Recommended delivery date</div>
+            </template>
+            <template #dateRender="{ current }">
+              <div class="ant-picker-cell-inner" :style="getCurrentStyle(current)">
+                {{ current.date() }}
+              </div>
+            </template>
+          </a-date-picker>
+        </div>
         <div>
-        <div class="delivery_type_title"><span class="stars_red">*</span>Preferred Delivery Date</div>
-        <a-date-picker
-          v-model:value ="DateValue"
-          :disabled="isNotClickAddress"
-          @change="changeDatePicker"
-          :showToday="false"
-          style="width: 240px;"
-          :format="userStore.dateFormat"
-          placeholder="Please Select Date"
-          valueFormat="YYYY.MM.DD"
-        >
-          <template #renderExtraFooter>
-            <div class="recommended"><div class="recommend_color"></div>Recommended delivery date</div>
-          </template>
-          <template #dateRender="{ current }">
-            <div class="ant-picker-cell-inner" :style="getCurrentStyle(current)">
-              {{ current.date() }}
-            </div>
-          </template>
-        </a-date-picker>
-      </div>
+          <div class="delivery_type_title"><span class="stars_red">*</span>Delivery Time</div>
+          <el-time-select
+            v-model="DeliveryTime"
+            :disabled="isNotClickAddress"
+            start="00:00"
+            step="00:30"
+            end="23:30"
+            style="width: 240px;"
+            prefix-icon=""
+            placeholder="Please Select Time"
+          ></el-time-select>
+        </div>
       </div>
       <div class="delivery_type_title">Special Requirements</div>
       <div class="flex" style="margin-top: 8px;">
@@ -539,18 +876,18 @@ onMounted(() => {
         <el-radio v-for="(item, index) in ManageAddressList" :key="index" :value="index">
           <div class="addressradio">
             <div class="radio_top">
-              <div class="radio_title">{{ item.location_name }}</div>
-              <div>
-                <el-button class="el-button--blue"><span class="font_family icon-icon_edit_b"></span></el-button>
-                <el-button class="el-button--blue"><span class="font_family icon-icon_delete_b"></span></el-button>
+              <div class="radio_title">{{ item.contact_person }}({{ item.contact_number }})</div>
+              <div v-if="item.create_user == 'Online_D_Address'">
+                <el-button @click="handleClickEditAddress(item)" class="el-button--blue"><span class="font_family icon-icon_edit_b"></span></el-button>
+                <el-button @click="handleDeleteAddress(item)" class="el-button--blue"><span class="font_family icon-icon_delete_b"></span></el-button>
               </div>
             </div>
             <div class="radio_content">
-              <div class="radio_content_text">{{ item.address_1 }}</div>
-              <div class="radio_content_text">{{ item.country }},{{ item.city }} {{ item.postal_code }}</div>
-            </div>
-            <div class="radio_bottom radio_content_text">
-              Contact: {{ item.contact_person }} {{ item.contact_number }}
+              <div v-if="item.address_1 != null && item.address_1 != ''" class="radio_content_text">{{ item.address_1 }}</div>
+              <div v-if="item.address_2 != null && item.address_2 != ''" class="radio_content_text">{{ item.address_2 }}</div>
+              <div v-if="item.address_3 != null && item.address_3 != ''" class="radio_content_text">{{ item.address_3 }}</div>
+              <div v-if="item.address_4 != null && item.address_4 != ''" class="radio_content_text">{{ item.address_4 }}</div>
+              <div class="radio_content_text">{{ item.country }},{{ item.city }},{{ item.postal_code }}</div>
             </div>
           </div>
         </el-radio>
@@ -558,7 +895,7 @@ onMounted(() => {
       <template #header>
         <div class="my-header">
           <div class="header_Title">Manage Address</div>
-          <el-button  @click="AddNewAddressVisible = true" class="el-button--noborder--configuration">+ Add New Address</el-button>
+          <el-button  @click="handleClickAddNewAddress" class="el-button--noborder--configuration">+ Add New Address</el-button>
         </div>
       </template>
       <template #footer>
@@ -576,18 +913,109 @@ onMounted(() => {
       title="Add New Delivery Address"
       :show-close="false"
     >
-      <div class="diaolog_add_title"><span class="stars_red">*</span>Location Name</div>
-      <el-input class="inputmargin" placeholder="Enter location name" v-model="LocationName"></el-input>
-      <div class="diaolog_add_title"><span class="stars_red">*</span>Address Line 1</div>
-      <el-input class="inputmargin" placeholder="Street address, P.O. Box, or company name" v-model="AddressLine1"></el-input>
-      <div class="diaolog_add_title">Address Line 2</div>
-      <el-input class="inputmargin" placeholder="Unit number, floor, etc. (optional)" v-model="AddressLine2"></el-input>
+      <div class="diaolog_add_title"><span class="stars_red">*</span>Address</div>
+      <el-tooltip
+        class="box-item"
+        :visible="isShowLimitLine1"
+        effect="dark"
+        content="Maximum character limit reached (45 characters)"
+        placement="bottom"
+      >
+        <el-input @input="handleAddressLine1" class="inputmargin2" placeholder="Line 1" v-model="AddressLine1">
+          <template #suffix>
+            <div class="character-counter" :class="{ 'limit-reached': isShowLimitLine1Style }">
+              {{ AddressLine1.length }}/45
+            </div>
+          </template>
+        </el-input>
+      </el-tooltip>
+      <el-tooltip
+        class="box-item"
+        :visible="isShowLimitLine2"
+        effect="dark"
+        content="Maximum character limit reached (45 characters)"
+        placement="bottom"
+      >
+        <el-input @input="handleAddressLine2" class="inputmargin2" placeholder="Line 2" v-model="AddressLine2">
+          <template #suffix>
+            <div class="character-counter" :class="{ 'limit-reached': isShowLimitLine2Style }">
+              {{ AddressLine2.length }}/45
+            </div>
+          </template>
+        </el-input>
+      </el-tooltip>
+      <el-tooltip
+        class="box-item"
+        :visible="isShowLimitLine3"
+        effect="dark"
+        content="Maximum character limit reached (45 characters)"
+        placement="bottom"
+      >
+        <el-input @input="handleAddressLine3" class="inputmargin2" placeholder="Line 3" v-model="AddressLine3">
+          <template #suffix>
+            <div class="character-counter" :class="{ 'limit-reached': isShowLimitLine3Style }">
+              {{ AddressLine3.length }}/45
+            </div>
+          </template>
+        </el-input>
+      </el-tooltip>
+      <el-tooltip
+        class="box-item"
+        :visible="isShowLimitLine4"
+        effect="dark"
+        content="Maximum character limit reached (45 characters)"
+        placement="bottom"
+      >
+        <el-input style="margin-bottom: 16px;" @input="handleAddressLine4" class="inputmargin2" placeholder="Line 4" v-model="AddressLine4">
+          <template #suffix>
+            <div class="character-counter" :class="{ 'limit-reached': isShowLimitLine4Style }">
+              {{ AddressLine4.length }}/45
+            </div>
+          </template>
+        </el-input>
+      </el-tooltip>
       <div class="flex">
-        <div style="margin-right: 9px;width: 50%;">
-          <div class="diaolog_add_title"><span class="stars_red">*</span>Country/City</div>
-          <el-input class="inputmargin" placeholder="Unit number, floor, etc. (optional)" v-model="CountryCity"></el-input>
+        <div style="width: 33%;">
+          <div class="diaolog_add_title"><span class="stars_red">*</span>Country Code</div>
+          <el-select
+            v-model="CountryCode"
+            filterable
+            remote
+            @focus="getAddressCountryCityData('country')"
+            placeholder="Select Country"
+            :remote-method="querySearchCountry"
+            :loading="Countryloading"
+            class="inputmargin"
+          >
+            <el-option
+              v-for="item in Countryoptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
         </div>
-        <div style="width: 50%;">
+        <div style="margin: 0 9px;width: 33%;">
+          <div class="diaolog_add_title"><span class="stars_red">*</span>City Code</div>
+          <el-select
+            v-model="CityCode"
+            filterable
+            remote
+            @focus="getAddressCountryCityData('city')"
+            placeholder="Select City"
+            :remote-method="querySearchCity"
+            :loading="cityloading"
+            class="inputmargin"
+          >
+            <el-option
+              v-for="item in Cityoptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </div>
+        <div style="width: 33%;">
           <div class="diaolog_add_title"><span class="stars_red">*</span>Postal Code</div>
           <el-input class="inputmargin" placeholder="Enter postal code" v-model="PostalCode"></el-input>
         </div>
@@ -596,15 +1024,13 @@ onMounted(() => {
       <div class="flex">
         <div style="margin-right: 9px;width: 50%;">
           <div class="diaolog_add_title"><span class="stars_red">*</span>Contact Person</div>
-          <el-input class="inputmargin" placeholder="Name" v-model="ContactPerson"></el-input>
+          <el-input style="margin-top: 4px;" placeholder="Name" v-model="ContactPerson"></el-input>
         </div>
         <div style="width: 50%;">
           <div class="diaolog_add_title"><span class="stars_red">*</span>Contact Number</div>
-          <el-input class="inputmargin" placeholder="Mobile Numer" v-model="ContactNumber"></el-input>
+          <el-input style="margin-top: 4px;" placeholder="Mobile Numer" v-model="ContactNumber"></el-input>
         </div>
       </div>
-      <div class="diaolog_add_title" style="margin-bottom: 4px;">Additional Notes</div>
-      <el-input type="textarea" :rows="3" placeholder="Ddelivery instructions, landmarks,etc. (optional)" v-model="instructions"></el-input>
       <template #footer>
         <div class="dialog-footer" style="justify-content: end;">
           <el-button class="el-button--default dialog-button" @click="AddNewAddressVisible = false">Cancel</el-button>
@@ -774,6 +1200,18 @@ onMounted(() => {
   margin: 17px 24px 12px 24px;
   padding: 9px 16px 16px 16px;
   border-radius: 12px;
+  position: relative;
+}
+.alertIndormation {
+  position: absolute;
+  left: 35%;
+  top: 30%;
+  z-index: 1213;
+  background-color: var(--color-btn-default-dark-bg);
+  color: var(--color-btn-default-bg-color);
+  padding: 2px 4px;
+  border-radius: 3px;
+  box-shadow: 1px 1px 6px 0 rgba(0, 0, 0, 0.25);
 }
 .delivery_address {
   border: 1px solid var(--color-border);
@@ -784,6 +1222,11 @@ onMounted(() => {
 .stars_red {
   color: var(--color-danger);
 }
+.title_warning {
+  margin-left: 8px;
+  color: var(--color-neutral-2);
+  font-size: 12px;
+}
 .shipments_search {
   margin: 0 0 8px 0;
 }
@@ -794,7 +1237,7 @@ onMounted(() => {
 .input-with-label {
   position: relative;
   display: inline-block;
-  width: 35%;
+  width: 34%;
 }
 .border-label {
   position: absolute;
@@ -892,6 +1335,10 @@ onMounted(() => {
   padding: 0 16px;
   height: 48px;
 }
+:deep(.ManageDialog) {
+  max-height: 800px;
+  overflow-y: scroll;
+}
 .header_Title {
   font-size: 18px;
 }
@@ -908,7 +1355,6 @@ onMounted(() => {
 .radio_title {
   font-size: 14px;
   font-weight: 700;
-  margin-top: -7px;
 }
 .radio_content_text {
   color: var(--color-neutral-2);
@@ -929,8 +1375,14 @@ onMounted(() => {
   margin-right: 0;
   height: fit-content;
   line-height: 32px;
+  align-items: baseline;
+}
+:deep(.selectedAddress) {
   align-items: start;
 }
+:deep(.selectedAddress .radio_title) {
+  margin-top: -8px;
+}
 .el-button--blue {
   width: 24px;
   height: 24px;
@@ -945,6 +1397,9 @@ onMounted(() => {
 .inputmargin {
   margin: 4px 0 16px 0;
 }
+.inputmargin2 {
+  margin-top: 4px ;
+}
 .diaolog_add_title_bold {
   color: var(--color-neutral-1);
   font-size: 14px;
@@ -954,7 +1409,7 @@ onMounted(() => {
 .dialog-footer {
   display: flex;
   align-items: center;
-  justify-content: center;
+  justify-content: end;
 }
 .flex_center {
   display: flex;
@@ -1012,4 +1467,17 @@ onMounted(() => {
     color: var(--color-neutral-2);
   }
 }
+:deep(.el-select__wrapper.is-filterable) {
+  height: 32px !important;
+}
+:deep(.inputmargin .el-select__wrapper.is-filterable) {
+  height: 40px !important;
+}
+.character-counter {
+  color: var(--color-neutral-3);
+  font-size: 12px;
+}
+.limit-reached {
+  color: var(--color-warning-2);
+}
 </style>

+ 16 - 4
src/views/DestinationDelivery/src/components/CreateNewBooking/src/components/NewbookingTable.vue

@@ -114,18 +114,29 @@ let checkRecommend = []
 let checkShipmentsdata = []
 let checkShipmentsInfo = {}
 let checkShipmentsSubmitInfo = {}
+const checkUniformArray = (arrary: Array<{ consignee_id: any; country: any }>) => {
+  if (arrary.length === 0) return false;
+  const first = arrary[0];
+  for (let i = 1; i < arrary.length; i++) {
+    if (arrary[i].consignee_id !== first.consignee_id) {
+        return false;
+    }
+  }
+  return [first];
+}
 const selectChangeEvent = () => {
   const $grid = tableRef.value
   if ($grid) {
     const records = $grid.getCheckboxRecords()
-    checkShipments = records.map(item => ({ consignee_id: item.consignee_id }))
+    checkShipments = records.map(item => ({ consignee_id: item.consignee_id, country: item.dc_country }))
     checkRecommend = records.map(item => ({ date_range: item.date_range.split('-'), Hbol: item.h_bol  }))
-    if(checkShipments.length != 0) {
-      checkShipmentsdata = Object.keys(checkShipments?.[0])
+    const array = checkUniformArray(checkShipments)
+    if(array != false) {
+      checkShipmentsdata = Object.keys(checkUniformArray(checkShipments)?.[0])
       checkShipmentsSubmit = Object.keys(records?.[0])
       checkShipmentsdata.forEach((item) => {
         Object.assign(checkShipmentsInfo, {
-          [item]: checkShipments.map((row) => row[item] )
+          [item]: array.map((row) => row[item] )
         })
       })
       checkShipmentsSubmit.forEach((item) => {
@@ -141,6 +152,7 @@ const selectChangeEvent = () => {
       })
     } else {
       checkShipmentsSubmitInfo = {}
+      checkShipmentsInfo = {}
     }
     emits('selectChangeEvent',checkShipmentsInfo, checkRecommend,checkShipmentsSubmitInfo)
   }

+ 3 - 2
src/views/DestinationDelivery/src/components/TableView/src/TableView.vue

@@ -313,7 +313,7 @@ const clickEmailBtn = (row: any) => {
 }
 
 // edit
-const handelEdit = (row: any) => {
+const handleEdit = (row: any) => {
   router.push({
     path: '/destination-delivery/CreateNewBooking',
     query: { a: row._serial_no}
@@ -370,6 +370,7 @@ defineExpose({
       ref="tableRef"
       v-vloading="tableLoadingTableData || tableLoadingColumn"
       :height="props.height"
+      @cell-dblclick="({ row }) => handleEdit(row)"
       :style="{ border: 'none' }"
       v-bind="tableData"
     >
@@ -411,7 +412,7 @@ defineExpose({
         </el-button>
         <!-- edit -->
         <el-button
-          @click="handelEdit(row)"
+          @click="handleEdit(row)"
           class="action-btn el-button--blue"
           style="height: 24px; width: 24px"
           v-if="isEmployeeRole && row.status === 'Pending Approval'"