2024-03-20 15:57:03 +08:00

368 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80%" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="auto" :rules="formRules" inline>
<el-row>
<el-col :span="8">
<el-form-item label="客户名称" prop="custom_id"
:rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="formData.custom_name" clearable placeholder="点击选择客户" readonly
@click="showDialog = true" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系人" prop="custom_master_name">
<el-input v-model="formData.custom_master_name" disabled clearable placeholder="请输入联系人" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系电话" prop="custom_master_phone"
:rules="[{ validator: isMobileNumber, trigger: 'blur' }]">
<el-input v-model="formData.custom_master_phone" disabled clearable placeholder="请输入联系电话"
:regex="/^ 1[3 - 9]\d{ 9}$ /" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="报价日期" prop="quotation_date">
<el-date-picker v-model="formData.quotation_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="选择报价日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="制单人" prop="create_user">
<el-input v-model="formData.create_user" clearable placeholder="请输入制单人" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发票类型" prop="invoice_type">
<el-radio-group v-model="formData.invoice_type" placeholder="请选择发票类型">
<el-radio v-for="( item, index ) in dictData.invoice_type " :key="index"
:label="parseInt(item.value)">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="含税金额" prop="amount_including_tax"
:rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="formData.amount_including_tax" disabled clearable
placeholder="请输入含税金额" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="含税金额大写" prop="amount_including_tax"
:rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="amount_including_daxie" disabled clearable placeholder="请输入含税金额大写" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="运费" prop="freight"
:rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.freight" clearable placeholder="请输入运费" type="number"
@change="calcAmount()" />
</el-form-item></el-col><el-col :span="8">
<el-form-item label="其他费用" prop="other_fee"
:rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.other_fee" clearable type="number" @change="calcAmount()"
placeholder="请输入其他费用" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="合计金额" prop="total_amount">
<el-input v-model="formData.total_amount" disabled clearable placeholder="请输入合计金额" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="合计金额大写" prop="total_amount">
<el-input v-model="total_amount_daxie" clearable disabled placeholder="请输入合计金额大写" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="客户需求" prop="customer_require"
:rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.customer_require" clearable placeholder="请输入客户需求" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="附件">
<uploadAnnex :formData="formData" />
</el-form-item>
</el-col>
</el-row>
<div style=" display: flex;justify-content: flex-end;margin-bottom: 30px;"> <el-button
@click="showDialog1 = true">选择产品</el-button></div>
<div style="margin-bottom: 30px;">
<el-table :data="formData.quotation_detail">
<el-table-column label="序号">
<template #default="{ row }">
<el-button @click="handleDelete(row)" size="small">-</el-button>
</template>
</el-table-column>
<el-table-column label="产品名称">
<template #default="{ row }">
<el-input v-model="row.product_name" disabled placeholder="系统自动填写" />
</template>
</el-table-column>
<el-table-column label="产品编码">
<template #default="{ row }"> <el-input v-model="row.product_code" disabled
placeholder="系统自动填写" />
</template></el-table-column>
<el-table-column label="规格型号">
<template #default="{ row }"> <el-input v-model="row.product_specs" disabled
placeholder="系统自动填写" />
</template></el-table-column>
<el-table-column label="品牌">
<template #default="{ row }">
<el-input v-model="row.product_brand" disabled placeholder="系统自动填写" />
</template>
</el-table-column>
<el-table-column label="参数说明">
<template #default="{ row }"> <el-input v-model="row.product_parameter_description"
disabled />
</template></el-table-column>
<el-table-column label="单位">
<template #default="{ row, index }"> <el-input v-model="row.product_unit" disabled />
</template></el-table-column>
<el-table-column label="数量">
<template #default="{ row, $index }">
<el-input v-model="row.num" @change="calcAmount($index)" />
</template>
</el-table-column>
<el-table-column label="税率(%)" prop="tax_rate">
<template #default="scope">
<el-select class="flex-1" v-model="scope.row.tax_rate" clearable placeholder="请选择税率"
@change="getTaxText(scope.$index)">
<el-option v-for="(item, index) in dictData.tax_rate" :key="index"
:label="item.name" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column label="含税单价">
<template #default="{ row }">
<el-input v-model="row.tax_inclusive_price" disabled />
</template>
</el-table-column>
<el-table-column label="含税金额">
<template #default="{ row }">
<el-input v-model="row.tax_inclusive_amount" disabled />
</template>
</el-table-column>
<el-table-column label="不含税金额">
<template #default="{ row }">
<el-input v-model="row.tax_exclusive_amount" disabled />
</template>
</el-table-column>
<el-table-column label="备注" prop="remark">
<template #default="{ row }">
<el-input v-model="row.remark" />
</template>
</el-table-column>
</el-table>
</div>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择客户" width="70%">
<customDialog @customEvent="customEvent"></customDialog>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择产品" width="70%">
<customDialog1 @customEvent="customEvent1"></customDialog1>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="quotationEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiQuotationAdd, apiQuotationEdit, apiQuotationDetail } from '@/api/quotation'
import { apiQuotationDetailLists, apiQuotationDetailDelete } from '@/api/quotation_detail'
import { convertToChinese } from '@/utils/util'
import customDialog1 from '@/components/product/index.vue'
import type { PropType } from 'vue'
import { computed, watch } from "vue"
const props = defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const showDialog = ref(false)
const showDialog1 = ref(false)
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑报价单' : '新增报价单'
})
// 表单数据
const formData = reactive({
id: '',
approve_id: 1,
custom_id: '',
custom_name: "",
quotation_date: '',
custom_master_name: '',
custom_master_phone: '',
create_user: '',
invoice_type: '',
amount_including_tax: 0,
freight: '',
other_fee: '',
total_amount: '',
customer_require: '',
remark: '',
annex: [],
quotation_detail: [],
})
const customEvent = (e: any) => {
formData.custom_id = e.id;
formData.custom_name = e.name;
formData.custom_master_name = e.master_name
formData.custom_master_phone = e.master_phone
showDialog.value = false;
};
const customEvent1 = (e: any) => {
formData.quotation_detail.push({
product_id: e.id,
product_name: e.name,
product_code: e.code,
product_unit: e.unit,
product_specs: e.specs,
product_brand: e.brand,
product_parameter_description: e.parameter_description,
tax_rate: '',
tax_rate_text: "",
remark: '',
tax_inclusive_price: e.sales_price
})
showDialog1.value = false;
};
// 表单验证
const formRules = reactive<any>({
})
const handleDelete = async (row: any) => {
if (row.id) await apiQuotationDetailDelete({ id: row.id });
// 删除 row
const index = formData.quotation_detail.indexOf(row);
formData.quotation_detail.splice(index, 1);
calcAmount()
};
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
let res = await apiQuotationDetailLists({ quotation_id: data.id })
formData.quotation_detail = res.lists
}
const isMobileNumber = (rule: any, value: string | number | any[], callback: (arg0: Error | undefined) => void) => {
if (value && !/^1[3|4|5|7|8][0-9]{9}$/.test(value)) {
callback(new Error('请输入正确的手机号码'));
} else {
callback()
}
};
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiQuotationEdit(data)
: await apiQuotationAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
// 计算价格
// 获取列表每行的税率text
const getTaxText = (index: number) => {
let table = formData.quotation_detail
let taxRate = props.dictData.tax_rate[props.dictData.tax_rate.findIndex(item => item.value == table[index]?.tax_rate)].name
table[index].tax_rate_text = (1 - taxRate / 100)
calcAmount(index)
}
// 计算价格
const calcAmount = () => {
let table = formData.quotation_detail
// 通过含税单价tax_inclusive_price和税率tax_rate_text计算列表每行的含税金额tax_inclusive_amount不含税金额tax_exclusive_amount,遍历列表累加含税金额得出总的含税金额
formData.amount_including_tax = 0
table.forEach(item => {
item.tax_inclusive_amount = (Number((item)?.num || 0) * Number(item.tax_inclusive_price)).toFixed(2)
item.tax_exclusive_amount = (Number(item.tax_inclusive_amount || 0) * Number(item.tax_rate_text)).toFixed(2)
formData.amount_including_tax += Number(item.tax_inclusive_amount)
})
// 合计金额=总含税金额+运费+其他费用
formData.total_amount = (+formData.amount_including_tax || 0) + (+formData.freight || 0) + (+formData.other_fee || 0)
}
// 金额大写
const amount_including_daxie = computed(() => {
return convertToChinese(formData.amount_including_tax) || ''
})
const total_amount_daxie = computed(() => {
return convertToChinese(formData.total_amount) || ''
})
defineExpose({
open,
setFormData,
})
</script>