@@ -344,7 +374,7 @@
-
+
@@ -359,16 +389,18 @@ import { QuotationApi, QuotationVO } from '@/api/crm/quotation'
import { defaultProps, handleTree } from '@/utils/tree'
import { BillTemplateApi, BillTemplateVO } from '@/api/crm/billtemplate'
import QuotationProductForm from './components/QuotationProductForm.vue'
+import * as ContractApi from '@/api/crm/contract'
import * as CustomerApi from '@/api/crm/customer'
import * as UserApi from '@/api/system/user'
import * as DeptApi from '@/api/system/dept'
import * as BusinessApi from '@/api/crm/business'
-import {BillTemplateApi } from '@/api/crm/billtemplate'
-import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils'
+import { propTypes } from '@/utils/propTypes'
/** CRM 方案报价 表单 */
defineOptions({ name: 'QuotationForm' })
-
+const props = defineProps({
+ id: propTypes.number.def(undefined),
+})
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const customerList = ref([]) // 客户列表的数据
@@ -377,6 +409,8 @@ const templateOptions = ref([])
const businessList = ref([])
const deptTree = ref() // 部门树形结构
const deptList = ref() // 部门
+const orgList = ref([])
+const handleType = ref('')
const invoiceTemplateList = ref([])
const { proxy }: any = getCurrentInstance();
@@ -430,13 +464,29 @@ const formData = ref({
bBankAccount: undefined, // 银行账号
bLegalRepresentative: undefined, // 法人代表
bBusinessLicenseNumber: undefined, // 营业执照号
- bBusinessLicense: undefined // 营业执照
+ bBusinessLicense: undefined, // 营业执照
+ creditAmount: undefined,
+ creditLimitNum: undefined,
+ quotationTimes:undefined,
})
const formRules = reactive({
no: [{ required: true, message: '报价单编号不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '客户id不能为空', trigger: 'change' }],
businessId: [{ required: true, message: '商机编号不能为空', trigger: 'change' }],
- invoiceTemplateId: [{ required: true, message: '票据模板Id不能为空', trigger: 'change' }]
+ invoiceTemplateId: [{ required: true, message: '票据模板Id不能为空', trigger: 'change' }],
+ actualCapital: [{ required: true, message: '实缴资金不能为空', trigger: 'blur' }],
+ socialEmployeeNum: [{ required: true, message: '参保人数不能为空', trigger: 'blur' }],
+ defendantRecord: [{ required: true, message: '被告记录不能为空', trigger: 'blur' }],
+ abnormalService: [{ required: true, message: '经营异常不能为空', trigger: 'blur' }],
+ equityPledge: [{ required: true, message: '股权出质不能为空', trigger: 'blur' }],
+ dishonestyRecord: [{ required: true, message: '失信记录不能为空', trigger: 'blur' }],
+ financeRecord: [{ required: true, message: '融资记录不能为空', trigger: 'blur' }],
+ judgmentRecord: [{ required: true, message: '被执行记录不能为空', trigger: 'blur' }],
+ paymentTerm: [{ required: true, message: '账期不能为空', trigger: 'change' }],
+ partnerCompanyId: [{ required: true, message: '合作主体不能为空', trigger: 'change' }],
+ creditMethod: [{ required: true, message: '授信方式不能为空', trigger: 'change' }],
+ creditCalcCycle: [{ required: true, message: '授信计算周期不能为空', trigger: 'change' }],
+ quotationTimes: [{ required: true, message: '第几次报价不能为空', trigger: 'change' }],
})
const formRef = ref() // 表单 Ref
@@ -446,6 +496,8 @@ const quotationProductFormRef = ref()
const onBusinessChange = async (businessId: string) => {
if (!businessId) return
+
+ handleType.value = 1
try {
formLoading.value = true;
const res = await BusinessApi.getBusiness(businessId);
@@ -473,6 +525,10 @@ const onCustomerChange = async (customerId: string) => {
try {
formLoading.value = true;
const customerRes = await CustomerApi.getCustomer(customerId);
+ formData.value.actualCapital = customerRes.actualCapital
+ formData.value.socialEmployeeNum = customerRes.socialEmployeeNum
+ formData.value.startDate = customerRes.startDate
+ formData.value.actualCapital = customerRes.actualCapital
formData.value.cooperationType = customerRes.cooperationType;
formData.value.companyType = customerRes.companyType;
formData.value.listingStatus = customerRes.listingStatus;
@@ -488,6 +544,7 @@ const onCustomerChange = async (customerId: string) => {
formData.value.dishonestRecord = customerRes.dishonestRecord;
formData.value.financingRecord = customerRes.financingRecord;
formData.value.enforcementRecord = customerRes.enforcementRecord;
+ formData.value.creditAmount = customerRes.creditAmount || 0;
} catch (err) {
console.error('获取客户详情失败:', err);
} finally {
@@ -499,18 +556,22 @@ const onPartnerChange = async (id: string) => {
if (!id) return
try {
formLoading.value = true;
- const res = await DeptApi.getDept(id);
- formData.value.bBankName = res.bankName;
- formData.value.bBankAccount = res.bankAccount;
- formData.value.bLegalRepresentative = res.legalRepresentative;
- formData.value.bBusinessLicenseNumber = res.businessLicenseNumber;
- formData.value.bBusinessLicense = res.businessLicense;
+ const res = await ContractApi.getOrgInfo(id);
+ formData.value.bankName = res.bankName;
+ formData.value.bankAccount = res.bankAccount;
+ formData.value.legalRepresentative = res.legalRepresentative;
+ formData.value.businessLicenseNumber = res.businessLicenseNumber;
+ formData.value.businessLicense = res.businessLicense;
+ // formData.value.partnerCompanyId = res.partnerCompanyId;
} catch (err) {
} finally {
formLoading.value = false;
}
}
+const changeNum = (val) => {
+ formData.value.creditLimit = (Number(val) + (formData.value.creditAmount || 0)).toFixed(2)
+}
/** 打开弹窗 */
const open = async (type: string) => {
formType.value = type
@@ -565,6 +626,11 @@ const submitForm = async () => {
}
+const changeTemplate = async() => {
+ handleType.value = 1
+ console.log('%csrc/views/crm/quotation/QuotationForm.vue:631 handleType.value,222', 'color: #007acc;', handleType.value,222);
+}
+
const goBack = ()=> {
proxy.$router.go(-1)
}
@@ -602,13 +668,12 @@ const resetForm = () => {
const route = useRoute();
onMounted(async () => {
- console.log('%csrc/views/crm/quotation/QuotationForm.vue:596 route', 'color: #007acc;', route);
- formType.value = route.query.id;
+ formType.value = props.id || route.query.id;
if (formType.value) open(formType.value)
// 获得客户列表
- customerList.value = await CustomerApi.getCustomerSimpleList()
+ customerList.value = await CustomerApi.getSelfCustomerSimpleList()
// 获得用户列表
userOptions.value = await UserApi.getSimpleUserList()
//票据
@@ -617,8 +682,13 @@ onMounted(async () => {
pageSize: 1000,
})
templateOptions.value = data.list
- businessList.value = await BusinessApi.getSimpleBusinessList()
+ businessList.value = await BusinessApi.getSelfSimpleBusinessList()
// 获得部门树
deptTree.value = handleTree(await DeptApi.getSimpleDeptList())
+ const org = await ContractApi.getOrg({
+ pageNo: 1,
+ pageSize: 1000
+ })
+ orgList.value = org.list
});
-
\ No newline at end of file
+
diff --git a/src/views/crm/quotation/components/QuotationProductDetail.vue b/src/views/crm/quotation/components/QuotationProductDetail.vue
index a5e105cfe..b837d1c9c 100644
--- a/src/views/crm/quotation/components/QuotationProductDetail.vue
+++ b/src/views/crm/quotation/components/QuotationProductDetail.vue
@@ -62,28 +62,57 @@
-
+
+
+
-
+
-
+
+
+
+
-
-
+
+
+
+
-
+
-
-
+
+
+
+
@@ -103,7 +132,9 @@ import * as BusinessApi from '@/api/crm/business'
const props = defineProps<{
quotationId: undefined, // 报价编号(主表的关联字段)
businessId: undefined,
- billTemplateId: undefined
+ billTemplateId: undefined,
+ products: undefined
+
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
@@ -120,57 +151,21 @@ const formRules = reactive({
const formRef = ref() // 表单 Ref
/** 监听主表的关联字段的变化,加载对应的子表数据 */
-watch(
- () => props.businessId,
- async (val) => {
- // 1. 重置表单
- formData.value = []
- // 2. val 非空,则加载数据
- if (!val) {
- return;
- }
- try {
- formLoading.value = true
- // if(val.quotationId) {
- // formData.value = await QuotationApi.getQuotationProductListByQuotationId(val.quotationId)
- // } else if(val.businessId) {
- const business = await BusinessApi.getBusiness(val);
- formData.value = business.products
- // }
- } finally {
- formLoading.value = false
- }
- },
- { immediate: true }
-)
watch(
- () => props.billTemplateId,
- async (val) => {
- // 1. 重置表单
- formData.value = []
- // 2. val 非空,则加载数据
- if (!val) {
+ () => props.products,
+ (val) => {
+ if (!val || val.length === 0) {
return;
}
- try {
- formLoading.value = true
- // if(val.quotationId) {
- // formData.value = await QuotationApi.getQuotationProductListByQuotationId(val.quotationId)
- // } else if(val.businessId) {
- const business = await BillTemplateApi.getTemplateProduct({
- businessId: props.businessId,
- billTemplateId: val,
- });
- console.log('%csrc/views/crm/quotation/components/QuotationProductForm.vue:167 business.data', 'color: #007acc;', business.data);
- formData.value = business
- // }
- } finally {
- formLoading.value = false
- }
+ nextTick(() => {
+ formData.value = val
+ console.log('%csrc/views/crm/quotation/components/QuotationProductDetail.vue:134 val', 'color: #007acc;', val);
+ })
},
{ immediate: true }
-)
+
+);
/** 新增按钮操作 */
const handleAdd = () => {
diff --git a/src/views/crm/quotation/components/QuotationProductForm.vue b/src/views/crm/quotation/components/QuotationProductForm.vue
index 9307087ba..b31728904 100644
--- a/src/views/crm/quotation/components/QuotationProductForm.vue
+++ b/src/views/crm/quotation/components/QuotationProductForm.vue
@@ -8,12 +8,13 @@
:inline-message="true"
>
-
-
+
+
+
@@ -31,10 +32,10 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -94,10 +95,10 @@
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
@@ -169,14 +172,21 @@ const formRules = reactive({
productUnit: [{ required: true, message: '产品单位不能为空', trigger: 'blur' }],
onlinePrice: [{ required: true, message: '线上价格不能为空', trigger: 'blur' }],
offlinePrice: [{ required: true, message: '线下价格不能为空', trigger: 'blur' }],
- totalPrice: [{ required: true, message: '总计价格不能为空', trigger: 'blur' }]
+ totalPrice: [{ required: true, message: '总计价格不能为空', trigger: 'blur' }],
+ productInvoiceItem: [{ required: true, message: '产品开具项目不能为空', trigger: 'blur' }],
+ serviceInvoice: [{ required: true, message: '服务费票据不能为空', trigger: 'blur' }],
+ serviceInvoiceItem: [{ required: true, message: '服务开具项目不能为空', trigger: 'blur' }],
+ productInvoice: [{ required: true, message: '产品票据不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
+const emit = defineEmits(['update:handleType'])
/** 监听主表的关联字段的变化,加载对应的子表数据 */
watch(
() => props.businessId,
async (val) => {
+
+ if(!props.handleType) return
// 1. 重置表单
formData.value = []
// 2. val 非空,则加载数据
@@ -190,6 +200,8 @@ watch(
// } else if(val.businessId) {
const business = await BusinessApi.getBusiness(val);
formData.value = business.products
+ // console.log('%csrc/views/crm/quotation/components/QuotationProductForm.vue:214 1111', 'color: #007acc;', 2222);
+ emit('update:handleType', 0)
// }
} finally {
formLoading.value = false
@@ -201,9 +213,11 @@ watch(
watch(
() => props.billTemplateId,
async (val) => {
- // 1. 重置表单
- formData.value = []
// 2. val 非空,则加载数据
+ if(!props.handleType) {
+ return
+ }
+
if (!val) {
return;
}
@@ -216,8 +230,25 @@ watch(
businessId: props.businessId,
billTemplateId: val,
});
- console.log('%csrc/views/crm/quotation/components/QuotationProductForm.vue:167 business.data', 'color: #007acc;', business.data);
- formData.value = business
+ for(let i = 0; i < business.length; i++) {
+ let data = business[i]
+ if(!data.productId) {
+ data.productInvoice = ''
+ data.productInvoiceItem = ''
+ data.serviceInvoice = ''
+ data.serviceInvoiceItem = ''
+ }
+ let foundItem = formData.value.find(item => item.productId == data.productId);
+ if (foundItem) {
+ foundItem.productInvoice = data.productInvoice
+ foundItem.productInvoiceItem = data.productInvoiceItems
+ foundItem.serviceInvoice = data.serviceFeeInvoice
+ foundItem.serviceInvoiceItem = data.serviceFeeInvoiceItems
+ }
+ }
+ emit('update:handleType', 0)
+
+ // formData.value = business
// }
} finally {
formLoading.value = false
@@ -225,7 +256,39 @@ watch(
},
{ immediate: true }
)
+// 监听合同产品变化,计算合同产品总价
+watch(
+ () => formData.value,
+ (val) => {
+ if (!val || val.length === 0) {
+ return;
+ }
+ // 循环处理
+ val.forEach((item) => {
+ if (item.offlinePrice != null && item.onlinePrice != null) {
+ item.totalPrice = Number((Number(item.offlinePrice) + Number(item.onlinePrice)).toFixed(2));
+ } else {
+ item.totalPrice = 0;
+ }
+ });
+ },
+ { deep: true }
+);
+watch(
+ () => props.products,
+ async (val) => {
+ if (!val || val.length === 0) {
+ return;
+ }
+ await nextTick(() => {
+ formData.value = val
+ })
+ },
+ { immediate: true },
+
+
+);
/** 新增按钮操作 */
const handleAdd = () => {
const row = {
@@ -238,8 +301,8 @@ const handleAdd = () => {
offlinePrice: undefined,
totalPrice: undefined,
productInvoice: undefined,
- productInvoiceItems: undefined,
- serviceFeeInvoice: undefined,
+ productInvoiceItem: undefined,
+ serviceInvoice: undefined,
serviceFeeInvoiceItems: undefined
}
row.quotationId = props.quotationId
@@ -262,4 +325,4 @@ const getData = () => {
}
defineExpose({ validate, getData })
-
\ No newline at end of file
+
diff --git a/src/views/crm/quotation/index.vue b/src/views/crm/quotation/index.vue
index 35cd0b0ab..83cb13d90 100644
--- a/src/views/crm/quotation/index.vue
+++ b/src/views/crm/quotation/index.vue
@@ -84,17 +84,28 @@
+
+
+
+
+
-
-
+
-
+ {{ scope.row.no }}
+
+
+
+
+
+
{{ scope.row.customerName }}
-
+
@@ -139,7 +150,8 @@
/>
-
+
编辑
- handleCommand(command, scope.row)"
+ v-hasPermi="[
+ 'crm:quotation:delete',
+ 'crm:customer-suggestion:query',
+ 'system:permission:assign-user-role'
+ ]"
>
- 删除
-
+ 更多
+
+
+
+ 提交审核
+
+
+ 进度
+
+
+ 删除
+
+
+
+
+
+