ソースを参照

feat: crm包裹处理页面初稿.

peter 1 週間 前
コミット
b0c98293cb
2 ファイル変更415 行追加0 行削除
  1. 410 0
      src/pages/shipping-tracking2/index.vue
  2. 5 0
      src/route.ts

+ 410 - 0
src/pages/shipping-tracking2/index.vue

@@ -0,0 +1,410 @@
+<template>
+  <div class="w-[100vw] bg-white page-shipping-tracking2">
+    <div
+      v-loading="loading"
+      class="pt-2 w-[100%] min-h-[100vh]"
+    >
+      <el-form inline>
+        <el-form-item label="Container Num">
+          <el-input
+            size="small"
+            v-model="containerNumber"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="REF">
+          <el-input
+            size="small"
+            v-model="soRef"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-tooltip
+            content="注意 Container Number 和 REF只能同时搜一个, 如果同时输入, 那只会用REF来搜"
+          >
+            <el-button
+              size="small"
+              @click="getList()"
+              type="primary"
+              :loading="loading"
+            >
+              搜索输入的单号/柜号
+            </el-button>
+          </el-tooltip>
+          <el-button
+            size="small"
+            @click="getList(2)"
+            type="warning"
+            :loading="loading"
+          >
+            搜索所有未处理申请
+          </el-button>
+          <el-button
+            size="small"
+            :loading="loading"
+            @click="exportFunc"
+          >
+            导出Excel
+          </el-button>
+          <el-button
+            size="small"
+            :loading="loading"
+            @click="commit"
+          >保存改动</el-button>
+        </el-form-item>
+      </el-form>
+      <div
+        class="mb-2"
+        v-show="tabList.length"
+      >
+        <el-button-group>
+          <el-button
+            v-for="tab in tabList"
+            :key="tab"
+            size="small"
+            :type="tab === currentTab ? 'primary' : ''"
+            @click="currentTab = tab"
+          >
+            {{ tab.length ? tab : '未输入箱规' }}
+          </el-button>
+        </el-button-group>
+
+        <div class="flex text-red-500 text-sm">
+          当前筛选得 {{ computedList.length }} 条,
+          <!-- <br /> -->
+          从CRM共搜索得 {{ list.length }} 条记录
+        </div>
+      </div>
+      <el-table
+        :data="computedList"
+        max-height="550"
+        stripe
+        size="small"
+        :row-style="calcRowStyle"
+        :row-class-name="
+          (row: any) => {
+            return row.editFlag ? 'table-row-edit' : ''
+          }
+        "
+        border
+      >
+        <el-table-column
+          fixed
+          type="index"
+          width="50"
+        ></el-table-column>
+        <el-table-column
+          v-for="col in columnList"
+          :key="col.prop"
+          :width="col.width ? col.width : ''"
+          :fixed="col.fixed ? col.fixed : false"
+          :label="col.label"
+          :prop="col.prop"
+        >
+          <template #default="scope">
+            <div v-if="col.prop === 'Owner'">
+              {{ getName(scope.row.Owner.id) }}
+            </div>
+
+            <div v-if="col.prop === 'Client_Label_Links'">
+              <el-tooltip
+                :content="scope.row.Client_Label_Links"
+                v-if="scope.row.Client_Label_Links"
+              >
+                <a
+                  :href="scope.row.Client_Label_Links"
+                  target="_blank"
+                >
+                  点击会在新标签页打开
+                </a>
+              </el-tooltip>
+            </div>
+
+            <div v-if="col.prop === 'Artwork_Links'">
+              <el-tooltip
+                :content="scope.row.Artwork_Links"
+                v-if="scope.row.Artwork_Links"
+              >
+                <a
+                  :href="scope.row.Artwork_Links"
+                  target="_blank"
+                >
+                  点击会在新标签页打开
+                </a>
+              </el-tooltip>
+            </div>
+
+            <div v-if="col.prop === 'Courier'">
+              <el-input
+                v-model="scope.row.Courier"
+                @change="scope.row.editFlag = true"
+                size="small"
+              ></el-input>
+            </div>
+            <div v-if="col.prop === 'Tracking_No'">
+              <el-input
+                size="small"
+                v-model="scope.row.Tracking_No"
+                @change="scope.row.editFlag = true"
+              ></el-input>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { defineComponent, ref, watch, computed, nextTick } from 'vue'
+import {
+  ElNotification,
+  ElTable,
+  ElTableColumn,
+  ElInput,
+  ElForm,
+  ElFormItem,
+  ElButton,
+  ElTooltip,
+  ElTabs,
+  ElTabPane,
+  ElButtonGroup,
+  ElMessage,
+} from 'element-plus'
+import cloneDeep from 'lodash.clonedeep'
+import dayjs from 'dayjs'
+import * as XLSX from 'xlsx'
+import request from '@/utils/axios'
+import { last } from 'lodash'
+
+defineComponent({
+  name: 'ComponentShippingTracking2',
+})
+let loading = ref(false)
+let list = ref([] as any[])
+// @ts-ignore
+const zoho = window.ZOHO
+zoho.embeddedApp.on('PageLoad', function () {
+  zoho.CRM.CONFIG.getCurrentUser().then(function (data: any) {
+    if (Array.isArray(data.users) && data.users.length) {
+      // const user = data.users[0]
+      // console.log(user, 'user')
+      // currentUser.value = user.id
+      // currentUserName.value = user.full_name || ''
+      // currentUserRawData.value = cloneDeep(user)
+      // getList()
+      getUserList()
+    }
+  })
+})
+let containerNumber = ref('')
+let soRef = ref('')
+let tabList = ref([] as any)
+let currentTab = ref('')
+let resetData = () => {
+  list.value = []
+  tabList.value = []
+  currentTab.value = ''
+}
+let userList = ref(new Map())
+let getUserList = () => {
+  return zoho.CRM.API.coql({
+    select_query:
+      'select id,first_name,last_name,state from users where first_name is not null',
+  }).then((res: any) => {
+    console.log(res, 'res')
+    if (Array.isArray(res.data) && res.data.length) {
+      // userList.value = res.data
+      res.data.forEach((i: any) => {
+        userList.value.set(i.id, i)
+      })
+    }
+  })
+}
+
+let getName = (id: string) => {
+  const temp = userList.value.get(id) || {}
+  let firstName = temp.first_name || ''
+  let lastName = temp.last_name || ''
+  return firstName + ' ' + lastName
+}
+const columnList = [
+  { label: 'Urgent', prop: 'Urgent' },
+  { label: 'REF', prop: 'SO_Reference', width: 140 },
+  { label: 'Sales Person', prop: 'Owner', width: 120 },
+  {
+    label: 'Qty to be sent',
+    prop: 'Total_Actual_Product',
+    width: 100,
+  },
+  {
+    label: 'Qty (Carton)',
+    prop: 'Total_Quantity_Carton',
+    width: 130,
+  },
+  { label: 'Weight', prop: 'Total_Weight', width: 100 },
+  { label: 'Cube', prop: 'Total_Cube', width: 100 },
+  {
+    label: 'AU Standard Pallet',
+    prop: 'AU_Standard_Pallet',
+    width: 150,
+  },
+  {
+    label: 'Delivery Notes',
+    prop: 'Delivery_Notes',
+    width: 200,
+  },
+  {
+    label: 'Client Label Links',
+    prop: 'Client_Label_Links',
+    width: 145,
+  },
+  { label: 'Artwork Link', prop: 'Artwork_Links', width: 145 },
+  {
+    label: 'Time Requirement',
+    prop: 'Time_requirement',
+    width: 150,
+  },
+  { label: 'Packing', prop: 'Packing', width: 100 },
+  {
+    label: 'Delivery Method',
+    prop: 'Delivery_Method',
+    width: 160,
+  },
+  { label: 'Carton Mark', prop: 'Carton_Mark', width: 150 },
+  {
+    label: 'Container_Number',
+    prop: 'Container_Number',
+    width: 150,
+    fixed: 'right',
+  },
+  { label: 'Courier', prop: 'Courier', width: 180, fixed: 'right' },
+  { label: 'Tracking No', prop: 'Tracking_No', width: 180, fixed: 'right' },
+]
+let getList = (type = 1) => {
+  loading.value = true
+  let sql =
+    'select ' +
+    columnList.map((i: any) => `Shipping_Tracking.${i.prop}`).join(',') +
+    ' from Shipping_Tracking '
+
+  let whereSQL =
+    "  (Package_Type='SGL Package' and Confirm_send_to_Starshipit=true) "
+
+  if (type === 2) {
+    sql += ' where (Tracking_No is null or Courier is null) and' + whereSQL
+  } else if (soRef.value) {
+    sql = sql + ` where (SO_Reference like '%${soRef.value}%') and` + whereSQL
+  } else if (containerNumber.value) {
+    sql +=
+      ` where (Container_Number like '%${containerNumber.value}%') and` +
+      whereSQL
+  } else {
+    sql += ' where ' + whereSQL
+  }
+
+  return zoho.CRM.API.coql({
+    select_query: sql,
+  })
+    .then((res: any) => {
+      console.log(res, 'res')
+      if (Array.isArray(res.data) && res.data.length) {
+        list.value = res.data.map((i: any) => {
+          return {
+            ...i,
+            editFlag: false,
+          }
+        })
+        const temp = res.data
+          .filter(
+            (i: any) =>
+              ![null, 'null', '', '-', '_', 'N/A'].includes(i.Container_Number),
+          )
+          .map((i: any) => i.Container_Number)
+        // tabList.value 去重
+        tabList.value = [...new Set(temp)]
+        if (tabList.value.length) tabList.value.unshift('')
+
+        console.log(tabList.value.length, 'tabList.value.length')
+        if (tabList.value.length > 1) currentTab.value = tabList.value[1]
+      } else if (res.status === 204) {
+        ElNotification({
+          type: 'warning',
+          title: 'No Data Found',
+          message: res.statusText || `zoho api return: ${res.status}`,
+          duration: 3000,
+        })
+        resetData()
+      } else {
+        resetData()
+      }
+    })
+    .catch(() => {
+      resetData()
+    })
+    .finally(() => {
+      loading.value = false
+    })
+}
+
+let computedList = computed(() =>
+  currentTab.value
+    ? list.value.filter((i) => i.Container_Number === currentTab.value)
+    : list.value.filter((i) => ['', 'null', null].includes(i.Container_Number)),
+)
+zoho.embeddedApp.init()
+// 给表格加红绿背景. 颜色用的tailwind的 red green
+const calcRowStyle = ($e: any) => {
+  const result = {} as any
+  if ($e.row.editFlag) result['background-color'] = 'rgb(187, 247, 208)'
+  return result
+}
+// 帮我把导出表格的表头, 从columnList中获取的prop改为label, 但是表格其他数据不变
+let exportFunc = () => {
+  if (!computedList.value.length) {
+    ElNotification({
+      type: 'warning',
+      title: '换个tab筛选数据吧',
+      message: '当前表格没有数据可以导出',
+      duration: 3000,
+    })
+    return
+  }
+  const sheetData = computedList.value.map((i) => {
+    let result = {
+      ...cloneDeep(i),
+      Urgent: `${i.Urgent}`,
+      Owner: getName(i.Owner.id),
+    }
+    delete result.id
+    delete result.editFlag
+
+    // 关键:根据 columnList 顺序构建导出对象
+    let ordered: { [label: string]: any } = {}
+    columnList.forEach((col) => {
+      ordered[col.label] = result[col.prop]
+    })
+    return ordered
+  })
+
+  const sheet1 = XLSX.utils.json_to_sheet(sheetData, {
+    header: columnList.map((i) => i.label),
+  })
+
+  const wb = XLSX.utils.book_new()
+
+  sheet1['!cols'] = columnList.map((i) => {
+    return { wpx: i.width ? i.width + 30 : 110 }
+  })
+
+  XLSX.utils.book_append_sheet(wb, sheet1, 'sheet1')
+  let name = currentTab.value || '未输入箱规'
+  XLSX.writeFile(wb, name + '.xlsx')
+}
+const commit = () => {
+  if (loading.value) return
+  // loading.value = true
+  ElMessage.info('正在开发中')
+}
+</script>
+<style lang="scss" scoped></style>

+ 5 - 0
src/route.ts

@@ -125,6 +125,11 @@ const router = createRouter({
       path: '/so-confirm',
       component: () => import('@/pages/so-confirm/index.vue'),
     },
+    {
+      name: 'ComponentShippingTracking2',
+      path: '/shipping-tracking2',
+      component: () => import('@/pages/shipping-tracking2/index.vue'),
+    },
     {
       path: '/:pathMatch(.*)*',
       name: 'pageNotFound',