客户组件封装

pull/781/head
zy 2025-05-19 12:31:14 +08:00
parent a98497cf47
commit 185b306240
15 changed files with 497 additions and 97 deletions

View File

@ -6,8 +6,9 @@ VITE_DEV=true
# 请求路径
# VITE_BASE_URL='http://8.130.12.151:48080'
# VITE_BASE_URL='http://lhy.free.idcfengye.com'
# VITE_BASE_URL='http://m94844f6.natappfree.cc'
VITE_BASE_URL='http://172.22.3.168:48080'
VITE_BASE_URL='http://m94844f6.natappfree.cc'
# VITE_BASE_URL='http://172.22.3.168:48080'
# VITE_BASE_URL='http://172.22.3.203:48080'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务
VITE_UPLOAD_TYPE=server

View File

@ -40,6 +40,13 @@ export const getForm = async (id: number) => {
})
}
// 获得工作流的业务表单定义
export const getBusinessForm = async (params) => {
return await request.get({
url: 'bpm/form-visible/get?id=', params
})
}
// 获得工作流的表单定义分页
export const getFormPage = async (params) => {
return await request.get({

View File

@ -90,6 +90,16 @@ export const QuotationApi = {
return await request.get({ url: `/crm/service-fee-collection-method/page`, params })
},
// 获取服务费次数
getServerFee: async (data: any) => {
return await request.post({ url: `/crm/quotation/get-service-fee`, data })
},
// 获取第几次报价
getQutoTimes: async (params: any) => {
return await request.get({ url: `/crm/quotation/get-quotation-times`, params })
},
// ==================== 子表CRM 报价产品关联) ====================
// 获得CRM 报价产品关联列表

View File

@ -0,0 +1,3 @@
import SelectComponent from './src/index.vue'
export { SelectComponent }

View File

@ -0,0 +1,121 @@
<template>
<el-select
:disabled="disabled"
v-model="selectValue"
:loading="loading"
loading-text="数据加载中..."
filterable
clearable
popper-class="event-select-poper"
v-el-select-loadmore="loadmore"
placeholder="请选择"
style="width: 100%"
:filter-method="filterOptions"
@change="handleEventsChange"
@visible-change="handleVisibleChange">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id" />
</el-select>
</template>
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
defineOptions({ name: 'SelectCustomer' })
const props = defineProps({
disabled: propTypes.number.def(undefined),
value: propTypes.number.def(undefined),
customerList: propTypes.object.def([]), //
})
const selectValue = ref( '')
watch(() => props.value, (val) => {
selectValue.value = val
}, {
immediate: true,
});
watch(() => props.customerList, (val) => {
options.value = val.slice(0, 10)
}, {
deep: true,
});
let pageNo = ref(1)
let pageSize = ref(10)
const loading = ref(false);
const allFilterEvents = reactive([]);
const options = ref([]) //
const vElSelectLoadmore = {
beforeMount(el, binding) {
const selectDom = document.querySelector('.event-select-poper .el-select-dropdown__wrap');
const loadMores = function() {
const isBase = this.scrollHeight - this.scrollTop <= this.clientHeight + 20;
if (isBase) {
binding.value && binding.value();
}
};
el.selectDomInfo = selectDom;
el.selectLoadMore = loadMores;
selectDom?.addEventListener('scroll', loadMores.bind(selectDom));
},
beforeUnmount(el) {
if (el.selectLoadMore) {
el.selectDomInfo.removeEventListener('scroll', el.selectLoadMore);
delete el.selectDomInfo;
delete el.selectLoadMore;
}
}
};
watch(() => allFilterEvents, () => {
let startIndex = pageNo.value * pageSize.value - pageSize.value;
let endIndex = pageNo.value * pageSize.value;
options.value = allFilterEvents.slice(startIndex, endIndex);
}, {
immediate: true,
deep: true
});
const loadmore = () => {
if (props.customerList.length <= options.value.length) return;
pageNo.value++;
nextTick(() => {
loading.value = true;
let startIndex = pageNo.value * pageSize.value - pageSize.value;
let endIndex = pageNo.value * pageSize.value;
options.value = [
...options.value,
...props.customerList.slice(startIndex, endIndex)
];
loading.value = false;
});
};
const filterOptions = (query = '') => {
pageNo.value = 1;
nextTick(() => {
if (query === '') {
allFilterEvents.splice(0, allFilterEvents.length, ...props.customerList);
} else {
allFilterEvents.splice(0, allFilterEvents.length, ...props.customerList.filter(item => item.name.includes(query)));
}
});
};
const handleVisibleChange = (visible) => {
if (!visible) {
pageNo.value = 1;
nextTick(() => {
allFilterEvents.splice(0, allFilterEvents.length, ...props.customerList);
});
}
};
const handleEventsChange = (val) => {
console.log('update:selectValue:', val);
};
</script>

View File

@ -178,6 +178,9 @@ onMounted(async () => {
const bpmnForm = (await getForm(bpmnModel.formId)) as unknown as FormVO
formFields.value = bpmnForm?.fields
}
if (formType.value === BpmModelFormType.CUSTOM && bpmnModel.formId) {
window.localStorage.setItem('businessKey', bpmnModel.key)
}
}
}
//

View File

@ -57,6 +57,7 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
nodeFormFields = toRaw(nodeFormFields)
console.log('%csrc/components/SimpleProcessDesignerV2/src/node.ts:60 nodeFormFields', 'color: #007acc;', nodeFormFields);
if (!nodeFormFields || nodeFormFields.length === 0) {
fieldsPermissionConfig.value = getDefaultFieldsPermission(unref(formFields))
} else {

View File

@ -38,7 +38,7 @@
</el-radio>
</el-radio-group>
</div>
<el-tabs type="border-card" v-model="activeTabName" v-if="approveType === ApproveType.USER">
<el-tabs type="border-card" v-model="activeTabName" v-if="approveType === ApproveType.USER" @tab-click="tabClick">
<el-tab-pane :label="`${nodeTypeName}人`" name="user">
<div>
<el-form ref="formRef" :model="configForm" label-position="top" :rules="formRules">
@ -448,6 +448,58 @@
</div>
</div>
</el-tab-pane>
<el-tab-pane label="表单字段权限" name="businessFields" v-if="formType === 20">
<div class="field-setting-pane">
<div class="field-setting-desc">字段权限</div>
<div class="field-permit-title">
<div class="setting-title-label first-title"> 字段名称 </div>
<div class="other-titles">
<span class="setting-title-label cursor-pointer" @click="updatePermission('READ')">
只读
</span>
<span class="setting-title-label cursor-pointer" @click="updatePermission('WRITE')">
可编辑
</span>
<span class="setting-title-label cursor-pointer" @click="updatePermission('NONE')">
隐藏
</span>
</div>
</div>
<div
class="field-setting-item"
v-for="(item, index) in fieldsPermissionConfig"
:key="index"
>
<div class="field-setting-item-label"> {{ item.title }} </div>
<el-radio-group class="field-setting-item-group" v-model="item.permission">
<div class="item-radio-wrap">
<el-radio
:value="FieldPermissionType.READ"
size="large"
:label="FieldPermissionType.READ"
><span></span
></el-radio>
</div>
<div class="item-radio-wrap">
<el-radio
:value="FieldPermissionType.WRITE"
size="large"
:label="FieldPermissionType.WRITE"
><span></span
></el-radio>
</div>
<div class="item-radio-wrap">
<el-radio
:value="FieldPermissionType.NONE"
size="large"
:label="FieldPermissionType.NONE"
><span></span
></el-radio>
</div>
</el-radio-group>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10">
<div class="field-setting-pane">
<div class="field-setting-desc">字段权限</div>
@ -558,6 +610,7 @@ import { defaultProps } from '@/utils/tree'
import { cloneDeep } from 'lodash-es'
import { convertTimeUnit, getApproveTypeText } from '../utils'
import UserTaskListener from './components/UserTaskListener.vue'
import { getBusinessForm, FormVO } from '@/api/bpm/form'
defineOptions({
name: 'UserTaskNodeConfig'
})
@ -971,6 +1024,17 @@ const updatePermission = (type: string) => {
: FieldPermissionType.NONE
})
}
const tabClick = async (tab) => {
console.log('%csrc/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue:1029 activeTabName.value', 'color: #007acc;', tab.props);
if(tab.props.name === 'businessFields') {
const bpmnForm = (await getBusinessForm({
key: window.localStorage.getItem('businessKey'),
modelNodeId: props.flowNode.id
})) as unknown as FormVO
console.log('%csrc/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue:1035 object', 'color: #007acc;', bpmnForm);
}
}
</script>
<style lang="scss" scoped>

View File

@ -66,6 +66,7 @@ import install from '@form-create/element-ui/auto-import'
import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile'
import { processForm } from '@/components/processForm'
import { processTable } from '@/components/processTable'
import { SelectComponent } from '@/components/SelectCustomer'
import { useApiSelect } from '@/components/FormCreate'
import { Editor } from '@/components/Editor'
import DictSelect from '@/components/FormCreate/src/components/DictSelect.vue'
@ -116,6 +117,7 @@ const components = [
UploadFile,
processForm,
processTable,
SelectComponent,
DictSelect,
UserSelect,
DeptSelect,

View File

@ -34,7 +34,8 @@
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="customerId">
<el-select
<SelectComponent :customerList="customerList" :disabled="formData.customerDefault" :value="formData.customerId" />
<!-- <el-select
:disabled="formData.customerDefault"
v-model="formData.customerId"
:loading="loading"
@ -54,7 +55,7 @@
:label="item.name"
:value="item.id" />
</el-select>
</el-select> -->
</el-form-item>
</el-col>
<el-col :span="12">
@ -178,7 +179,7 @@ import * as CustomerApi from '@/api/crm/customer'
import * as AreaApi from '@/api/system/area'
import { defaultProps } from '@/utils/tree'
import { useUserStore } from '@/store/modules/user'
import SelectComponent from '@/components/SelectCustomer/src/index.vue'
const { t } = useI18n() //
const message = useMessage() //

View File

@ -56,7 +56,45 @@
<dict-tag v-else :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
</template>
</el-table-column>
<el-table-column label="线上价格" align="center" min-width="150">
<el-table-column label="基础服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.basicServiceFee`" :rules="formRules.basicServiceFee" class="mb-0px!">
<!-- <el-input v-model="row.basicServiceFee" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.basicServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="垫资服务费(元)" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.offlinePrice`" :rules="formRules.offlinePrice" class="mb-0px!">
<!-- <el-input v-model="row.offlinePrice" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.advancePaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="代订服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.advancePaymentServiceFee`" :rules="formRules.advancePaymentServiceFee" class="mb-0px!">
{{row.bookingPaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="票据分拣服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.billSortingServiceFee`" :rules="formRules.billSortingServiceFee" class="mb-0px!">
{{row.billSortingServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="服务费收入合计(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.totalServiceFee`" :rules="formRules.totalServiceFee" class="mb-0px!">
{{row.totalServiceFee}}
</el-form-item>
</template>
</el-table-column>
<!-- <el-table-column label="线上价格" align="center" min-width="150">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.onlinePrice`" :rules="formRules.onlinePrice" class="mb-0px!" v-if="!type">
<el-input v-model="row.onlinePrice" placeholder="请输入线上价格" disabled />
@ -78,14 +116,11 @@
</el-table-column>
<el-table-column label="总计价格" align="center" min-width="150">
<template #default="{ row }">
<!-- <el-form-item :prop="`${$index}.totalPrice`" :rules="formRules.totalPrice" class="mb-0px!">
<el-input v-model="row.totalPrice" placeholder="请输入总计价格" disabled />
</el-form-item> -->
<div>
{{row.onlinePrice}}
</div>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="产品票据" align="center" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productInvoice`" :rules="formRules.productInvoice" class="mb-0px!" v-if="!type">
@ -207,8 +242,11 @@ const onChangeProduct = (productId, row) => {
if (product) {
row.productUnit = product.unit
row.productNo = product.no
row.productPrice = product.price
row.contractPrice = product.price
row.basicServiceFee = product.basicServiceFee
row.advancePaymentServiceFee = product.advancePaymentServiceFee
row.bookingPaymentServiceFee = product.bookingPaymentServiceFee
row.billSortingServiceFee = product.billSortingServiceFee
row.totalServiceFee = product.totalServiceFee
}
}

View File

@ -235,7 +235,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-col :span="8">
<el-form-item label="拓展人" prop="expanderUserId">
<el-select v-model="formData.expanderUserId" placeholder="" disabled>
<el-option
@ -246,7 +246,7 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="8">
<el-form-item label="方案报价人" prop="pricingUserId">
<el-select v-model="formData.pricingUserId" placeholder="" disabled>
@ -259,7 +259,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-col :span="8">
<el-form-item label="报价签约人" prop="signUserId">
<el-select v-model="formData.signUserId" placeholder="" disabled>
<el-option
@ -270,7 +270,7 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-col> -->
<!-- <el-col :span="8">
<el-form-item label="签约人联系电话" prop="signPhoneNumber">
<el-input v-model="formData.signPhoneNumber" placeholder="请输入签约人联系电话" />
@ -323,11 +323,6 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="授信额度" prop="creditLimit">
<el-input v-model="formData.creditLimit" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="票据模板" prop="invoiceTemplateId">
<el-select v-model="formData.invoiceTemplateId" placeholder="" disabled >
@ -340,10 +335,33 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="第几次报价" prop="quotationTimes">
<el-input v-model="formData.quotationTimes" disabled placeholder="" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="授信额度" prop="creditLimit">
<el-input v-model="formData.creditLimit" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="线上总金额" prop="onlinePrice">
<el-form-item label="服务费收取方式" prop="serviceFeeCollectionMethodId">
<el-select v-model="formData.serviceFeeCollectionMethodId" disabled placeholder="">
<el-option
v-for="dict in serverMethodList"
:key="dict.id"
:label="dict.productDetail"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="基础服务费合计" prop="onlinePrice">
<el-input
disabled
v-model="formData.onlinePrice"
@ -351,7 +369,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-col :span="8">
<el-form-item label="线下总金额" prop="offlinePrice">
<el-input
disabled
@ -359,9 +377,9 @@
:formatter="erpPriceInputFormatter"
/>
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="8">
<el-form-item label="总金额" prop="totalPrice">
<el-form-item label="服务费收入合计" prop="totalPrice">
<el-input
disabled
v-model="formData.totalPrice"
@ -395,6 +413,7 @@ import { propTypes } from '@/utils/propTypes'
/** CRM 方案报价 表单 */
defineOptions({ name: 'QuotationForm' })
const serverMethodList = ref([])
const { t } = useI18n() //
const message = useMessage() //
const customerList = ref([]) //
@ -481,6 +500,32 @@ const formRules = reactive({
// creditMethod: [{ required: true, message: '', trigger: 'change' }],
// creditCalcCycle: [{ required: true, message: '', trigger: 'change' }],
})
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.basicServiceFee) {
totalOnlinePrice += Number(product.basicServiceFee);
}
if (typeof product.totalServiceFee) {
totalOfflinePrice += Number(product.totalServiceFee);
}
}
formData.value.onlinePrice = totalOnlinePrice.toFixed(2)
// formData.value.offlinePrice = (totalOfflinePrice + totalOnlinePrice).toFixed(2)
// let all = totalOnlinePrice + totalOfflinePrice + totalOnlinePrice
formData.value.totalPrice = totalOfflinePrice.toFixed(2)
},
{ deep: true }
);
const formRef = ref() // Ref
/** 子表的表单 */
@ -582,6 +627,7 @@ const open = async (type: string) => {
totalOfflinePrice += Number(product.offlinePrice);
}
}
formData.value.serviceFeeCollectionMethodId = Number(formData.value.serviceFeeCollectionMethodId)
formData.value.onlinePrice = totalOnlinePrice.toFixed(2)
formData.value.offlinePrice = (totalOfflinePrice + totalOnlinePrice).toFixed(2)
let all = totalOnlinePrice + totalOfflinePrice + totalOnlinePrice
@ -670,7 +716,6 @@ const resetForm = () => {
const route = useRoute();
onMounted(async () => {
console.log('%csrc/views/crm/quotation/QuotationDetail.vue:651 props.id', 'color: #007acc;', props.id, route.query.id);
formType.value = props.id || route.query.id;
if (formType.value) open(formType.value)
@ -688,6 +733,9 @@ onMounted(async () => {
businessList.value = await BusinessApi.getSelfSimpleBusinessList()
//
deptTree.value = handleTree(await DeptApi.getSimpleDeptList())
//
let serverList = await QuotationApi.getServerMethodList({pageNo: 1, pageSize: 1000})
serverMethodList.value = serverList.list
const org = await ContractApi.getOrg({
pageNo: 1,
pageSize: 1000

View File

@ -203,18 +203,7 @@
<el-input v-model="formData.businessLicense" disabled />
</el-form-item>
</el-col>-->
<el-col :span="8">
<el-form-item label="服务费收取方式" prop="serviceFeeCollectionMethodId">
<el-select v-model="formData.serviceFeeCollectionMethodId" placeholder="请选择服务费收取方式">
<el-option
v-for="dict in serverMethodList"
:key="dict.id"
:label="dict.productDetail"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
@ -360,7 +349,19 @@
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="线上总金额" prop="onlinePrice">
<el-form-item label="服务费收取方式" prop="serviceFeeCollectionMethodId">
<el-select v-model="formData.serviceFeeCollectionMethodId" @change="changeQuotationTimes" placeholder="请选择服务费收取方式">
<el-option
v-for="dict in serverMethodList"
:key="dict.id"
:label="dict.productDetail"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="基础服务费合计" prop="onlinePrice">
<el-input
disabled
v-model="formData.onlinePrice"
@ -368,7 +369,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-col :span="8">
<el-form-item label="线下总金额" prop="offlinePrice">
<el-input
disabled
@ -376,9 +377,9 @@
:formatter="erpPriceInputFormatter"
/>
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="8">
<el-form-item label="总金额" prop="totalPrice">
<el-form-item label="服务费收入合计" prop="totalPrice">
<el-input
disabled
v-model="formData.totalPrice"
@ -391,7 +392,7 @@
<!-- 子表的表单 -->
<el-tabs v-model="subTabsName" @tab-Click="handleClick">
<el-tab-pane label="报价产品关联" name="quotationProduct">
<QuotationProductForm ref="quotationProductFormRef" :handleType="handleType" :quotation-id="formData.id" :business-id="formData.businessId" :billTemplateId="formData.invoiceTemplateId" :products="formData.products" @success="setSuccess" />
<QuotationProductForm ref="quotationProductFormRef" :handleType="handleType" :quotation-id="formData.id" :serviceFeeId ="formData.serviceFeeCollectionMethodId" :business-id="formData.businessId" :billTemplateId="formData.invoiceTemplateId" :products="formData.products" :QuotationTimes="formData.QuotationTimes" @success="setSuccess" />
</el-tab-pane>
<el-tab-pane label="营收分析" name="RevenueAnalysis">
<RevenueAnalysis ref="RevenueAnalysisFormRef" :quotation-id="formData.id" :products="formData.products" />
@ -530,17 +531,17 @@ watch(
let totalOfflinePrice = 0;
for (const product of newProducts) {
if (typeof product.onlinePrice) {
totalOnlinePrice += Number(product.onlinePrice);
if (typeof product.basicServiceFee) {
totalOnlinePrice += Number(product.basicServiceFee);
}
if (typeof product.offlinePrice) {
totalOfflinePrice += Number(product.offlinePrice);
if (typeof product.totalServiceFee) {
totalOfflinePrice += Number(product.totalServiceFee);
}
}
formData.value.onlinePrice = totalOnlinePrice.toFixed(2)
formData.value.offlinePrice = (totalOfflinePrice + totalOnlinePrice).toFixed(2)
let all = totalOnlinePrice + totalOfflinePrice + totalOnlinePrice
formData.value.totalPrice = all.toFixed(2)
// formData.value.offlinePrice = (totalOfflinePrice + totalOnlinePrice).toFixed(2)
// let all = totalOnlinePrice + totalOfflinePrice + totalOnlinePrice
formData.value.totalPrice = totalOfflinePrice.toFixed(2)
},
{ deep: true }
);
@ -549,16 +550,40 @@ const setSuccess = (val) => {
formData.value.products = val
}
const changeQuotationTimes = async() => {
if(formData.value.serviceFeeCollectionMethodId && formData.value.businessId) {
newProducts.value = []
formData.value.products.forEach( item => {
newProducts.value.push({
id: item.productId,
productUnit: item.productUnit,
productName: item.productName,
detailType: item.detailType,
category: item.category
})
})
let data = {
businessId: formData.value.businessId,
creditMethod: formData.value.creditMethod,
serviceFeeCollectionMethodId: formData.value.serviceFeeCollectionMethodId,
paymentTerm: formData.value.paymentTerm,
quotationProducts: newProducts.value
}
let num = await QuotationApi.getServerFee(data)
formData.value.QuotationTimes = num.quotationProducts
console.log('%csrc/views/crm/quotation/QuotationForm.vue:574 formData.value.QuotationTimes', 'color: #007acc;', formData.value.QuotationTimes);
}
}
//
const RevenueAnalysisFormRef = ref('')
const newProducts = ref([])
const handleClick = (val) => {
console.log('%csrc/views/crm/quotation/QuotationForm.vue:556 subTabsName.value ', 'color: #007acc;', subTabsName.value );
if (subTabsName.value == 'RevenueAnalysis') return
if(!formData.value.serviceFeeCollectionMethodId) return message.warning('请选择服务费收取方式')
console.log('%csrc/views/crm/quotation/QuotationForm.vue:561 1111', 'color: #007acc;', 1111);
newProducts.value = []
formData.value.products.forEach( item => {
newProducts.value.push({
@ -586,6 +611,8 @@ console.log('%csrc/views/crm/quotation/QuotationForm.vue:561 1111', 'color: #007
const onBusinessChange = async (businessId: string) => {
if (!businessId) return
changeQuotationTimes()
handleType.value = 1
try {
formLoading.value = true;
@ -604,6 +631,7 @@ const onBusinessChange = async (businessId: string) => {
// 🔁
await onCustomerChange(res.customerId);
await getQutotaionTimes(res.customerId);
} catch (err) {
} finally {
formLoading.value = false;
@ -661,6 +689,10 @@ const onPartnerChange = async (id: string) => {
formLoading.value = false;
}
}
const getQutotaionTimes = async (val) => {
console.log('%csrc/views/crm/quotation/QuotationForm.vue:692 val', 'color: #007acc;', val);
formData.value.quotationTimes = await QuotationApi.getQutoTimes({customerId: val})
}
const changeNum = (val) => {
formData.value.creditLimit = (Number(val) + (formData.value.creditAmount || 0)).toFixed(2)

View File

@ -32,24 +32,42 @@
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
</template>
</el-table-column>
<el-table-column label="线上价格" align="center" min-width="150">
<template #default="{ row }">
{{row.onlinePrice}}
<el-table-column label="基础服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.basicServiceFee`" :rules="formRules.basicServiceFee" class="mb-0px!">
<!-- <el-input v-model="row.basicServiceFee" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.basicServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线下手续费" align="center" min-width="150">
<template #default="{ row }">
{{row.offlinePrice}}
<el-table-column label="垫资服务费(元)" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.advancePaymentServiceFee`" :rules="formRules.offlinePrice" class="mb-0px!">
<!-- <el-input v-model="row.offlinePrice" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.advancePaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线下价格(元)" align="center" min-width="130">
<template #default="{ row }">
{{row.downlinePrice}}
<el-table-column label="代订服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.bookingPaymentServiceFee`" :rules="formRules.advancePaymentServiceFee" class="mb-0px!">
{{row.bookingPaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="总计价格" align="center" min-width="150">
<template #default="{ row }">
{{row.totalPrice}}
<el-table-column label="票据分拣服务费(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.billSortingServiceFee`" :rules="formRules.billSortingServiceFee" class="mb-0px!">
{{row.billSortingServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="服务费收入合计(元)" min-width="130">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.totalServiceFee`" :rules="formRules.totalServiceFee" class="mb-0px!">
{{row.totalServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="产品票据" align="center" min-width="150">
@ -117,14 +135,14 @@ watch(
}
nextTick(() => {
//
val.forEach((item) => {
if (item.offlinePrice != null && item.onlinePrice != null) {
item.downlinePrice = Number((Number(item.offlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
item.totalPrice = Number((Number(item.downlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
} else {
item.totalPrice = 0;
}
});
// val.forEach((item) => {
// if (item.offlinePrice != null && item.onlinePrice != null) {
// item.downlinePrice = Number((Number(item.offlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
// item.totalPrice = Number((Number(item.downlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
// } else {
// item.totalPrice = 0;
// }
// });
formData.value = val
})
},

View File

@ -46,32 +46,41 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线上价格(元)" min-width="130">
<el-table-column label="基础服务费(元)" min-width="160">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.onlinePrice`" :rules="formRules.onlinePrice" class="mb-0px!">
<el-input v-model="row.onlinePrice" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" />
<el-form-item :prop="`${$index}.basicServiceFee`" :rules="formRules.basicServiceFee" class="mb-0px!">
<!-- <el-input v-model="row.basicServiceFee" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.basicServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线下手续费(元)" min-width="140">
<el-table-column label="垫资服务费(元)" min-width="160">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.offlinePrice`" :rules="formRules.offlinePrice" class="mb-0px!">
<el-input v-model="row.offlinePrice" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" />
<!-- <el-input v-model="row.offlinePrice" oninput="value=value.match(/^\d+(?:\.\d{0,2})?/)" placeholder="" /> -->
{{row.advancePaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="线下价格(元)" min-width="130">
<el-table-column label="代订服务费(元)" min-width="160">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.downlinePrice`" :rules="formRules.onlinePrice" class="mb-0px!">
{{row.downlinePrice}}
<el-form-item :prop="`${$index}.advancePaymentServiceFee`" :rules="formRules.advancePaymentServiceFee" class="mb-0px!">
{{row.bookingPaymentServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="总计价格(元)" min-width="130">
<el-table-column label="票据分拣服务费(元)" min-width="172">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.totalPrice`" :rules="formRules.totalPrice" class="mb-0px!">
{{row.totalPrice}}
<el-form-item :prop="`${$index}.billSortingServiceFee`" :rules="formRules.billSortingServiceFee" class="mb-0px!">
{{row.billSortingServiceFee}}
</el-form-item>
</template>
</el-table-column>
<el-table-column label="服务费收入合计(元)" min-width="172">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.totalServiceFee`" :rules="formRules.totalServiceFee" class="mb-0px!">
{{row.totalServiceFee}}
</el-form-item>
</template>
</el-table-column>
@ -153,7 +162,9 @@ const props = defineProps<{
businessId: undefined,
billTemplateId: undefined,
products: undefined,
handleType: undefined
handleType: undefined,
serviceFeeId: undefined
QuotationTimes: []
}>()
const formLoading = ref(false) //
const formData = ref([])
@ -164,8 +175,8 @@ const formRules = reactive({
category: [{ required: true, message: '产品类型不能为空', trigger: 'blur' }],
detailType: [{ required: true, message: '产品明细类型不能为空', trigger: 'blur' }],
productUnit: [{ required: true, message: '产品单位不能为空', trigger: 'blur' }],
onlinePrice: [{ required: true, message: '线上价格不能为空', trigger: 'blur' }],
offlinePrice: [{ required: true, message: '线下价格不能为空', trigger: 'blur' }],
basicServiceFee: [{ required: true, message: '基础服务费不能为空', trigger: 'blur' }],
// offlinePrice: [{ required: true, message: '线', trigger: 'blur' }],
totalPrice: [{ required: true, message: '总计价格不能为空', trigger: 'blur' }],
productInvoiceItem: [{ required: true, message: '产品开具项目不能为空', trigger: 'blur' }],
serviceInvoice: [{ required: true, message: '服务费票据不能为空', trigger: 'blur' }],
@ -254,6 +265,46 @@ watch(
},
{ immediate: true }
)
watch(
() => props.QuotationTimes,
async (val) => {
// 2. val
if (!val || !val.length) {
return;
}
try {
formLoading.value = true
for(let i = 0; i < val.length; i++) {
let data = val[i]
if(!data.id) {
data.basicServiceFee = ''
data.advancePaymentServiceFee = ''
data.bookingPaymentServiceFee = ''
data.billSortingServiceFee = ''
data.totalServiceFee = ''
}
console.log('%csrc/views/crm/quotation/components/QuotationProductForm.vue:289 formData.value,data', 'color: #007acc;', formData.value,data);
let foundItem = formData.value.find(item => item.productId == data.id);
console.log('%csrc/views/crm/quotation/components/QuotationProductForm.vue:290 foundItem', 'color: #007acc;', foundItem);
if (foundItem) {
foundItem.basicServiceFee = data.serviceFeeVO.basicServiceFee
foundItem.advancePaymentServiceFee = data.serviceFeeVO.advancePaymentServiceFee
foundItem.bookingPaymentServiceFee = data.serviceFeeVO.bookingPaymentServiceFee
foundItem.billSortingServiceFee = data.serviceFeeVO.billSortingServiceFee
foundItem.totalServiceFee = data.serviceFeeVO.totalServiceFee
}
}
// formData.value = data
// emit('update:handleType', 0)
// }
} finally {
formLoading.value = false
}
},
{ deep: true }
)
//
watch(
() => formData.value,
@ -262,14 +313,14 @@ watch(
return;
}
//
val.forEach((item) => {
if (item.offlinePrice != null && item.onlinePrice != null) {
item.downlinePrice = Number((Number(item.offlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
item.totalPrice = Number((Number(item.downlinePrice) + Number(item.onlinePrice)).toFixed(2)) || 0;
} else {
item.totalPrice = 0;
}
});
// val.forEach((item) => {
// if (item.offlinePrice != null && item.basicServiceFee != null) {
// item.downlinePrice = Number((Number(item.offlinePrice) + Number(item.basicServiceFee)).toFixed(2)) || 0;
// item.totalServiceFee = Number((Number(item.downlinePrice) + Number(item.basicServiceFee)).toFixed(2)) || 0;
// } else {
// item.totalServiceFee = 0;
// }
// });
emit('success', formData.value)
},
{ deep: true }
@ -297,9 +348,9 @@ const handleAdd = () => {
productName: undefined,
detailType: undefined,
productUnit: undefined,
onlinePrice: undefined,
basicServiceFee: undefined,
offlinePrice: undefined,
totalPrice: undefined,
totalServiceFee: undefined,
productInvoice: undefined,
productInvoiceItem: undefined,
serviceInvoice: undefined,