admin-vue3/src/views/crm/business/BusinessForm.vue

427 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<ContentWrap class="mt-10px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
v-loading="formLoading"
>
<el-row>
<el-col :span="8">
<el-form-item label="商机名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入商机名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="负责人" prop="ownerUserId">
<el-select
v-model="formData.ownerUserId"
:disabled="formType"
placeholder="请选择负责人"
class="w-1/1"
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="需求提交人" prop="requestorUserId">
<el-select
v-model="formData.requestorUserId"
:disabled="formType"
placeholder="请选择需求提交人"
class="w-1/1"
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户名称" prop="customerId">
<el-select
:disabled="formData.customerDefault"
v-model="formData.customerId"
placeholder="请选择客户"
class="w-1/1"
>
<el-option
v-for="item in customerList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="归属部门" prop="deptId">
<el-tree-select
v-model="formData.deptId"
:data="deptTree"
:props="defaultProps"
filterable
check-strictly
node-key="id"
placeholder="请选择归属部门"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="商机状态组" prop="statusTypeId">
<el-select
v-model="formData.statusTypeId"
placeholder="请选择商机状态组"
clearable
class="w-1/1"
:disabled="formType"
>
<el-option
v-for="item in statusTypeList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计成交日期" prop="dealTime">
<el-date-picker
v-model="formData.dealTime"
type="date"
value-format="x"
placeholder="选择预计成交日期"
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="销售阶段" prop="saleStage">
<el-select v-model="formData.saleStage" placeholder="请选择销售阶段">
<el-option
v-for="dict in getIntDictOptions('sale_stage')"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="账期" prop="paymentTerm">
<el-select v-model="formData.paymentTerm" @change="changePayment" placeholder="请选择账期">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.PAYMENT_TERM)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="授信方式" prop="creditMethod">
<el-select v-model="formData.creditMethod" placeholder="请选择授信方式">
<el-option
v-for="dict in getIntDictOptions('credit_method')"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="授信计算周期" prop="creditCalcCycle">
<!-- <el-select v-model="formData.creditCalcCycle" placeholder="请选择授信计算周期">
<el-option
v-for="dict in getIntDictOptions('credit_calc_cycle')"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select> -->
<el-input v-model="formData.creditCalcCycle" disabled placeholder="授信计算周期" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="授信额度" prop="creditLimit">
<el-input v-model="formData.creditLimit" disabled placeholder="授信额度" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="技术需求支持" prop="techSupport">
<el-radio-group v-model="formData.techSupport">
<el-radio
v-for="dict in getStrDictOptions(DICT_TYPE.TECH_SUPPORT)"
:key="dict.value"
:value="dict.value == 2 ? true : false"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
<!-- 子表的表单 -->
<ContentWrap>
<el-tabs v-model="subTabsName" class="-mt-15px -mb-10px">
<el-tab-pane label="产品清单" name="product">
<BusinessProductForm
ref="productFormRef"
:products="formData.products"
:disabled="disabled"
@success="setList"
/>
</el-tab-pane>
</el-tabs>
</ContentWrap>
<el-row>
<el-col :span="8">
<el-form-item label="线上总金额" prop="onlinePrice">
<el-input
disabled
v-model="formData.onlinePrice"
:formatter="erpPriceInputFormatter"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="线下总金额" prop="offlinePrice">
<el-input
disabled
v-model="formData.offlinePrice"
:formatter="erpPriceInputFormatter"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总金额" prop="totalPrice">
<el-input
disabled
v-model="formData.totalPrice"
:formatter="erpPriceInputFormatter"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div style="text-align: right">
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="goBack"> </el-button>
</div>
</ContentWrap>
</template>
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import { getIntDictOptions, getStrDictOptions, DICT_TYPE, getBoolDictOptions } from '@/utils/dict';
import * as BusinessApi from '@/api/crm/business';
import * as BusinessStatusApi from '@/api/crm/business/status';
import * as CustomerApi from '@/api/crm/customer';
import * as UserApi from '@/api/system/user';
import * as DeptApi from '@/api/system/dept';
import { useUserStore } from '@/store/modules/user';
import { defaultProps, handleTree } from '@/utils/tree';
import BusinessProductForm from './components/BusinessProductForm.vue';
import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils';
import { number } from 'vue-types';
const { proxy }: any = getCurrentInstance();
const { t } = useI18n();
const message = useMessage();
const dialogVisible = ref(false);
const dialogTitle = ref('');
const formLoading = ref(false);
const formType = ref('');
const formData = ref({
id: undefined,
name: undefined,
customerId: undefined,
followUpStatus: undefined,
contactLastTime: undefined,
contactNextTime: undefined,
ownerUserId: undefined,
deptId: undefined,
requestorUserId: undefined,
statusTypeId: undefined,
statusId: undefined,
endStatus: undefined,
dealTime: undefined,
onlinePrice: 0,
offlinePrice: 0,
totalProductPrice: 0,
totalPrice: 0,
saleStage: undefined,
paymentTerm: undefined,
creditMethod: undefined,
creditCalcCycle: undefined,
creditLimit: undefined,
techSupport: undefined,
products: []
});
const formRules = reactive({
name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }]
});
const formRef = ref();
const userOptions = ref<UserApi.UserVO[]>([]);
const statusTypeList = ref([]);
const customerList = ref([]);
const deptTree = ref();
const subTabsName = ref('product');
const productFormRef = ref();
watch(
() => formData.value.products,
(newProducts) => {
if (!Array.isArray(newProducts)) {
console.warn('formData.value.products is not an array');
return;
}
let totalOnlinePrice = 0;
let totalOfflinePrice = 0;
for (const product of newProducts) {
if (typeof product.onlinePrice === 'number') {
totalOnlinePrice += product.onlinePrice;
}
if (typeof product.offlinePrice === 'number') {
totalOfflinePrice += product.offlinePrice;
}
}
formData.value.onlinePrice = totalOnlinePrice.toFixed(2)
formData.value.offlinePrice = totalOfflinePrice.toFixed(2)
let all = totalOnlinePrice + totalOfflinePrice
formData.value.totalPrice = all.toFixed(2)
},
{ deep: true }
);
watch(
() => formData.value.totalPrice,
(newProducts) => {
console.log('%csrc/views/crm/business/BusinessForm.vue:326 111', 'color: #007acc;', 111);
formData.value.creditLimit = parseInt(newProducts / 365 * formData.value.creditCalcCycle)
},
{ deep: true }
);
const open = async (id?: number, customerId?: number) => {
if (id) {
formLoading.value = true;
try {
const data = await BusinessApi.getBusiness(id);
formData.value = {
...data,
products: data.products || []
};
} finally {
formLoading.value = false;
}
} else {
if (customerId) {
formData.value.customerId = customerId;
formData.value.customerDefault = true;
}
}
if (!formType.value) {
formData.value.ownerUserId = useUserStore().getUser.id;
}
};
const setList = (newProducts) => {
formData.value.products = newProducts;
};
// 改版账期
const changePayment = (val) => {
const currentDate = new Date(); // 获取当前日期
const currentMonth = currentDate.getMonth() + 1; // 获取当前月份注意月份是从0开始的所以需要加1
const daysInMonth = new Date(currentDate.getFullYear(), currentMonth, 0).getDate(); // 获取指定月份的天数
formData.value.creditCalcCycle = (val > 2 ? parseInt(daysInMonth + Number(val)) : 0)
formData.value.creditLimit = parseInt(formData.value.totalPrice / 365 * formData.value.creditCalcCycle)
}
const { push } = useRouter()
const submitForm = async () => {
if (!productFormRef.value) return;
const valid = await productFormRef.value.validate();
if (!valid) return;
formLoading.value = true;
try {
const data = formData.value as unknown as BusinessApi.BusinessVO;
if (!formType.value) {
await BusinessApi.createBusiness(data);
message.success(t('common.createSuccess'));
} else {
await BusinessApi.updateBusiness(data);
message.success(t('common.updateSuccess'));
}
dialogVisible.value = false;
goBack()
} finally {
formLoading.value = false;
}
};
const goBack = ()=> {
proxy.$router.go(-1)
}
const resetForm = () => {
formData.value = {
id: undefined,
name: undefined,
customerId: undefined,
ownerUserId: undefined,
statusTypeId: undefined,
dealTime: undefined,
totalPrice: 0,
products: [],
contactId: undefined,
customerDefault: false
};
formRef.value?.resetFields();
};
const route = useRoute();
onMounted(async () => {
console.log('%csrc/views/crm/business/BusinessForm.vue:406 getStrDictOptions(DICT_TYPE.PAYMENT_TERM)', 'color: #007acc;', getStrDictOptions(DICT_TYPE.PAYMENT_TERM));
const customerId = route.query.customerId;
formType.value = route.query.id;
if (formType.value) open(formType.value, customerId)
customerList.value = await CustomerApi.getCustomerSimpleList();
statusTypeList.value = await BusinessStatusApi.getBusinessStatusTypeSimpleList();
userOptions.value = await UserApi.getSimpleUserList();
deptTree.value = handleTree(await DeptApi.getSimpleDeptList());
});
</script>