4 次代碼提交 fc3ee8086d ... 2b4a1945b2

作者 SHA1 備註 提交日期
  peter 2b4a1945b2 change: indent sku选择.商品图片修复. 1 月之前
  peter c43152edb2 feat: indent客户名供应商名远程搜索/自建逻辑优化. 1 月之前
  peter ef554766fb change: cargo货期功能迭代. 1 月之前
  peter 9de3fc5ae2 doc: 增加代码文档注释. 1 月之前

+ 123 - 30
src/pages/cargo-consolidation-request/index.vue

@@ -35,7 +35,7 @@
 
       <el-tabs v-model="currentTab">
         <el-tab-pane
-          v-for="tab in tabs"
+          v-for="tab in finalTabs"
           :key="tab.value"
           :label="tab.label"
           :name="tab.value"
@@ -138,7 +138,30 @@
               {{ currentRow.Name }}
             </div>
           </div>
-          <div class="flex flex-wrap min-w-[800px]">
+          <div class="flex flex-wrap min-w-[800px] mr-2">
+            <el-input
+              v-if="
+                currentTab === 'Arrangement' &&
+                ['可用', '已截仓'].includes(currentRow.Status) &&
+                [
+                  '4791186000259693001',
+                  '4791186000022965001',
+                  '4791186000052269001',
+                ].includes(currentUser)
+              "
+              style="width: 200px; height: 24px; margin-right: 10px"
+              size="small"
+              v-model="bookingNumber"
+            >
+              <template #append>
+                <el-button
+                  size="small"
+                  @click="updateBookingNumber"
+                >
+                  更新订舱号
+                </el-button>
+              </template>
+            </el-input>
             <el-button
               v-if="
                 ['可用', '已截仓'].includes(currentRow.Status) &&
@@ -155,21 +178,21 @@
               确认集货
             </el-button>
             <el-button
-              v-if="currentTab === 'my_request'"
+              v-if="['Arrangement', 'my_request'].includes(currentTab)"
               size="small"
               @click="addBulkProduct"
             >
-              Submit Bulk Production Request
+              提交大货集货申请
             </el-button>
             <el-button
-              v-if="currentTab === 'my_request'"
+              v-if="['Arrangement', 'my_request'].includes(currentTab)"
               size="small"
               @click="addSample"
             >
-              Submit Sample Request
+              提交样品集货申请
             </el-button>
             <el-button
-              v-if="currentTab === 'my_request'"
+              v-if="['Arrangement', 'my_request'].includes(currentTab)"
               :disabled="subList.length < 1"
               size="small"
               type="danger"
@@ -182,21 +205,21 @@
               :disabled="subList.length < 1"
               @click="exportSubTable"
             >
-              Export Excel File
+              导出Excel文档
             </el-button>
             <el-button
-              v-if="currentTab === 'my_request'"
+              v-if="['Arrangement', 'my_request'].includes(currentTab)"
               :disabled="subList.length < 1"
               size="small"
               type="primary"
               class="custom-button small"
               @click="commit"
             >
-              Commit
+              保存更改
             </el-button>
           </div>
         </div>
-        <div class="flex justify-between min-w-[350px]">
+        <div class="flex flex-wrap min-w-[380px] gap-2">
           <div class="flex">总重量: {{ computedWeight }}</div>
           <div class="flex">总体积: {{ computedCube }}</div>
           <div class="flex">总离岸价: {{ computedTotalFOB }}</div>
@@ -351,10 +374,11 @@
           label="负责人"
           fixed="right"
           width="120"
+          prop="Sales_Person"
         >
           <template #default="scope">
             <el-input
-              v-model="scope.row.Requester.name"
+              v-model="scope.row.Sales_Person"
               size="small"
               disabled
             ></el-input>
@@ -364,18 +388,17 @@
           label="申请人"
           fixed="right"
           width="120"
-          prop="Sales_Person"
         >
           <template #default="scope">
             <el-input
-              v-model="scope.row.Sales_Person"
+              v-model="scope.row.Requester.name"
               size="small"
               disabled
             ></el-input>
           </template>
         </el-table-column>
         <el-table-column
-          v-show="currentTab === 'my_request'"
+          v-show="['Arrangement', 'my_request'].includes(currentTab)"
           fixed="right"
           label="更新时间"
           width="90"
@@ -400,14 +423,14 @@
           "
           fixed="right"
           label="操作"
-          width="85"
+          width="90"
         >
           <template #default="scope">
             <el-tooltip
               content="新增未commit的行会被直接移除; 已commit的行只会标记, 正式commit后才会删除"
             >
               <el-button
-                v-if="currentTab === 'my_request'"
+                v-if="['Arrangement', 'my_request'].includes(currentTab)"
                 type="danger"
                 size="small"
                 link
@@ -540,6 +563,7 @@ defineComponent({
 
 const currentUser = ref('')
 const currentUserName = ref('')
+const currentUserRawData = ref({} as any)
 let loading = ref(false)
 let list = ref([] as any[])
 let currentTab = ref('all')
@@ -562,6 +586,10 @@ let tabs = [
     value: 'my_request',
   },
 ]
+
+let finalTabs = ref([] as any[])
+finalTabs.value = cloneDeep(tabs)
+
 let computedList = computed(() => {
   return list.value.filter((i: any) => {
     let condition = true
@@ -679,7 +707,7 @@ const generateSubList = () => {
         (i: any) =>
           i.Parent_Id.id === currentRow.value.id &&
           (currentTab.value === 'my_request'
-            ? i.Sales_Person === currentUserName.value
+            ? i.Requester.id === currentUser.value
             : true),
       )
       .map((i: any) => ({
@@ -794,6 +822,10 @@ const goodMaterialOption = ref([
   'PVC 聚氯乙烯',
   'Velvet 天鹅绒',
   'Zinc alloy 锌合金',
+  'Aluminum alloy 铝合金',
+  'Glass 玻璃',
+  'Rubber 橡胶',
+  'Stainless Steel 不锈钢',
 ])
 
 const addBulkProduct = () => {
@@ -1080,6 +1112,47 @@ const ensure = () => {
     })
   })
 }
+let bookingNumber = ref('')
+const updateBookingNumber = () => {
+  bookingNumber.value = bookingNumber.value.trim()
+  if (!bookingNumber.value || !currentRow.value.id) {
+    ElMessage.error('请填写订舱号')
+    return
+  }
+  loading.value = true
+  ElMessageBox.confirm(
+    `确定要把该记录的订舱号更新为"${bookingNumber.value}"吗?`,
+    {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    },
+  ).then(() => {
+    zoho.CRM.API.updateRecord({
+      Entity: 'Sea_Freight_Table',
+      Trigger: ['workflow'],
+      APIData: {
+        id: currentRow.value.id,
+        Booking_Number: bookingNumber.value,
+      },
+    }).then((res: any) => {
+      if (
+        Array.isArray(res.data) &&
+        res.data.length &&
+        res.data[0].code === 'SUCCESS'
+      ) {
+        ElMessage.success('操作成功, 正在刷新数据')
+        loading.value = false
+        getList()
+        clearSubList()
+      } else {
+        loading.value = false
+        ElMessage.error('操作失败, 请稍后再试或者联系管理员')
+      }
+    })
+  })
+}
+
 // @ts-ignore
 const zoho = window.ZOHO
 zoho.embeddedApp.on('PageLoad', function () {
@@ -1089,30 +1162,50 @@ zoho.embeddedApp.on('PageLoad', function () {
       // console.log(user, 'user')
       currentUser.value = user.id
       currentUserName.value = user.full_name || ''
+      currentUserRawData.value = cloneDeep(user)
       getList()
     }
   })
 })
 
 zoho.embeddedApp.init()
+watch(currentUserRawData, () => {
+  if (!currentUserRawData.value.role) return false
+
+  let result = currentUserRawData.value.role.name.indexOf('Logistics') === -1
+
+  if (result) {
+    finalTabs.value = cloneDeep(tabs)
+    finalTabs.value.push({
+      label: 'Arrangement',
+      value: 'Arrangement',
+    })
+  }
+})
 
 let computedWeight = computed(() => {
-  return subList.value.reduce((t, c) => {
-    t = t + Number(c.Weight)
-    return t
-  }, 0)
+  return subList.value
+    .reduce((t, c) => {
+      t = t + Number(c.Weight)
+      return t
+    }, 0)
+    .toFixed(2)
 })
 let computedCube = computed(() => {
-  return subList.value.reduce((t, c) => {
-    t = t + Number(c.Cube)
-    return t
-  }, 0)
+  return subList.value
+    .reduce((t, c) => {
+      t = t + Number(c.Cube)
+      return t
+    }, 0)
+    .toFixed(2)
 })
 let computedTotalFOB = computed(() => {
-  return subList.value.reduce((t, c) => {
-    t = t + Number(c.Total_FOB)
-    return t
-  }, 0)
+  return subList.value
+    .reduce((t, c) => {
+      t = t + Number(c.Total_FOB)
+      return t
+    }, 0)
+    .toFixed(2)
 })
 
 // 订单轨迹地图插件

+ 49 - 17
src/pages/indent-manage/indent/components/info.vue

@@ -57,15 +57,15 @@
                       v-model="item.vendor_id"
                       :remote-method="($e: any) => queryVenderList($e, index)"
                       filterable
-                      allow-create
                       remote
                       style="width: 100%"
                       placeholder="请选择供应商"
                       @change="($e) => changeVenderSelect($e, index)"
                     >
+                      <!-- allow-create -->
                       <el-option
-                        v-for="option in vendorList[index]"
-                        :key="option.id"
+                        v-for="(option, subIndex) in vendorList[index]"
+                        :key="option.id || subIndex"
                         :value="option.id"
                         :label="option.name"
                       ></el-option>
@@ -326,7 +326,9 @@
                 <el-input
                   v-model="item.product_capacity"
                   placeholder="请输入容量"
-                  @input="($e) => inputFilter($e, forms[index], 'product_capacity')"
+                  @input="
+                    ($e) => inputFilter($e, forms[index], 'product_capacity')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -349,7 +351,9 @@
                 <el-input
                   v-model="item.product_material"
                   placeholder="请输入材质"
-                  @input="($e) => inputFilter($e, forms[index], 'product_material')"
+                  @input="
+                    ($e) => inputFilter($e, forms[index], 'product_material')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -372,7 +376,9 @@
                 <el-input
                   v-model="item.product_battery"
                   placeholder="是否带电池"
-                  @input="($e) => inputFilter($e, forms[index], 'product_battery')"
+                  @input="
+                    ($e) => inputFilter($e, forms[index], 'product_battery')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -395,7 +401,10 @@
                 <el-input
                   v-model="item.product_require_print"
                   placeholder="请输入要求"
-                  @input="($e) => inputFilter($e, forms[index], 'product_require_print')"
+                  @input="
+                    ($e) =>
+                      inputFilter($e, forms[index], 'product_require_print')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -420,7 +429,9 @@
                 <el-input
                   v-model="item.product_color"
                   placeholder="请输入颜色"
-                  @input="($e) => inputFilter($e, forms[index], 'product_color')"
+                  @input="
+                    ($e) => inputFilter($e, forms[index], 'product_color')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -443,7 +454,10 @@
                 <el-input
                   v-model="item.product_require_color"
                   placeholder="请输入颜色定制要求"
-                  @input="($e) => inputFilter($e, forms[index], 'product_require_color')"
+                  @input="
+                    ($e) =>
+                      inputFilter($e, forms[index], 'product_require_color')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -470,7 +484,9 @@
                   placeholder="其他信息"
                   type="textarea"
                   :rows="3"
-                  @input="($e) => inputFilter($e, forms[index], 'product_other')"
+                  @input="
+                    ($e) => inputFilter($e, forms[index], 'product_other')
+                  "
                 ></el-input>
                 <div
                   v-if="index < forms.length - 1"
@@ -1308,17 +1324,32 @@ watch(
     show.value = visible > 0
   },
 )
-const queryVenderList = function (keywords: string, index: number) {
+const queryVenderList = function (keyword: string, index: number) {
+  let keywords = keyword.trim()
+  if (!keywords.length) return
   getVendorList({ keywords }).then((response: any) => {
+    const defaultCreateOption = {
+      name: keywords,
+      id: '',
+    }
     if (Array.isArray(response.result)) {
+      const tempStr = keywords.replace(/\S_-/g, '').toLowerCase()
+      const tempList = response.result.map((i: any) =>
+        i.name.replace(/\S_-/g, '').toLowerCase(),
+      )
+      let result = []
+      if (response.result.length) {
+        if (tempList.includes(tempStr)) {
+          result = response.result
+        } else {
+          // 结果里面没找到输入的搜索字符串, 就把它加入到结果里面当成‘新增的’
+          result = [cloneDeep(defaultCreateOption)].concat(response.result)
+        }
+      }
       if (manualVendor.value.id) {
-        vendorList.value.splice(
-          index,
-          1,
-          [manualVendor.value].concat(response.result || []),
-        )
+        vendorList.value.splice(index, 1, [manualVendor.value].concat(result))
       } else {
-        vendorList.value.splice(index, 1, response.result || [])
+        vendorList.value.splice(index, 1, result)
       }
     }
   })
@@ -1334,6 +1365,7 @@ const changeVenderSelect = function (value: string | number, index: number) {
         id: '',
       }
     } else {
+      // vendor_name === vendor_id 为新增
       forms.value[index].vendor_name = value || ''
       forms.value[index].vendor_phone = ''
       forms.value[index].vendor_type = ''

+ 36 - 19
src/pages/indent-manage/indent/components/skuSelect.vue

@@ -48,7 +48,13 @@
             :key="sku.id"
             class="sku-item"
           >
-            <div class="image"></div>
+            <div class="image flex justify-center">
+              <img
+                v-if="sku.images.length"
+                :src="sku.images[0]"
+                class="h-[100%] w-auto"
+              />
+            </div>
             <div class="sku-name">{{ sku.product_name }}</div>
             <div class="flex justify-between items-center">
               <div class="sku-code">Product Code: {{ sku.product_sku }}</div>
@@ -101,7 +107,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineComponent, ref, watch } from 'vue'
+import { defineComponent, ref, inject, watch } from 'vue'
 import { ElButton, ElInput, ElTree, ElDialog, ElPagination } from 'element-plus'
 
 import { getCategoryTree, getSkuList } from '@/api/indent.js'
@@ -109,6 +115,8 @@ import skuApply from './skuApply.vue'
 defineComponent({
   name: 'ComponentSkuSelect',
 })
+
+const $mediaRegExp = inject('mediaRegExp') as RegExp
 const { visible = false } = defineProps<{ visible: boolean }>()
 
 const $emit = defineEmits(['update:visible', 'select'])
@@ -194,7 +202,20 @@ const getSku = () => {
   getSkuList(params)
     .then((response: any) => {
       const res = response.result
-      skuList.value = res.data
+      skuList.value = res.data.map((item: any) => {
+        const t =
+          typeof item.images === 'string'
+            ? `${item.images}`.split(',').filter((i: string) => i.length > 0)
+            : []
+        return {
+          ...item,
+          images: t.map((i: string) => {
+            return $mediaRegExp.test(i)
+              ? i
+              : import.meta.env.VITE_APP_OSS_PREFIX + i
+          }),
+        }
+      })
       total.value = res.total
     })
     .finally(() => {
@@ -212,22 +233,18 @@ watch(
     }
   },
 )
-watch(
-  currentCategory,
-  () => {
-    console.log('watch run bbb')
-    if (!currentCategory.value) return
-    console.log('watch run')
-    keywords.value = ''
-    skuList.value = []
-    pageForm.value = {
-      page: 1,
-      limit: 20,
-    }
-    total.value = 0
-    getSku()
-  },
-)
+watch(currentCategory, () => {
+  if (!currentCategory.value) return
+
+  keywords.value = ''
+  skuList.value = []
+  pageForm.value = {
+    page: 1,
+    limit: 20,
+  }
+  total.value = 0
+  getSku()
+})
 const close = (done = {} as any) => {
   $emit('update:visible', false)
   if (typeof done === 'function') done()

+ 34 - 11
src/pages/indent-manage/indent/edit.vue

@@ -25,21 +25,21 @@
             prop="custom_name"
           >
             <el-select
-              v-model="form.custom_name"
+              v-model="form.custom_id"
               style="width: 100%"
               :placeholder="$t('text_please_select')"
-              :remote-method="getCustomListFun"
+              :remote-method="debounce(getCustomListFun, 500)"
               :loading="loading"
-              allow-create
               remote
               filterable
               @change="customChange"
             >
+              <!-- allow-create -->
               <el-option
-                v-for="option in customList"
-                :key="option.id"
+                v-for="(option, index) in customList"
+                :key="option.id || index"
                 :label="option.name"
-                :value="option.name"
+                :value="option.id"
               ></el-option>
             </el-select>
           </el-form-item>
@@ -294,6 +294,7 @@ import {
 import type { FormInstance } from 'element-plus'
 import cloneDeep from 'lodash.clonedeep'
 import dayjs from 'dayjs'
+import debounce from 'lodash.debounce'
 import ImageUpload from '@/components/ImageUpload.vue'
 import editInfo from './components/info.vue'
 
@@ -492,8 +493,9 @@ const selectSku = (data: any) => {
   form.value.item_id = data.id || ''
 }
 const customChange = (value: any) => {
-  const temp = customList.value.filter((i: any) => i.name === value)
-  form.value.custom_id = temp.length ? temp[0].id : ''
+  const temp = customList.value.filter((i: any) => i.id === value)
+  // id为空且custom_name有值是新增
+  form.value.custom_name = temp.length ? temp[0].name : '-'
 }
 // 成功创建了报价, 把数据展示到界面
 const quotaCreated = (data: any) => {
@@ -571,13 +573,34 @@ const checkForm = (
     }
   })
 }
-const getCustomListFun = (keywords: string) => {
+const getCustomListFun = (keyword: string) => {
+  let keywords = keyword.trim()
+  if (!keywords.length) return
   loading.value = true
   customList.value = []
   getCustomList({ keywords })
     .then((response: any) => {
-      if (Array.isArray(response.result) && response.result.length) {
-        customList.value = response.result
+      const defaultCreateOption = {
+        name: keywords,
+        id: '',
+      }
+      if (Array.isArray(response.result)) {
+        const tempStr = keywords.replace(/\S_-/g, '').toLowerCase()
+        const tempList = response.result.map((i: any) =>
+          i.name.replace(/\S_-/g, '').toLowerCase(),
+        )
+        let result = []
+        if (response.result.length) {
+          if (tempList.includes(tempStr)) {
+            result = response.result
+          } else {
+            // 结果里面没找到输入的搜索字符串, 就把它加入到结果里面当成‘新增的’
+            result = [cloneDeep(defaultCreateOption)].concat(response.result)
+          }
+        } else if (keywords.length) {
+          result = [cloneDeep(defaultCreateOption)]
+        }
+        customList.value = result
       }
     })
     .finally(() => {