Переглянути джерело

feat: crm付款申请-国内运费相关逻辑改造. 初稿.

peter 8 місяців тому
батько
коміт
8cf50be172

+ 4 - 1
src/pages/payment-record/components/edit.vue

@@ -134,7 +134,10 @@
             </el-form-item>
 
             <el-form-item label="Payment Type">
-              <el-select v-model="form.payment_type">
+              <el-select
+                v-model="form.payment_type"
+                disabled
+              >
                 <el-option
                   v-for="option in paymentOption"
                   :key="option.value"

+ 414 - 0
src/pages/payment-record/components/edit2.vue

@@ -0,0 +1,414 @@
+<template>
+  <div class="dialog-edit-record-item">
+    <el-dialog
+      v-model="dialogVisible"
+      width="800px"
+      :title="editMode === 1 ? 'New line' : 'Edit'"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :before-close="handleClose"
+    >
+      <el-form
+        ref="mainForm"
+        :rules="formRule"
+        :model="form"
+        label-width="140px"
+      >
+        <div class="flex start form-box">
+          <div class="flex-auto">
+            <el-form-item
+              label="PO Number"
+              prop="PO_Number"
+            >
+              <el-input
+                v-model="form.PO_Number"
+                placeholder="eg: POXXXX"
+                @change="(v) => (form.PO_Number = v.toUpperCase())"
+              />
+            </el-form-item>
+            <el-form-item
+              label="PO Number2"
+              prop="PO_Number2"
+            >
+              <el-input
+                v-model="form.PO_Number2"
+                placeholder="eg: POXXXX"
+                @change="(v) => (form.PO_Number2 = v.toUpperCase())"
+              />
+            </el-form-item>
+            <el-form-item
+              label="PO Number3"
+              prop="PO_Number3"
+            >
+              <el-input
+                v-model="form.PO_Number3"
+                placeholder="eg: POXXXX"
+                @change="(v) => (form.PO_Number3 = v.toUpperCase())"
+              />
+            </el-form-item>
+            <el-form-item
+              label="Tracking_Number"
+              prop="Tracking_Number"
+            >
+              <el-input v-model="form.Tracking_Number" />
+            </el-form-item>
+            <el-form-item
+              label="Sender"
+              prop="Sender"
+            >
+              <el-input v-model="form.Sender" />
+            </el-form-item>
+
+            <el-form-item
+              label="ATTN"
+              prop="ATTN"
+            >
+              <el-input v-model="form.ATTN" />
+            </el-form-item>
+
+            <el-form-item label="From_Address">
+              <el-input v-model="form.From_Address" />
+            </el-form-item>
+            <el-form-item label="To_Address">
+              <el-input v-model="form.To_Address" />
+            </el-form-item>
+            <el-form-item
+              label="Issue_Date"
+              prop="Issue_Date"
+            >
+              <el-date-picker
+                v-model="form.Issue_Date"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+              ></el-date-picker>
+            </el-form-item>
+            <el-form-item
+              label="Weight"
+              prop="Weight"
+            >
+              <el-input
+                v-model="form.Weight"
+                type="number"
+                min="0"
+              />
+            </el-form-item>
+          </div>
+
+          <div class="flex-auto">
+            <el-form-item
+              label="Currency"
+              prop="currency"
+            >
+              <el-select
+                v-model="form.currency"
+                :disabled="disableFlag"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="option in currencyList as IOptionItem[]"
+                  :key="option.value"
+                  :label="option.label"
+                  :value="option.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+
+            <el-form-item
+              label="Statement Name"
+              prop="statement_name"
+            >
+              <el-select
+                v-model="form.statement_name"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="(option, index) in statementList as IOptionItem[]"
+                  :key="index"
+                  :label="option.label"
+                  :value="option.label"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+
+            <el-form-item
+              label="Payment Type"
+              prop="payment_type"
+            >
+              <el-select
+                v-model="form.payment_type"
+                disabled
+              >
+                <el-option
+                  v-for="option in paymentOption"
+                  :key="option.value"
+                  :label="option.label"
+                  :value="option.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+
+            <el-form-item
+              label="Billable_Weight"
+              prop="Billable_Weight"
+            >
+              <el-input v-model="form.Billable_Weight" />
+            </el-form-item>
+
+            <el-form-item
+              label="Total"
+              prop="Total"
+            >
+              <el-input
+                v-model="form.Total"
+                type="number"
+                min="0"
+              />
+            </el-form-item>
+            <el-form-item
+              label="Volume"
+              prop="Volume"
+            >
+              <el-input
+                v-model="form.Volume"
+                type="number"
+                min="0"
+              />
+            </el-form-item>
+            <el-form-item
+              label="Fee_Type"
+              prop="Fee_Type"
+            >
+              <el-input v-model="form.Fee_Type" />
+            </el-form-item>
+            <el-form-item
+              label="Package_Type"
+              prop="Package_Type"
+            >
+              <el-input v-model="form.Package_Type" />
+            </el-form-item>
+            <el-form-item
+              label="Director"
+              prop="Director"
+            >
+              <el-input v-model="form.Director" />
+            </el-form-item>
+          </div>
+        </div>
+
+        <br />
+        <div class="flex end">
+          <el-button
+            type="primary"
+            @click="save(mainForm)"
+          >
+            Save
+          </el-button>
+        </div>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue'
+export default defineComponent({
+  name: 'EditIPoItem',
+})
+</script>
+
+<script lang="ts" setup>
+import { ref, watchEffect } from 'vue'
+import {
+  ElMessage,
+  ElDialog,
+  ElForm,
+  ElFormItem,
+  ElSelect,
+  ElOption,
+  ElInput,
+  ElButton,
+  ElDatePicker,
+} from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import {
+  // IPoItem,
+  IOptionItem,
+} from '../inteface'
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false,
+  },
+  disableFlag: {
+    type: Boolean,
+    default: false,
+  },
+  lockedCurrency: {
+    type: String,
+    default: '',
+  },
+  currentEditRow: {
+    type: Object,
+    default: () => {
+      return {}
+    },
+  },
+  currencyList: {
+    type: Array,
+    default: () => {
+      return []
+    },
+  },
+  statementList: {
+    type: Array,
+    default: () => {
+      return [] as string[]
+    },
+  },
+  editMode: {
+    type: Number,
+    default: 1,
+  },
+})
+
+const paymentOption = [
+  {
+    label: '货款',
+    value: '货款',
+  },
+  {
+    label: '快递款',
+    value: '快递款',
+  },
+]
+
+const dialogVisible = ref(false)
+
+const mainForm = ref<FormInstance>()
+const form: any = ref({})
+const formRule = ref<FormRules>({
+  PO_Number: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  statement_name: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  Total: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  unit_price: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  Billable_Weight: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  Tracking_Number: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+  payment_type: {
+    required: true,
+    message: '必填项',
+    trigger: 'blur',
+  },
+})
+watchEffect(() => {
+  dialogVisible.value = props.visible
+  form.value = Object.assign(
+    {
+      po_number: '',
+      // po_id: '',
+      unit_price: '',
+      quantity: '',
+      sample_fee: '',
+      setup_service_fee: '',
+      total: '',
+      currency: 'CNY',
+      statement_name: '',
+      statement_id: '',
+      description: '',
+      payment_type: '国内运费',
+    },
+    JSON.parse(JSON.stringify(props.currentEditRow)),
+  )
+
+  if (props.disableFlag) {
+    form.value.currency = props.lockedCurrency
+  }
+})
+
+const emit = defineEmits(['update:visible', 'edit', 'add'])
+
+const handleClose = function (done: any) {
+  emit('update:visible', false)
+
+  if (typeof done === 'function') {
+    done()
+  }
+}
+const save = function (formEl: FormInstance | undefined) {
+  console.log('run', formEl)
+
+  if (!formEl) return
+  formEl.validate((valid, fields) => {
+    console.log(valid)
+    if (valid) {
+      if (props.editMode === 1) {
+        emit('add', form.value)
+      } else if (props.editMode === 2) {
+        emit('edit', form.value)
+      }
+    } else {
+      console.log('check form has not pass!', fields)
+      ElMessage.error('请检查表单必填项')
+    }
+  })
+}
+</script>
+
+<style lang="scss">
+.dialog-edit-record-item {
+  input[type='number'] {
+    -moz-appearance: textfield;
+    appearance: textfield;
+    &:hover {
+      -moz-appearance: textfield;
+      appearance: textfield;
+      &::-webkit-inner-spin-button,
+      &::-webkit-outer-spin-button {
+        -webkit-appearance: none;
+        margin: 0;
+      }
+    }
+    &::-webkit-inner-spin-button,
+    &::-webkit-outer-spin-button {
+      -webkit-appearance: none;
+      margin: 0;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.form-box {
+  .flex-auto {
+    &:first-of-type {
+      padding-right: 12px;
+    }
+    & + .flex-auto {
+      padding-left: 12px;
+    }
+  }
+}
+</style>

+ 122 - 76
src/pages/payment-record/components/upload.vue

@@ -53,6 +53,19 @@
               ></el-option>
             </el-select>
           </el-form-item>
+          <el-form-item
+            v-if="form.paymentType === '国内运费'"
+            label="Weight Unit"
+          >
+            <el-select v-model="form.weightUnit">
+              <el-option
+                v-for="option in weightOption"
+                :key="option.value"
+                :label="option.label"
+                :value="option.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
 
           <el-form-item label="Upload Mode">
             <el-select
@@ -88,16 +101,19 @@
                   <upload-filled />
                 </el-icon>
               </div>
-              <br />
 
               <div class="el-upload__text">拖动文件到这或者点击选择</div>
               <br />
+              <div class="el-upload__text">
+                注意, 点确认前确保Payment Type选了正确的类型;
+              </div>
+              <br />
               <div class="el-upload">
-                单个Excel数据最好控制在100行内, 处理起来会慢
+                单个Excel数据最好控制在100行内, 处理起来会慢;
               </div>
               <br />
               <div
-                v-if="tableData.length"
+                v-if="fileContainer"
                 style="color: green"
               >
                 读取文件成功!
@@ -114,13 +130,15 @@
         >
           关闭
         </el-button>
-        <el-button
-          type="primary"
-          :loading="loading"
-          @click="next(mainForm)"
-        >
-          确认
-        </el-button>
+        <el-tooltip content="注意, 点确认前确保Payment Type选了正确的类型">
+          <el-button
+            type="primary"
+            :loading="loading"
+            @click="next(mainForm)"
+          >
+            确认
+          </el-button>
+        </el-tooltip>
       </div>
     </el-dialog>
     <!-- multiple -->
@@ -152,12 +170,13 @@ import {
   ElInput,
   ElButton,
   ElIcon,
+  ElTooltip,
 } from 'element-plus'
 
 import { UploadFilled } from '@element-plus/icons-vue'
 import * as XLSX from 'xlsx'
 import type { FormInstance, FormRules } from 'element-plus'
-import { IPoItem, IOptionItem } from '../inteface'
+import { IPoItem, IOptionItem, IPoItem2 } from '../inteface'
 // import request from '@/utils/axios'
 import utils from '@/utils/index'
 
@@ -172,6 +191,10 @@ const props = defineProps({
       return []
     },
   },
+  defaultFileType: {
+    type: String,
+    default: '',
+  },
 })
 
 const emit = defineEmits(['update:visible', 'update-table-data'])
@@ -182,7 +205,7 @@ watchEffect(() => {
   dialogVisible.value = props.visible
 })
 
-const tableData = ref([] as IPoItem[])
+const tableData = ref([] as any[])
 
 const handleClose = function (done: any) {
   emit('update:visible', false)
@@ -191,12 +214,14 @@ const handleClose = function (done: any) {
     statement_name: '',
     currency: 'CNY',
     mode: 'Replace',
-    paymentType: '货款',
+    paymentType: props.defaultFileType,
+    weightUnit: 'Kg',
   }
   const target = document.getElementById('fileInput') as HTMLInputElement
   if (target) {
     target.value = ''
   }
+  fileContainer.value = null
 
   if (typeof done === 'function') {
     done()
@@ -214,7 +239,11 @@ const form = ref({
   statement_name: '',
   currency: 'CNY',
   mode: 'Replace',
-  paymentType: '货款',
+  paymentType: props.defaultFileType,
+  weightUnit: 'Kg',
+})
+watchEffect(() => {
+  form.value.paymentType = props.defaultFileType
 })
 const uploadOption = [
   {
@@ -233,8 +262,19 @@ const paymentOption = [
     value: '货款',
   },
   {
-    label: '快递款',
-    value: '快递款',
+    label: '国内运费',
+    value: '国内运费',
+  },
+]
+
+const weightOption = [
+  {
+    label: 'Kg',
+    value: 'Kg',
+  },
+  {
+    label: 'Lb',
+    value: 'Lb',
   },
 ]
 
@@ -247,7 +287,7 @@ const processExcel = (event: any) => {
   const files = event.target.files || event.dataTransfer.files
 
   let str = ''
-  let arr: IPoItem[] = []
+  // let arr: IPoItem[] = []
   tableData.value = []
   try {
     for (let i = 0; i < files.length; i++) {
@@ -267,43 +307,11 @@ const processExcel = (event: any) => {
         str +
         `${str.length ? ', ' : ''}` +
         (files[i].name.replace(/\.xlsx?/, '') || 'unNameFile')
-      const fileReader = new FileReader()
-
-      fileReader.onload = (e: any) => {
-        const data = XLSX.read(e.target.result, { type: 'binary' })
-        // 重命名列名
-        data.Sheets[data.SheetNames[0]].A1.w = 'po_number'
-        data.Sheets[data.SheetNames[0]].B1.w = 'sku'
-        data.Sheets[data.SheetNames[0]].C1.w = 'description'
-        data.Sheets[data.SheetNames[0]].D1.w = 'unit_price'
-        data.Sheets[data.SheetNames[0]].E1.w = 'quantity'
-        data.Sheets[data.SheetNames[0]].F1.w = 'sample_fee'
-        data.Sheets[data.SheetNames[0]].G1.w = 'setup_service_fee'
-        data.Sheets[data.SheetNames[0]].H1.w = 'total'
-
-        const jsonData = XLSX.utils.sheet_to_json(
-          data.Sheets[data.SheetNames[0]],
-        ) as IPoItem[]
-        jsonData.forEach((i) => {
-          i.unit_price = utils.toFixed(Number(i.unit_price || 0), 1000)
-          i.quantity = utils.toFixed(Number(i.quantity || 0), 1000)
-          i.sample_fee = utils.toFixed(Number(i.sample_fee || 0), 1000)
-          i.setup_service_fee = utils.toFixed(
-            Number(i.setup_service_fee || 0),
-            1000,
-          )
-          i.total = utils.toFixed(Number(i.total || 0), 1000)
-          tableData.value.push(i)
-        })
-        // tableData.value = tableData.value.concat(jsonData)
-      }
-
-      fileReader.readAsBinaryString(files[i])
     }
 
     form.value.statement_name = str
   } catch (error) {
-    console.log('处理文件出错:', error)
+    console.log('读取文件出错:', error)
   }
 
   event.preventDefault()
@@ -315,42 +323,80 @@ const next = (formEl: FormInstance | undefined) => {
   formEl.validate((valid, fields) => {
     if (valid) {
       loading.value = true
-      // 创建statement 动作调整到主界面点击保存再调用.
-      // request
-      //   .post('/payment_request/createStatementData', [
-      //     {
-      //       Name: form.value.statement_name,
-      //     },
-      //   ])
-      //   .then((response) => {
-      // if (response.data.code !== 1) return
-      // const res = response.data.result
 
-      let result = {
-        mode: form.value.mode,
-        data: tableData.value.map((i) => {
-          return {
-            ...i,
-            po_number: i.po_number.toUpperCase(),
-            payment_type: form.value.paymentType,
-            statement_name: form.value.statement_name,
-            currency: form.value.currency,
-            statement_id: form.value.statement_name,
+      try {
+        const fileReader = new FileReader()
+
+        fileReader.onload = (e: any) => {
+          const data = XLSX.read(e.target.result, { type: 'binary' })
+          // 重命名列名
+          if (form.value.paymentType === '货款') {
+            data.Sheets[data.SheetNames[0]].A1.w = 'po_number'
+            data.Sheets[data.SheetNames[0]].B1.w = 'sku'
+            data.Sheets[data.SheetNames[0]].C1.w = 'description'
+            data.Sheets[data.SheetNames[0]].D1.w = 'unit_price'
+            data.Sheets[data.SheetNames[0]].E1.w = 'quantity'
+            data.Sheets[data.SheetNames[0]].F1.w = 'sample_fee'
+            data.Sheets[data.SheetNames[0]].G1.w = 'setup_service_fee'
+            data.Sheets[data.SheetNames[0]].H1.w = 'total'
+
+            const jsonData = XLSX.utils.sheet_to_json(
+              data.Sheets[data.SheetNames[0]],
+            ) as IPoItem[]
+            jsonData.forEach((i) => {
+              i.unit_price = utils.toFixed(Number(i.unit_price || 0), 1000)
+              i.quantity = utils.toFixed(Number(i.quantity || 0), 1000)
+              i.sample_fee = utils.toFixed(Number(i.sample_fee || 0), 1000)
+              i.setup_service_fee = utils.toFixed(
+                Number(i.setup_service_fee || 0),
+                1000,
+              )
+              i.total = utils.toFixed(Number(i.total || 0), 1000)
+              tableData.value.push({
+                ...i,
+                po_number: i.po_number.toUpperCase(),
+                payment_type: form.value.paymentType,
+                statement_name: form.value.statement_name,
+                currency: form.value.currency,
+              })
+            })
+          } else if (form.value.paymentType === '国内运费') {
+            // todo
+            const jsonData = XLSX.utils.sheet_to_json(
+              data.Sheets[data.SheetNames[0]],
+            ) as IPoItem2[]
+            jsonData.forEach((i) => {
+              tableData.value.push({
+                ...i,
+                Weight_Unit: form.value.weightUnit,
+                Currency: form.value.currency,
+                payment_type: form.value.paymentType,
+                statement_name: form.value.statement_name,
+              })
+            })
           }
-        }),
+
+          let result = {
+            mode: form.value.mode,
+            data: tableData.value,
+          }
+          emit('update-table-data', result, fileContainer.value)
+          handleClose(false)
+        }
+        fileReader.readAsBinaryString(fileContainer.value)
+      } catch (e) {
+        console.log(e, '处理文件出错')
       }
-      emit('update-table-data', result, fileContainer.value)
-      handleClose(false)
-      // })
-      // .finally(() => {
+
       loading.value = false
-      // })
     } else {
       console.log('check form has not pass!', fields)
       ElMessage.error('请检查表单必填项')
     }
   })
 }
+
+form.value.paymentType = props.defaultFileType
 </script>
 
 <style lang="scss" scoped>

Різницю між файлами не показано, бо вона завелика
+ 798 - 71
src/pages/payment-record/index.vue


+ 22 - 1
src/pages/payment-record/inteface.ts

@@ -14,7 +14,28 @@ export interface IPoItem {
   payment_type?: string
   sales_person?: string
 }
-
+export interface IPoItem2 {
+  PO_Number: string
+  PO_Number2: string
+  PO_Number3: string
+  Tracking_Number: string
+  Sender: string
+  ATTN: string
+  From_Address: string
+  To_Address: string
+  Issue_Date: string
+  Weight: number
+  Volume: number
+  Billable_Weight: number
+  Fee_Type: string
+  Package_Type: string
+  Director: string
+  Total: number
+  Currency: string
+  Weight_Unit: string
+  statement_name: string
+  payment_type?: string
+}
 export interface IOptionItem {
   label: string
   value: string

Деякі файли не було показано, через те що забагато файлів було змінено