Files
ss-crm-manage-web/src/views/Clue/Pool/Comp/DialogSuccess.vue
2024-08-19 17:26:23 +08:00

627 lines
20 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>
<Dialog title="成交登记" v-model="show" width="900px">
<template #btn>
<el-button class="mr-20px" type="primary" size="small" @click="handleSave">保存</el-button>
</template>
<Descriptions
:title="`线索信息-${info.name}`"
:data="info"
:schema="showSchema"
:columns="2"
labelWidth="130px"
:defaultShow="false"
/>
<el-form :model="form" ref="formRef" :rules="rules" label-width="100px" class="mt-20px">
<el-row :gutter="20">
<!-- 驾校招生模式 -->
<template v-if="appStore.getAppInfo?.instanceType == 1">
<el-col :span="8" :offset="0">
<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 :span="8" :offset="0">
<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 :span="8" :offset="0">
<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>
</template>
<el-col :span="8" :offset="0">
<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 :span="8" :offset="0">
<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 :span="8" :offset="0">
<el-form-item label="是否全款">
<el-radio-group v-model="form.isPayoff">
<el-radio :label="true"> 全款 </el-radio>
<el-radio :label="false"> 非全款 </el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8" :offset="0">
<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 :span="8" :offset="0">
<el-form-item label="公司收款" prop="isCompanyReceipts">
<el-radio-group v-model="form.isCompanyReceipts">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<template v-if="appStore.getAppInfo?.instanceType == 1">
<el-col :span="8" :offset="0" 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 :span="8" :offset="0">
<el-form-item label="接待人" prop="receiver">
<el-select v-model="form.receiver" placeholder="选择接待人" clearable filterable>
<el-option
v-for="item in allUserOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template v-else>
<el-col :span="8" :offset="0">
<el-form-item label="安装状态" prop="installStatus">
<el-select v-model="form.installStatus">
<el-option label="待安装" :value="1" />
<el-option label="已安装" :value="2" />
<el-option label="无需安装" :value="3" />
</el-select>
</el-form-item>
</el-col>
</template>
<el-col
:span="fieldItem.component == 'Editor' ? 24 : 8"
:offset="0"
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">
{{ 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" v-if="appStore.getAppInfo?.instanceType == 2">
<el-divider direction="horizontal" content-position="left">
成交产品<span v-if="prodTotalPrice">应收{{ prodTotalPrice }}</span>
</el-divider>
<el-button
class="mb-5px"
type="primary"
size="small"
@click="
form.signProducts.push({ productId: undefined, specsId: undefined, signNum: 0 })
"
>
添加成交产品
</el-button>
<el-table :data="form.signProducts" border size="small">
<el-table-column type="index" width="50" />
<el-table-column prop="productId" label="产品">
<template #default="{ row }">
<el-select
v-model="row.productId"
placeholder="选择成交产品"
filterable
@change="row.specsId = undefined"
>
<el-option
v-for="item in prodOptions"
:key="item.productId"
:label="item.productName"
:value="item.productId"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="specsId" label="规格">
<template #default="{ row }">
<el-select
v-model="row.specsId"
placeholder="选择规格"
filterable
:disabled="!row.productId"
@change="
row.price = specsOptions(row.productId).find(
(it) => it.specsId == row.specsId
).price
"
>
<el-option
v-for="item in specsOptions(row.productId)"
:key="item.specsId"
:label="item.specsName"
:value="item.specsId"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="price" label="销售单价" width="100px" />
<el-table-column prop="signNum" label="成交数量" width="100px">
<template #default="{ row }">
<el-input-number
v-model="row.signNum"
:min="1"
size="small"
:controls="false"
style="width: 100%"
/>
</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('signProducts', $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">
其他费用<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-divider
v-if="prodTotalPrice + extraTotalPrice"
direction="horizontal"
content-position="left"
>
合计应收{{ prodTotalPrice + extraTotalPrice }}
</el-divider>
</el-col>
<el-col :span="24" :offset="0">
<el-form-item label="备注">
<Editor v-model:modelValue="form.remark" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span>
<el-button @click="show = false"> </el-button>
<el-button :disabled="formLoading" type="primary" @click="handleSave"> </el-button>
</span>
</template>
</Dialog>
</template>
<script setup name="DialogSuccess">
import * as ClueApi from '@/api/clue'
import { createSign, getSignProfit } from '@/api/clue/sign'
import { getDiyFieldList } from '@/api/clue/orderField'
import { getPlaceList } from '@/api/school/place'
import { getClassTypeList } from '@/api/school/class'
import { getSimpleProductList } from '@/api/mall/product'
import { getConfigByConfigKey } from '@/api/system/set'
import { getSimpleFieldList } from '@/api/clue/orderField'
// import { getSimpleWarehouseList } from '@/api/mall/warehouse'
import { formatDate } from '@/utils/formatTime'
import { getDictOptions } from '@/utils/dict'
import { componentMap } from '@/components/Form/src/componentMap'
import { useAppStore } from '@/store/modules/app'
const show = ref(false)
const form = ref({})
const schoolRules = {
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 appStore = useAppStore()
const message = useMessage() // 消息弹窗
const props = defineProps({
schema: {
type: Array
},
allUserOptions: {
type: Array
}
})
const prodTotalPrice = computed(() => {
return form.value.signProducts.reduce(
(pre, cur) => pre + (cur?.price || 0) * (cur?.signNum || 0),
0
)
})
const extraTotalPrice = computed(() => {
return form.value.extraPay.reduce((pre, cur) => pre + cur.extraPayMoney, 0)
})
const showSchema = computed(() => {
let list = props.schema.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
}
]
return [...list, ...arr]
})
// const rules = computed(() => {
// let ruleObj = {}
// props.schema.map((it) => {
// if (it.isRequired) {
// Reflect.set(ruleObj, it.field, {
// required: true,
// message: `${it.label}不可为空`,
// trigger: 'blur, change'
// })
// }
// })
// if (appStore.getAppInfo?.instanceType == 1) {
// ruleObj = { ...ruleObj, ...schoolRules }
// }
// return ruleObj
// })
const extraPayOptions = getDictOptions('other_pay_type')
async function open(id) {
try {
resetForm(id)
getDiyFields()
const data = await ClueApi.getClue(id)
info.value = { ...data, ...data.diyParams }
show.value = true
} catch (error) {
console.log(error)
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
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'
})
}
})
if (appStore.getAppInfo?.instanceType == 1) {
ruleObj = { ...ruleObj, ...schoolRules }
}
rules.value = ruleObj
})
}
async function resetForm(id) {
const data = await getConfigByConfigKey({ configKey: 'companyCollectionConfig' })
form.value = {
clueId: id,
dealDate: formatDate(new Date()),
isPayoff: true,
signPrice: 0,
payAmount: 0,
remark: undefined,
isCompanyReceipts: data.configValue == 'true',
receiver: undefined,
extraPay: [],
signProducts: [],
installStatus: 3
}
}
const emit = defineEmits(['success'])
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
}
if (form.value.signProducts.some((it) => !it.productId || !it.specsId || !it.signNum)) {
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 prodOptions = ref([])
// const warehouseOptions = ref([])
const specsOptions = computed({
get() {
return (prodId) => {
if (prodId) {
return prodOptions.value.find((it) => it.productId == prodId).productSpecList
}
return []
}
}
})
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() {
if (appStore.getAppInfo?.instanceType == 1) {
// 驾校
getPlaceList({ placeStatus: 0, schoolStatus: 0, isSearchSchool: true }).then((data) => {
schoolOptions.value = data.schoolList
allPlaceOptions.value = data.placeList
})
} else {
// 产品
getSimpleProductList().then((data) => {
prodOptions.value = data
})
// 仓库
// getSimpleWarehouseList().then((data) => {
// warehouseOptions.value = data
// })
// 获取员工列表
}
// 自定义参数
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 && appStore.getAppInfo?.instanceType == 1) {
// 计算员工利润
getSignProfit({ signClass: form.value.signClass, signPrice: form.value.signPrice }).then(
(data) => {
profitNum.value = data
}
)
}
}
function handleRemove(type, index) {
form.value[type].splice(index, 1)
}
onMounted(() => {
getOptions()
})
</script>
<style lang="scss" scoped></style>