main
parent
fa2ee0cd6a
commit
7c0581f15f
@ -0,0 +1,553 @@ |
||||
<template> |
||||
<div style="height: 100vh; overflow-y: auto"> |
||||
<div> |
||||
<div> |
||||
<Descriptions |
||||
:title="`线索信息-${info.name}`" |
||||
:data="info" |
||||
:schema="showSchema" |
||||
:columns="2" |
||||
labelWidth="130px" |
||||
:defaultShow="false" |
||||
/> |
||||
<el-form |
||||
:model="form" |
||||
ref="formRef" |
||||
:rules="rules" |
||||
label-width="85px" |
||||
class="mt-20px pl-10px pr-10px" |
||||
> |
||||
<el-row> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="学员姓名" prop="name"> |
||||
<el-input v-model="form.name" placeholder="请输入学员姓名" /> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="联系方式" prop="phone"> |
||||
<el-input v-model="form.phone" placeholder="请输入联系方式" maxlength="11" /> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="成交驾校" prop="signSchool"> |
||||
<el-select |
||||
v-model="form.signSchool" |
||||
placeholder="选择驾校" |
||||
filterable |
||||
@change="changeSchool" |
||||
> |
||||
<el-option |
||||
v-for="item in schoolOptions" |
||||
:key="item.schoolId" |
||||
:label="item.schoolName" |
||||
:value="item.schoolId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="成交场地" prop="signPlace"> |
||||
<el-select |
||||
v-model="form.signPlace" |
||||
placeholder="选择场地" |
||||
filterable |
||||
:disabled="!form.signSchool" |
||||
@change="changePlace" |
||||
> |
||||
<el-option |
||||
v-for="item in placeOptions" |
||||
:key="item.placeId" |
||||
:label="item.name" |
||||
:value="item.placeId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="成交班型" prop="signClass"> |
||||
<el-select |
||||
v-model="form.signClass" |
||||
:disabled="!form.signPlace" |
||||
placeholder="选择班型" |
||||
filterable |
||||
@change="changeClass" |
||||
> |
||||
<el-option |
||||
v-for="item in classOptions" |
||||
:key="item.typeId" |
||||
:label="item.typeName" |
||||
:value="item.typeId" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="成交日期" prop="dealDate"> |
||||
<el-date-picker |
||||
v-model="form.dealDate" |
||||
type="date" |
||||
format="YYYY-MM-DD" |
||||
value-format="YYYY-MM-DD" |
||||
placeholder="选择日期时间" |
||||
style="width: 100%" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="成交价" prop="signPrice"> |
||||
<el-input-number |
||||
v-model="form.signPrice" |
||||
:min="0" |
||||
style="width: 100%" |
||||
:controls="false" |
||||
@change="signPriceChange" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="是否全款"> |
||||
<el-radio-group v-model="form.isPayoff"> |
||||
<el-radio :label="true" :value="true"> 全款 </el-radio> |
||||
<el-radio :label="false" :value="false"> 非全款 </el-radio> |
||||
</el-radio-group> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="支付金额" prop="payAmount"> |
||||
<el-input-number |
||||
v-model="form.payAmount" |
||||
:min="0" |
||||
style="width: 100%" |
||||
:controls="false" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24"> |
||||
<el-form-item label="公司收款" prop="isCompanyReceipts"> |
||||
<el-radio-group v-model="form.isCompanyReceipts"> |
||||
<el-radio :label="true" :value="true">是</el-radio> |
||||
<el-radio :label="false" :value="false">否</el-radio> |
||||
</el-radio-group> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :xl="6" :lg="6" :md="8" :sm="24" :xs="24" v-if="form.signClass"> |
||||
<el-form-item label="利润"> |
||||
<div style="color: blue; font-weight: bold; font-size: 16px">{{ profitNum }}</div> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col |
||||
:xl="6" |
||||
:lg="6" |
||||
:md="8" |
||||
:sm="24" |
||||
:xs="24" |
||||
v-for="fieldItem in diyFieldList" |
||||
:key="fieldItem.clueParamId" |
||||
> |
||||
<el-form-item :label="fieldItem.label" :prop="fieldItem.field"> |
||||
<component :is="componentMap[fieldItem.component]" v-model="form[fieldItem.field]"> |
||||
<template v-if="fieldItem.component == 'Select'"> |
||||
<el-option |
||||
v-for="item in fieldItem.options" |
||||
:key="item.id" |
||||
:label="item.name" |
||||
:value="item.id" |
||||
/> |
||||
</template> |
||||
<template v-else-if="fieldItem.component == 'Radio'"> |
||||
<el-radio |
||||
v-for="item in fieldItem.options" |
||||
:key="item.id" |
||||
:label="item.id" |
||||
:value="item.id" |
||||
> |
||||
{{ item.name }} |
||||
</el-radio> |
||||
</template> |
||||
<template v-else-if="fieldItem.component == 'Checkbox'"> |
||||
<el-checkbox |
||||
v-for="item in fieldItem.options" |
||||
:key="item.id" |
||||
:label="item.name" |
||||
:value="item.id" |
||||
/> |
||||
</template> |
||||
</component> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="24" :offset="0" class="mb-18px"> |
||||
<el-divider direction="horizontal" content-position="left"> |
||||
其他费用<span v-if="extraTotalPrice">,应收:{{ extraTotalPrice }}</span> |
||||
</el-divider> |
||||
<el-button |
||||
class="mb-5px" |
||||
type="primary" |
||||
size="small" |
||||
@click="form.extraPay.push({ extraPayType: undefined, extraPayMoney: 0 })" |
||||
> |
||||
添加其他费用 |
||||
</el-button> |
||||
<el-table :data="form.extraPay" border size="small"> |
||||
<el-table-column type="index" width="50" /> |
||||
<el-table-column prop="extraPayType" label="费用类型" width="200px"> |
||||
<template #default="{ row }"> |
||||
<el-select |
||||
v-model="row.extraPayType" |
||||
size="small" |
||||
placeholder="其他费用类型" |
||||
filterable |
||||
> |
||||
<el-option |
||||
v-for="item in extraPayOptions" |
||||
:key="item.value" |
||||
:label="item.label" |
||||
:value="item.value" |
||||
/> |
||||
</el-select> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="extraPayMoney" label="费用金额" width="180px"> |
||||
<template #default="{ row }"> |
||||
<el-input-number v-model="row.extraPayMoney" size="small" :controls="false" /> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="remark" label="备注"> |
||||
<template #default="{ row }"> |
||||
<el-input v-model="row.remark" size="small" placeholder="备注信息" /> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="60px"> |
||||
<template #default="{ $index }"> |
||||
<Icon |
||||
icon="ep:remove-filled" |
||||
class="text-red-500" |
||||
@click="handleRemove('extraPay', $index)" |
||||
/> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</el-col> |
||||
<el-col :span="24" :offset="0" class="mb-18px"> |
||||
<el-divider direction="horizontal" content-position="left"> 额外支出 </el-divider> |
||||
<el-button |
||||
class="mb-5px" |
||||
type="primary" |
||||
size="small" |
||||
@click=" |
||||
form.extraPay.push({ |
||||
extraPayType: undefined, |
||||
extraPayMoney: 0, |
||||
dictType: 'extra_pay_type', |
||||
editabled: true |
||||
}) |
||||
" |
||||
> |
||||
添加额外支出 |
||||
</el-button> |
||||
<el-table :data="form.extraPay" border size="small"> |
||||
<el-table-column type="index" width="50" /> |
||||
<el-table-column prop="extraPayType" label="费用类型" width="200px"> |
||||
<template #default="{ row }"> |
||||
<el-select |
||||
v-if="row.editabled" |
||||
v-model="row.extraPayType" |
||||
size="small" |
||||
placeholder="其他费用类型" |
||||
filterable |
||||
> |
||||
<el-option |
||||
v-for="item in extraPayOptions" |
||||
:key="item.id" |
||||
:label="item.extraPayName" |
||||
:value="item.id" |
||||
/> |
||||
</el-select> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="extraPayMoney" label="费用金额" width="180px"> |
||||
<template #default="{ row }"> |
||||
<el-input-number |
||||
v-if="row.editabled" |
||||
v-model="row.extraPayMoney" |
||||
size="small" |
||||
:controls="false" |
||||
/> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="remark" label="备注"> |
||||
<template #default="{ row }"> |
||||
<el-input |
||||
v-if="row.editabled" |
||||
v-model="row.remark" |
||||
size="small" |
||||
placeholder="备注信息" |
||||
/> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="60px"> |
||||
<template #default="{ row, $index }"> |
||||
<Icon |
||||
icon="ep:remove-filled" |
||||
class="text-red-500" |
||||
v-if="row.editabled" |
||||
@click="handleRemove('extraPay', $index)" |
||||
/> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</el-col> |
||||
<el-col :span="24" :offset="0"> |
||||
<el-form-item label="备注" label-width="50px"> |
||||
<Editor v-model:modelValue="form.remark" /> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<el-button v-if="!remarkInfo.isEnroll" type="primary" @click="handleSave">提 交</el-button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import * as ClueApi from '@/api/clue' |
||||
import { createSign, getSignProfit } from '@/api/clue/sign' |
||||
import { getClueRemarkByRemarkId } from '@/api/clue/clueRemark' |
||||
import { getDiyFieldList } from '@/api/clue/orderField' |
||||
import { getPlaceList } from '@/api/school/place' |
||||
import { getClassTypeList } from '@/api/school/class' |
||||
import { getConfigByConfigKey } from '@/api/system/set' |
||||
import { getSimpleFieldList as getClueField } from '@/api/clue/clueField' |
||||
import { getSimpleFieldList } from '@/api/clue/orderField' |
||||
|
||||
import { formatDate } from '@/utils/formatTime' |
||||
import { getDictOptions } from '@/utils/dict' |
||||
import { componentMap } from '@/components/Form/src/componentMap' |
||||
|
||||
const form = ref({}) |
||||
|
||||
const schoolRules = { |
||||
name: { required: true, message: '学员姓名不可为空', trigger: 'blur' }, |
||||
phone: { required: true, message: '联系方式不可为空', trigger: 'blur' }, |
||||
signSchool: { required: true, message: '成交驾校不可为空', trigger: 'change' }, |
||||
signPlace: { required: true, message: '成交场地不可为空', trigger: 'change' }, |
||||
signClass: { required: true, message: '成交班型不可为空', trigger: 'change' } |
||||
} |
||||
|
||||
const info = ref({}) |
||||
const formLoading = ref(false) |
||||
|
||||
const route = useRoute() |
||||
const message = useMessage() // 消息弹窗 |
||||
|
||||
const extraTotalPrice = computed(() => { |
||||
return form.value.extraPay?.reduce((pre, cur) => pre + cur.extraPayMoney, 0) |
||||
}) |
||||
|
||||
const showSchema = ref([]) |
||||
|
||||
const extraPayOptions = getDictOptions('other_pay_type') |
||||
|
||||
const remarkInfo = ref({}) |
||||
|
||||
onMounted(() => { |
||||
if (route.params.id && route.params.id != 0) { |
||||
// 这里可以调用API获取会议详情数据 |
||||
getClueRemarkByRemarkId({ remarkId: route.params.id }).then((response) => { |
||||
remarkInfo.value = response |
||||
resetForm() |
||||
getOptions() |
||||
getDiyFields() |
||||
ClueApi.getClue(remarkInfo.value.clueId).then((data) => { |
||||
info.value = { ...data, ...data.diyParams, signInfo: remarkInfo.value.signInfo } |
||||
let str = '' |
||||
if (!remarkInfo.value.remarkContent.includes(data.name)) { |
||||
// 提示姓名不一致 |
||||
str += '学员姓名不一致' |
||||
} |
||||
if (!remarkInfo.value.remarkContent.includes(data.phone)) { |
||||
// 提示姓名不一致 |
||||
str += '手机号不一致' |
||||
} |
||||
if (str.length) { |
||||
message.warning(`请注意:${str}`) |
||||
} |
||||
}) |
||||
}) |
||||
} else { |
||||
// 关闭网页 |
||||
window.close() |
||||
} |
||||
}) |
||||
|
||||
async function resetForm() { |
||||
const data = await getConfigByConfigKey({ configKey: 'companyCollectionConfig' }) |
||||
form.value = { |
||||
name: remarkInfo.value.name, |
||||
phone: remarkInfo.value.phone, |
||||
clueId: remarkInfo.value.clueId, |
||||
dealDate: formatDate(new Date()), |
||||
isPayoff: true, |
||||
signPrice: 0, |
||||
payAmount: 0, |
||||
remark: undefined, |
||||
isCompanyReceipts: data.configValue == 'true', |
||||
receiver: remarkInfo.value.enterUser, |
||||
extraPay: [], |
||||
signProducts: [], |
||||
installStatus: 3 |
||||
} |
||||
} |
||||
|
||||
const rules = ref([]) |
||||
function getDiyFields() { |
||||
getSimpleFieldList().then((data) => { |
||||
let ruleObj = {} |
||||
data.map((it) => { |
||||
if (it.isRequired) { |
||||
Reflect.set(ruleObj, it.field, { |
||||
required: true, |
||||
message: `${it.label}不可为空`, |
||||
trigger: 'blur, change' |
||||
}) |
||||
} |
||||
}) |
||||
rules.value = { ...ruleObj, ...schoolRules } |
||||
}) |
||||
} |
||||
|
||||
const formRef = ref() |
||||
async function handleSave() { |
||||
// 校验表单 |
||||
if (!formRef.value) return |
||||
const valid = await formRef.value.validate() |
||||
if (!valid) return |
||||
|
||||
if (form.value.extraPay.some((it) => !it.extraPayType || it.extraPayMoney == null)) { |
||||
message.info('请将费用类型及费用金额填写完整!') |
||||
return |
||||
} |
||||
|
||||
// 提交请求 |
||||
formLoading.value = true |
||||
try { |
||||
const params = { ...form.value } |
||||
params.diyParams = {} |
||||
diyFieldList.value.map((it) => { |
||||
params.diyParams[it.field] = undefined |
||||
}) |
||||
for (const key in params.diyParams) { |
||||
if (Object.hasOwnProperty.call(params, key)) { |
||||
params.diyParams[key] = params[key] |
||||
} |
||||
} |
||||
await createSign(params) |
||||
message.success('登记成功!') |
||||
show.value = false |
||||
// 发送操作成功的事件 |
||||
emit('success') |
||||
} finally { |
||||
formLoading.value = false |
||||
} |
||||
} |
||||
|
||||
const schoolOptions = ref([]) |
||||
const allPlaceOptions = ref([]) |
||||
|
||||
const diyFieldList = ref([]) |
||||
|
||||
const placeOptions = computed(() => { |
||||
return allPlaceOptions.value.filter((it) => it.schoolId == form.value.signSchool) |
||||
}) |
||||
|
||||
const classOptions = ref([]) |
||||
|
||||
async function getClassTypeOptions() { |
||||
const data = await getClassTypeList({ placeId: form.value.signPlace, status: 0 }) |
||||
classOptions.value = data |
||||
} |
||||
|
||||
function getOptions() { |
||||
getClueField().then((data) => { |
||||
const list = useCrudSchemas(data)?.allSchemas?.detailSchema?.map((it) => { |
||||
if (it.label.includes('日期')) { |
||||
it.dateFormat = 'YYYY-MM-DD' |
||||
} |
||||
return it |
||||
}) |
||||
if (list.length % 2 != 0) { |
||||
list.push({}) |
||||
} |
||||
const arr = [ |
||||
{ |
||||
field: 'requirement', |
||||
label: '诉求', |
||||
span: 2 |
||||
}, |
||||
{ |
||||
field: 'remark', |
||||
label: '备注', |
||||
isEditor: true, |
||||
span: 2 |
||||
}, |
||||
{ |
||||
field: 'signInfo', |
||||
label: '报名信息', |
||||
isEditor: true, |
||||
span: 2 |
||||
} |
||||
] |
||||
showSchema.value = [...list, ...arr] |
||||
}) |
||||
// 驾校 |
||||
getPlaceList({ placeStatus: 0, schoolStatus: 0, isSearchSchool: true }).then((data) => { |
||||
schoolOptions.value = data.schoolList |
||||
allPlaceOptions.value = data.placeList |
||||
}) |
||||
// 自定义参数 |
||||
getDiyFieldList().then((data) => { |
||||
diyFieldList.value = data |
||||
}) |
||||
} |
||||
|
||||
function changeSchool() { |
||||
form.value.signPlace = undefined |
||||
form.value.signClass = undefined |
||||
} |
||||
|
||||
function changePlace() { |
||||
form.value.signClass = undefined |
||||
getClassTypeOptions() |
||||
} |
||||
|
||||
function changeClass() { |
||||
form.value.signPrice = |
||||
classOptions.value.find((it) => it.typeId == form.value.signClass).guidingPrice || 0 |
||||
signPriceChange() |
||||
} |
||||
|
||||
function signPriceChange() { |
||||
if (form.value.isPayoff) { |
||||
form.value.payAmount = form.value.signPrice |
||||
} |
||||
calcSignProfit() |
||||
} |
||||
|
||||
const profitNum = ref(0) |
||||
function calcSignProfit() { |
||||
if (form.value.signClass) { |
||||
// 计算员工利润 |
||||
getSignProfit({ signClass: form.value.signClass, signPrice: form.value.signPrice }).then( |
||||
(data) => { |
||||
profitNum.value = data |
||||
} |
||||
) |
||||
} |
||||
} |
||||
|
||||
function handleRemove(type, index) { |
||||
form.value[type].splice(index, 1) |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
||||
Loading…
Reference in new issue