修改-反馈

pull/781/head
zy 2025-05-24 21:39:01 +08:00
parent 5591ad0240
commit 39d77b5a3c
26 changed files with 1767 additions and 201 deletions

View File

@ -0,0 +1,54 @@
import request from '@/config/axios'
// 客户反馈 VO
export interface CustomerFeedbackVO {
id: number // 主键
customerId: number // 客户ID
contactId: number // 反馈联系人ID
mobile: string // 联系电话
email: string // 电子邮箱
feedbackType: number // 反馈类型
feedbackLevel: number // 反馈级别
urgencyLevel: number // 紧急程度
feedbackTime: Date // 反馈时间
relatedPerson: number // 当事人用户ID
deptId: number // 所属部门ID
customerFeedbackCount: number // 客户累计计数
relatedPersonFeedbackCount: number // 当事人累计计数
feedbackCompanyEntity: string // 反馈主体
feedbackContent: string // 反馈内容
attachment: string // 附件
}
// 客户反馈 API
export const CustomerFeedbackApi = {
// 查询客户反馈分页
getCustomerFeedbackPage: async (params: any) => {
return await request.get({ url: `/crm/customer-feedback/page`, params })
},
// 查询客户反馈详情
getCustomerFeedback: async (id: number) => {
return await request.get({ url: `/crm/customer-feedback/get?id=` + id })
},
// 新增客户反馈
createCustomerFeedback: async (data: CustomerFeedbackVO) => {
return await request.post({ url: `/crm/customer-feedback/create`, data })
},
// 修改客户反馈
updateCustomerFeedback: async (data: CustomerFeedbackVO) => {
return await request.put({ url: `/crm/customer-feedback/update`, data })
},
// 删除客户反馈
deleteCustomerFeedback: async (id: number) => {
return await request.delete({ url: `/crm/customer-feedback/delete?id=` + id })
},
// 导出客户反馈 Excel
exportCustomerFeedback: async (params) => {
return await request.download({ url: `/crm/customer-feedback/export-excel`, params })
},
}

View File

@ -100,6 +100,11 @@ export const QuotationApi = {
return await request.get({ url: `/crm/quotation/get-quotation-times`, params }) return await request.get({ url: `/crm/quotation/get-quotation-times`, params })
}, },
// 获取保险列表
getInsuranceList: async (params: any) => {
return await request.get({ url: `/crm/service-fee-collection-method/get-insurance-list`, params })
},
// ==================== 子表CRM 报价产品关联) ==================== // ==================== 子表CRM 报价产品关联) ====================
// 获得CRM 报价产品关联列表 // 获得CRM 报价产品关联列表

View File

@ -45,15 +45,27 @@ const allFilterEvents = ref([])
watch(() => props.modelValue, (val) => { watch(() => props.modelValue, (val) => {
selectValue.value = val selectValue.value = val
let arr = options.value.filter(v => v.id === val) console.log('%csrc/components/SelectCustomer/src/index.vue:48 val,', 'green', val,props.customerList);
if (!arr.length) { nextTick(() => {
let selectItem = props.customerList.filter(v => v.id === val) let arr = options.value.filter(v => v.id === val)
options.value = [...options.value, ...selectItem] if (!arr.length) {
} let selectItem = props.customerList.filter(v => v.id === val)
options.value = [...options.value, ...selectItem]
}
})
}, { immediate: true }) }, { immediate: true })
watch(() => props.customerList, (val) => { watch(() => props.customerList, (val) => {
options.value = val.slice(0, 10) options.value = val.slice(0, 10)
console.log('%csrc/components/SelectCustomer/src/index.vue:60 props.customerList,4444', 'color: pink;', props.modelValue,props.customerList,4444);
nextTick(() => {
let arr = options.value.filter(v => v.id === props.modelValue)
if (!arr.length) {
let selectItem = props.customerList.filter(v => v.id === props.modelValue)
console.log('%csrc/components/SelectCustomer/src/index.vue:65 selectItem', 'color: #007acc;', selectItem);
options.value = [...options.value, ...selectItem]
}
})
}, { deep: true }) }, { deep: true })
let pageNo = ref(1) let pageNo = ref(1)

View File

@ -773,6 +773,42 @@ const remainingRouter: AppRouteRecordRaw[] = [
activeMenu: '/crm/customer-complaints' activeMenu: '/crm/customer-complaints'
} }
}, },
{
path: 'feedback/CustomerFeedbackForm',
component: () => import('@/views/crm/feedback/CustomerFeedbackForm.vue'),
name: 'CustomerFeedbackCreate',
meta: {
noCache: true,
hidden: true,
canTo: true,
title: '客户反馈新增',
activeMenu: '/crm/feed-back'
}
},
{
path: 'feedback/CustomerFeedbackFormEdit',
component: () => import('@/views/crm/feedback/CustomerFeedbackForm.vue'),
name: 'CustomerFeedbackEdit',
meta: {
noCache: true,
hidden: true,
canTo: true,
title: '客户反馈编辑',
activeMenu: '/crm/feed-back'
}
},
{
path: 'feedback/CustomerFeedbackDetail',
component: () => import('@/views/crm/feedback/CustomerFeedbackDetail.vue'),
name: 'CustomerFeedbackDetail',
meta: {
noCache: true,
hidden: true,
canTo: true,
title: '客户反馈详情',
activeMenu: '/crm/feed-back'
}
},
{ {
path: 'filetemplate/previewDoc', path: 'filetemplate/previewDoc',
component: () => import('@/views/crm/filetemplate/previewDoc.vue'), component: () => import('@/views/crm/filetemplate/previewDoc.vue'),

View File

@ -35,3 +35,7 @@
border-left-color: var(--el-color-primary); border-left-color: var(--el-color-primary);
} }
} }
.mt-3 {
margin-bottom: 10px;
}

View File

@ -220,6 +220,7 @@ export enum DICT_TYPE {
SALE_STAGE='sale_stage',// 销售阶段 SALE_STAGE='sale_stage',// 销售阶段
TIME_TYPE='time_type',// 时间类型 TIME_TYPE='time_type',// 时间类型
CRM_PARTNER_TYPE = 'crm_partner_type',//合作类型 CRM_PARTNER_TYPE = 'crm_partner_type',//合作类型
CRM_PARTNER_TYPE1 = 'CRM_PARTNER_TYPE1',//合作类型
CRM_SERVICE_FEE_COLLECTION_METHOD = 'crm_service_fee_collection_method',//服务费收取方式 CRM_SERVICE_FEE_COLLECTION_METHOD = 'crm_service_fee_collection_method',//服务费收取方式
CRM_CONTACT_ROLE_TYPE = 'crm_contact_role_type',//角色 CRM_CONTACT_ROLE_TYPE = 'crm_contact_role_type',//角色
@ -242,6 +243,9 @@ export enum DICT_TYPE {
SYNCHRONIZATION_STATUS="synchronization_status", //同步状态 SYNCHRONIZATION_STATUS="synchronization_status", //同步状态
MATCHING_PRODUCT_TYPES="matching_product_types", //对接产品类型 MATCHING_PRODUCT_TYPES="matching_product_types", //对接产品类型
CRM_SERVICE_FEE_COLLECTION_METHOD_TYPE = 'crm_service_fee_collection_method_type', // 服务费收取方式类型 CRM_SERVICE_FEE_COLLECTION_METHOD_TYPE = 'crm_service_fee_collection_method_type', // 服务费收取方式类型
CRM_URGENCY_LEVEL = "crm_urgency_level", // 紧急程度
CRM_FEEDBACK_LEVEL = "crm_feedback_level", // 反馈级别
CRM_FEEDBACK_TYPE = "crm_feedback_type", // 反馈类型
// ========== ERP - 企业资源计划模块 ========== // ========== ERP - 企业资源计划模块 ==========

View File

@ -8,11 +8,11 @@
v-loading="formLoading" v-loading="formLoading"
> >
<el-row> <el-row>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="商机名称" prop="name"> <el-form-item label="商机名称" prop="name">
<el-input v-model="formData.name" :disabled="type" clearable placeholder="请输入商机名称" /> <el-input v-model="formData.name" :disabled="type" clearable placeholder="请输入商机名称" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="客户名称" prop="customerId"> <el-form-item label="客户名称" prop="customerId">
<SelectComponent :customerList="customerList" :disabled="formData.customerDefault || type" v-model="formData.customerId" /> <SelectComponent :customerList="customerList" :disabled="formData.customerDefault || type" v-model="formData.customerId" />
@ -34,11 +34,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="线索拓展人" prop="ownerUserId"> <el-form-item label="拓展人" prop="clueDeveloper">
<el-select <el-select
v-model="formData.ownerUserId" v-model="formData.clueDeveloper"
disabled disabled
placeholder="请选择线拓展人" placeholder="请选择线拓展人"
class="w-1/1" class="w-1/1"
> >
<el-option <el-option
@ -104,7 +104,7 @@
/> />
</el-form-item> </el-form-item>
</el-col> --> </el-col> -->
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="商机状态组" prop="statusTypeId"> <el-form-item label="商机状态组" prop="statusTypeId">
<el-select <el-select
v-model="formData.statusTypeId" v-model="formData.statusTypeId"
@ -121,7 +121,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="预计成交日期" prop="dealTime"> <el-form-item label="预计成交日期" prop="dealTime">
<el-date-picker <el-date-picker
@ -195,17 +195,10 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> --> </el-col> -->
<el-col :span="8"> <el-col :span="24">
<el-form-item label="项目难度" prop="projectDifficultyId"> <ContentWrap style="border: none;font-weight: 700">
<el-select v-model="formData.projectDifficultyId" :disabled="type" clearable placeholder="请选择项目难度"> 项目难度
<el-option </ContentWrap>
v-for="dict in difficultOptions"
:key="dict.id"
:label="dict.projectDifficulty"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="平台" prop="platformId"> <el-form-item label="平台" prop="platformId">
@ -219,11 +212,39 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="项目难度" prop="projectDifficultyId">
<el-select v-model="formData.projectDifficultyId" :disabled="type" clearable placeholder="请选择项目难度">
<el-option
v-for="dict in difficultOptions"
:key="dict.id"
:label="dict.projectDifficulty"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" class="toop">
行政自主在线上预定无审批流无差标无客服服务
<!-- <el-form-item label="" prop="platformId">
</el-form-item> -->
</el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input type="textarea" :disabled="type" v-model="formData.remark" clearable :placeholder="formType ? '' : '请输入备注'" /> <el-input type="textarea" :disabled="type" v-model="formData.remark" clearable :placeholder="formType ? '' : '请输入备注'" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24">
<el-form-item label="产品类型" prop="remark">
<el-checkbox-group v-model="checkList" @change="changeCheck">
<el-checkbox v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_CATEGORY)"
:key="dict.value"
:label="dict.value">{{dict.label}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row> </el-row>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<ContentWrap> <ContentWrap>
@ -232,6 +253,7 @@
<BusinessProductForm <BusinessProductForm
ref="productFormRef" ref="productFormRef"
:products="formData.products" :products="formData.products"
:productsTypeList="productsTypeList"
:disabled="type" :disabled="type"
@success="setList" @success="setList"
/> />
@ -288,12 +310,15 @@ import { defaultProps, handleTree } from '@/utils/tree';
import BusinessProductForm from './components/BusinessProductForm.vue'; import BusinessProductForm from './components/BusinessProductForm.vue';
import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils'; import { erpPriceMultiply, erpPriceInputFormatter } from '@/utils';
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { json } from 'stream/consumers';
const { proxy }: any = getCurrentInstance(); const { proxy }: any = getCurrentInstance();
const { t } = useI18n(); const { t } = useI18n();
const message = useMessage(); const message = useMessage();
const checkList = ref([])
const productsTypeList = ref([])
const dialogVisible = ref(false); const dialogVisible = ref(false);
const dialogTitle = ref(''); const dialogTitle = ref('');
const formLoading = ref(false); const formLoading = ref(false);
@ -305,7 +330,7 @@ const formData = ref({
followUpStatus: undefined, followUpStatus: undefined,
contactLastTime: undefined, contactLastTime: undefined,
contactNextTime: undefined, contactNextTime: undefined,
ownerUserId: undefined, clueDeveloper: undefined,
deptId: undefined, deptId: undefined,
requestorUserId: undefined, requestorUserId: undefined,
statusTypeId: undefined, statusTypeId: undefined,
@ -327,7 +352,7 @@ const formData = ref({
const formRules = reactive({ const formRules = reactive({
name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], clueDeveloper: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }], statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }],
saleStage: [{ required: true, message: '销售阶段不能为空', trigger: 'change' }], saleStage: [{ required: true, message: '销售阶段不能为空', trigger: 'change' }],
paymentTerm: [{ required: true, message: '账期不能为空', trigger: 'change' }], paymentTerm: [{ required: true, message: '账期不能为空', trigger: 'change' }],
@ -391,10 +416,16 @@ const open = async (id?: number, customerId?: number) => {
formLoading.value = true; formLoading.value = true;
try { try {
const data = await BusinessApi.getBusiness(id); const data = await BusinessApi.getBusiness(id);
productsTypeList.value = JSON.parse(JSON.stringify(data.products))
formData.value = { formData.value = {
...data, ...data,
products: data.products || [] products: data.products || []
}; };
let newData = []
data.products.map(v => {
newData.push(v.category)
})
checkList.value = [...new Set(newData)]
} finally { } finally {
formLoading.value = false; formLoading.value = false;
} }
@ -408,6 +439,7 @@ const open = async (id?: number, customerId?: number) => {
}; };
const setList = (newProducts) => { const setList = (newProducts) => {
checkList.value = []
formData.value.products = newProducts; formData.value.products = newProducts;
}; };
@ -456,7 +488,7 @@ const resetForm = () => {
id: undefined, id: undefined,
name: undefined, name: undefined,
customerId: undefined, customerId: undefined,
ownerUserId: undefined, clueDeveloper: undefined,
statusTypeId: undefined, statusTypeId: undefined,
dealTime: undefined, dealTime: undefined,
totalPrice: 0, totalPrice: 0,
@ -468,10 +500,15 @@ const resetForm = () => {
formRef.value?.resetFields(); formRef.value?.resetFields();
}; };
const changeCheck = (val) => {
productFormRef.value.getData(val)
}
const route = useRoute(); const route = useRoute();
onMounted(async () => { onMounted(async () => {
const customerId = route.query.customerId; const customerId = route.query.customerId;
formData.value.ownerUserId = customerId ? '' : useUserStore().getUser.id; formData.value.clueDeveloper = customerId ? '' : useUserStore().getUser.id;
formData.value.requestorUserId = customerId ? '' : useUserStore().getUser.id;
formType.value = route.query.id || route.params.id; formType.value = route.query.id || route.params.id;
if (formType.value) open(formType.value, customerId) if (formType.value) open(formType.value, customerId)
customerList.value = await CustomerApi.getSelfCustomerSimpleList(); customerList.value = await CustomerApi.getSelfCustomerSimpleList();
@ -485,3 +522,12 @@ onMounted(async () => {
deptTree.value = handleTree(await DeptApi.getSimpleDeptList()); deptTree.value = handleTree(await DeptApi.getSimpleDeptList());
}); });
</script> </script>
<style scoped>
.toop {
line-height: 32px;
font-size: 12px;
font-weight: 500;
padding-left: 10px;
}
</style>

View File

@ -62,17 +62,11 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="合计(元)" prop="totalPrice" align="center" fixed="right" min-width="100"> <el-table-column label="合计(元)" prop="totalPrice" align="center" fixed="right" min-width="100">
<template #default="{ row, $index }"> <template #default="{ row }">
<el-form-item :prop="`${$index}.totalPrice`" class="mb-0px!">
{{row.totalPrice}} {{row.totalPrice}}
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="60" v-if="!disabled">
<template #default="{ $index }">
<el-button @click="handleDelete($index)" link></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-form> </el-form>
<el-row justify="center" class="mt-3" v-if="!disabled"> <el-row justify="center" class="mt-3" v-if="!disabled">
@ -91,6 +85,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict';
const formLoading = ref(false); // const formLoading = ref(false); //
const formData = ref([]); // const formData = ref([]); //
const listData = ref([])
const formRules = reactive({ const formRules = reactive({
detailType: [{ required: true, message: '产品明细不能为空', trigger: 'blur' }], detailType: [{ required: true, message: '产品明细不能为空', trigger: 'blur' }],
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }], productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
@ -103,12 +98,22 @@ const productList = ref<ProductApi.ProductVO[]>([]); // 产品列表
const props = defineProps<{ const props = defineProps<{
products: any[]; // products products: any[]; // products
disabled: boolean; // disabled disabled: boolean; // disabled
productsTypeList: any[]
}>(); }>();
// //
watch( watch(
() => props.products, () => props.products,
(val) => { (val) => {
formData.value = val || []; // formData formData.value = val || []; // formData
// listData.value = JSON.parse(JSON.stringify(formData.value))
},
{ immediate: true }
);
watch(
() => props.productsTypeList,
(val) => {
listData.value = val || []; // formData
}, },
{ immediate: true } { immediate: true }
); );
@ -170,6 +175,8 @@ const getList = (val: []) => {
}) })
} }
}) })
listData.value = JSON.parse(JSON.stringify(formData.value))
console.log('%csrc/views/crm/business/components/BusinessProductForm.vue:170 listData', 'color: #007acc;', listData.value);
emit('success', formData.value) emit('success', formData.value)
} }
@ -204,7 +211,25 @@ const onChangeProduct = (productId, row) => {
const validate = () => { const validate = () => {
return formRef.value.validate() return formRef.value.validate()
}; };
defineExpose({ validate });
const getData = (val) => {
let newArrList = []
for(let i = 0; i < val.length; i++) {
let item = val[i]
let newArr = listData.value.filter(v => v.category === item)
newArrList = [...newArrList, ...newArr]
}
formData.value = newArrList
console.log('%csrc/views/crm/business/components/BusinessProductForm.vue:215 listData.value', 'color: #007acc;',!val.length, listData.value);
if(!val.length) {
console.log('%csrc/views/crm/business/components/BusinessProductForm.vue:208 121212', 'color: #007acc;', 121212);
return formData.value = JSON.parse(JSON.stringify(listData.value))
}
console.log('%csrc/views/crm/business/components/BusinessProductForm.vue:218 formData.value', 'color: #007acc;', formData.value);
};
defineExpose({ validate, getData });
// //
onMounted(async () => { onMounted(async () => {

View File

@ -8,9 +8,15 @@
class="-mb-15px" class="-mb-15px"
label-width="68px" label-width="68px"
> >
<el-form-item label="客户名称" prop="customerId"> <el-form-item label="客户名称" prop="customerName">
<SelectComponent :customerList="customerList" class="!w-240px" v-model="queryParams.customerId" /> <!-- <SelectComponent :customerList="customerList" class="!w-240px" v-model="queryParams.customerId" /> -->
<!-- <el-select <el-input
v-model="queryParams.customerName"
class="!w-240px"
clearable
placeholder="请输入客户名称"
@keyup.enter="handleQuery"
/><!-- <el-select
v-model="queryParams.customerId" v-model="queryParams.customerId"
class="!w-240px" class="!w-240px"
clearable clearable
@ -40,7 +46,7 @@
<Icon class="mr-5px" icon="ep:plus" /> <Icon class="mr-5px" icon="ep:plus" />
新增 新增
</el-button> </el-button>
<el-button <!-- <el-button
v-hasPermi="['crm:business:export']" v-hasPermi="['crm:business:export']"
:loading="exportLoading" :loading="exportLoading"
plain plain
@ -49,18 +55,18 @@
> >
<Icon class="mr-5px" icon="ep:download" /> <Icon class="mr-5px" icon="ep:download" />
导出 导出
</el-button> </el-button> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
</ContentWrap> </ContentWrap>
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<!-- <el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="我负责的" name="1" /> <el-tab-pane label="我负责的" name="1" />
<el-tab-pane label="我参与的" name="2" /> <el-tab-pane label="我参与的" name="2" />
<el-tab-pane label="下属负责的" name="3" /> <el-tab-pane label="下属负责的" name="3" />
</el-tabs> --> </el-tabs>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" fixed="left" label="商机名称" prop="name" width="200"> <el-table-column align="center" fixed="left" label="商机名称" prop="name" width="200">
<template #default="scope"> <template #default="scope">
@ -137,13 +143,13 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <!-- <el-table-column
align="center" align="center"
label="商机阶段" label="商机阶段"
prop="statusName" prop="statusName"
width="120" width="120"
/> /> -->
<el-table-column align="center" fixed="right" label="操作" width="130px"> <el-table-column align="center" fixed="right" label="操作" width="130px" v-if="activeName == 1">
<template #default="scope"> <template #default="scope">
<el-button <el-button
v-hasPermi="['crm:business:update']" v-hasPermi="['crm:business:update']"

View File

@ -76,8 +76,8 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="角色" prop="sex"> <el-form-item label="角色" prop="contactRoleType">
<el-select v-model="formData.sex" placeholder="请选择角色" class="w-1/1"> <el-select v-model="formData.contactRoleType" placeholder="请选择角色" class="w-1/1">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CONTACT_ROLE_TYPE)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CONTACT_ROLE_TYPE)"
:key="dict.value" :key="dict.value"
@ -233,12 +233,14 @@ const formData = ref({
parentId: undefined, parentId: undefined,
remark: undefined, remark: undefined,
businessId: undefined, businessId: undefined,
contactRoleType: undefined,
customerDefault: false customerDefault: false
}) })
const formRules = reactive({ const formRules = reactive({
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }], name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
contactRoleType: [{ required: true, message: '角色不能为空', trigger: 'change' }] ,
email: [{ required: false, message: '电子邮箱不能为空', trigger: 'blur' } , email: [{ required: false, message: '电子邮箱不能为空', trigger: 'blur' } ,
{ {
pattern: pattern:

View File

@ -52,7 +52,7 @@
<el-input v-model="formData.processInstanceId" disabled placeholder="协议编码" /> <el-input v-model="formData.processInstanceId" disabled placeholder="协议编码" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="合同状态" prop="quotationId"> <el-form-item label="合同状态" prop="quotationId">
<el-select v-model="formData.auditStatus" disabled clearable placeholder=""> <el-select v-model="formData.auditStatus" disabled clearable placeholder="">
<el-option <el-option
@ -63,7 +63,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="协议截止日期" prop="endTime"> <el-form-item label="协议截止日期" prop="endTime">
<el-date-picker <el-date-picker
@ -116,7 +116,7 @@
<ContracExtension ref="contractExtensionFormRef" v-if="formData.changeItem == 3" :data="formData" /> <ContracExtension ref="contractExtensionFormRef" v-if="formData.changeItem == 3" :data="formData" />
<ContractStop ref="contractStopFormRef" :formData="formData" v-if="formData.changeItem == 4" /> <ContractStop ref="contractStopFormRef" :formData="formData" v-if="formData.changeItem == 4" />
<ContractAAuthorizedCompanyForm ref="contractAAuthorizedCompanyFormRef1" v-if="formData.changeItem == 5" :data="formData.contractAAuthorizedCompanys" /> <ContractAAuthorizedCompanyForm ref="contractAAuthorizedCompanyFormRef1" v-if="formData.changeItem == 5" :data="formData.contractAAuthorizedCompanys" />
<ContractForm ref="contractFormRef" :type="1" :changeType="true" v-if="formData.changeItem == 6" /> <ContractForm ref="contractFormRef" :type="1" v-if="formData.changeItem == 6" />
</ContentWrap> </ContentWrap>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">

View File

@ -11,22 +11,22 @@
基础信息 基础信息
</ContentWrap> </ContentWrap>
<el-row> <el-row>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="合同名称" prop="name"> <el-form-item label="合同名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入合同名称" /> <el-input v-model="formData.name" placeholder="请输入合同名称" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="客户名称" prop="customerId"> <el-form-item label="客户名称" prop="customerId">
<SelectComponent :customerList="customerList" :disabled="!!formType" v-model="formData.customerId" @change="onCustomerChange" /> <SelectComponent :customerList="customerList" :disabled="!!formType" v-model="formData.customerId" @change="onCustomerChange" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" v-if="formType"> <!-- <el-col :span="8" v-if="formType">
<el-form-item label="合同编号" prop="no"> <el-form-item label="合同编号" prop="no">
<el-input disabled v-model="formData.no" placeholder="" /> <el-input disabled v-model="formData.no" placeholder="" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="报价单编号" prop="quotationId"> <el-form-item label="报价单编号" prop="quotationId">
<el-select <el-select
@ -47,10 +47,11 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="方案签约人" prop="pricingUserId"> <el-form-item label="签约人" prop="contractor">
<el-select <el-select
v-model="formData.pricingUserId" v-model="formData.contractor"
class="w-1/1" class="w-1/1"
disabled
> >
<el-option <el-option
v-for="item in userOptions" v-for="item in userOptions"
@ -219,6 +220,18 @@
乙方基本信息 乙方基本信息
</ContentWrap> </ContentWrap>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="合作类型" prop="cooperationType">
<el-select v-model="formData.cooperationType" disabled filterable clearable placeholder="" class="w-1/1">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="合作主体" prop="partnerCompanyId"> <el-form-item label="合作主体" prop="partnerCompanyId">
<el-select v-model="formData.partnerCompanyId" placeholder="" disabled > <el-select v-model="formData.partnerCompanyId" placeholder="" disabled >
@ -246,7 +259,7 @@
<el-input v-model="formData.legalRepresentative" placeholder="" disabled /> <el-input v-model="formData.legalRepresentative" placeholder="" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="商务负责人" prop="ownerUserId"> <el-form-item label="商务负责人" prop="ownerUserId">
<el-select <el-select
v-model="formData.ownerUserId" v-model="formData.ownerUserId"
@ -261,7 +274,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="手机号" prop="mobile"> <el-form-item label="手机号" prop="mobile">
<el-input <el-input
@ -310,8 +323,8 @@
<el-col :span="8"> <el-col :span="8">
<el-form-item label="合同类型" prop="contractType"> <el-form-item label="合同类型" prop="contractType">
<el-radio-group v-model="formData.contractType"> <el-radio-group v-model="formData.contractType">
<el-radio :label="1">单次合同</el-radio> <el-radio :label="1">甲方合同</el-radio>
<el-radio :label="2">框架合同</el-radio> <el-radio :label="2">乙方合同</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -320,6 +333,7 @@
<el-date-picker <el-date-picker
v-model="formData.startTime" v-model="formData.startTime"
type="date" type="date"
@change="changeTime"
value-format="x" value-format="x"
format="YYYY-MM-DD" format="YYYY-MM-DD"
placeholder="选择合同签订日期" placeholder="选择合同签订日期"
@ -333,6 +347,7 @@
v-model="formData.endTime" v-model="formData.endTime"
type="date" type="date"
value-format="x" value-format="x"
disabled
format="YYYY-MM-DD" format="YYYY-MM-DD"
placeholder="选择合同结束时间" placeholder="选择合同结束时间"
style="width: 100%" style="width: 100%"
@ -341,7 +356,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="合同期限(月)" prop="contractTerm"> <el-form-item label="合同期限(月)" prop="contractTerm">
<el-input v-model="formData.contractTerm" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入合同期限(月)" /> <el-input v-model="formData.contractTerm" @input="changeTime" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入合同期限(月)" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@ -388,19 +403,19 @@
<el-row> --> <el-row> -->
<el-col :span="24"> <el-col :span="24">
<ContentWrap style="border: none;font-weight: 700"> <ContentWrap style="border: none;font-weight: 700">
财务与客服对接信息 对接信息
</ContentWrap> </ContentWrap>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="财务结算方式" prop="settleMethod"> <el-form-item label="财务结算方式" prop="settleMethod">
<el-radio-group v-model="formData.settleMethod"> <el-radio-group v-model="formData.settleMethod">
<el-radio :label="1">按月结算</el-radio> <el-radio :label="1">按月结算</el-radio>
<el-radio :label="0">按项目结算</el-radio> <el-radio :label="0">按项目结算</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="售后维护人" prop="afterSaleUserId"> <el-form-item label="维护人" prop="afterSaleUserId">
<el-select v-model="formData.afterSaleUserId" placeholder="请选择售后维护人"> <el-select v-model="formData.afterSaleUserId" placeholder="请选择售后维护人">
<el-option <el-option
v-for="dict in userOptions" v-for="dict in userOptions"
@ -412,6 +427,86 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="拓展人" prop="clueDeveloper">
<el-select
class="w-1/1"
placeholder="请选择拓展人"
v-model="formData.clueDeveloper"
filterable
>
<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="servicor">
<el-select
class="w-1/1"
placeholder="请选择服务对接人"
v-model="formData.servicor"
filterable
>
<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="technicalLead">
<el-select
class="w-1/1"
placeholder="请选择技术对接人"
v-model="formData.technicalLead"
filterable
>
<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="settlementLead">
<el-select
class="w-1/1"
placeholder="请选择结算对接人"
v-model="formData.settlementLead"
filterable
>
<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="afterSaleUserId">
<el-select v-model="formData.afterSaleUserId" placeholder="请选择售后维护人">
<el-option
v-for="dict in userOptions"
:key="dict.id"
:label="dict.nickname"
:value="dict.id"
/>
</el-select>
</el-form-item>
</el-col> -->
<!-- <el-col :span="8">
<el-form-item label="协作人" prop="collUserId"> <el-form-item label="协作人" prop="collUserId">
<el-select v-model="formData.collUserId" placeholder="请选择协作人"> <el-select v-model="formData.collUserId" placeholder="请选择协作人">
<el-option <el-option
@ -422,17 +517,17 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="24"> <!-- <el-col :span="24">
<el-form-item label="合同正文" prop="contractBody"> <el-form-item label="合同正文" prop="contractBody">
<el-input v-model="formData.contractBody" type="textarea" rows="5" placeholder="请输入合同正文" /> <el-input v-model="formData.contractBody" type="textarea" rows="5" placeholder="请输入合同正文" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="24"> <!-- <el-col :span="24">
<el-form-item label="合同补充协议" prop="contractAgreement"> <el-form-item label="合同补充协议" prop="contractAgreement">
<el-input v-model="formData.contractAgreement" type="textarea" rows="5" placeholder="请输入合同补充协议" /> <el-input v-model="formData.contractAgreement" type="textarea" rows="5" placeholder="请输入合同补充协议" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
</el-row> </el-row>
<ContentWrap style="border: none;font-weight:700"> <ContentWrap style="border: none;font-weight:700">
@ -460,12 +555,12 @@
<ContentWrap> <ContentWrap>
<ContractAAuthorizedPersonForm :formFields="formFields" ref="contractAAuthorizedPersonFormRef" :contract-id="formData.id" :customerId="formData.customerId" /> <ContractAAuthorizedPersonForm :formFields="formFields" ref="contractAAuthorizedPersonFormRef" :contract-id="formData.id" :customerId="formData.customerId" />
</ContentWrap> </ContentWrap>
<ContentWrap style="border: none;font-weight:700"> <!-- <ContentWrap style="border: none;font-weight:700">
合同乙方授权人信息 合同乙方授权人信息
</ContentWrap> </ContentWrap>
<ContentWrap> <ContentWrap>
<ContractBAuthorizedPersonForm :formFields="formFields" ref="contractBAuthorizedPersonFormRef" :userOptions="userOptions" :contract-id="formData.id" /> <ContractBAuthorizedPersonForm :formFields="formFields" ref="contractBAuthorizedPersonFormRef" :userOptions="userOptions" :contract-id="formData.id" />
</ContentWrap> </ContentWrap> -->
</el-form> </el-form>
<!-- 显示在其他页面时的判断type --> <!-- 显示在其他页面时的判断type -->
<div style="text-align: right" v-if="!type"> <div style="text-align: right" v-if="!type">
@ -491,6 +586,7 @@ import { propTypes } from '@/utils/propTypes'
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import moment from 'moment';
const { t } = useI18n() // const { t } = useI18n() //
@ -578,8 +674,8 @@ const formData = ref({
offlinePrice: undefined, offlinePrice: undefined,
onlinePrice: undefined, onlinePrice: undefined,
ownerUserId: undefined, ownerUserId: undefined,
expanderUserId: undefined, clueDeveloper: undefined,
pricingUserId: undefined, contractor: undefined,
afterSaleUserId: undefined, afterSaleUserId: undefined,
collUserId: undefined, collUserId: undefined,
totalPrice: undefined, totalPrice: undefined,
@ -683,12 +779,12 @@ const submitForm = async () => {
return message.warning('请完善合同甲方授权人信息') return message.warning('请完善合同甲方授权人信息')
} }
if(contractBAuthorizedPersonFormRef.value.getData().length) { // if(contractBAuthorizedPersonFormRef.value.getData().length) {
const contractBAuthorizedPersonPerson = await contractBAuthorizedPersonFormRef.value.validate() // const contractBAuthorizedPersonPerson = await contractBAuthorizedPersonFormRef.value.validate()
if (!contractBAuthorizedPersonPerson) return message.warning('请完善合同乙方授权人信息') // if (!contractBAuthorizedPersonPerson) return message.warning('')
} else { // } else {
return message.warning('请完善合同乙方授权人信息') // return message.warning('')
} // }
formLoading.value = true formLoading.value = true
@ -697,7 +793,7 @@ const submitForm = async () => {
// //
data.contractAAuthorizedCompanys = contractAAuthorizedCompanyFormRef.value.getData() data.contractAAuthorizedCompanys = contractAAuthorizedCompanyFormRef.value.getData()
data.contractAAuthorizedPersons = contractAAuthorizedPersonFormRef.value.getData() data.contractAAuthorizedPersons = contractAAuthorizedPersonFormRef.value.getData()
data.contractBAuthorizedPersons = contractBAuthorizedPersonFormRef.value.getData() // data.contractBAuthorizedPersons = contractBAuthorizedPersonFormRef.value.getData()
if (!formType.value ) { if (!formType.value ) {
await ContractApi.createContract(data) await ContractApi.createContract(data)
message.success(t('common.createSuccess')) message.success(t('common.createSuccess'))
@ -743,8 +839,8 @@ const resetForm = () => {
offlinePrice: undefined, offlinePrice: undefined,
onlinePrice: undefined, onlinePrice: undefined,
ownerUserId: undefined, ownerUserId: undefined,
expanderUserId: undefined, clueDeveloper: undefined,
pricingUserId: undefined, contractor: undefined,
afterSaleUserId: undefined, afterSaleUserId: undefined,
collUserId: undefined, collUserId: undefined,
totalPrice: undefined, totalPrice: undefined,
@ -777,7 +873,7 @@ const handleQuotationChange = async (quotationId: number) => {
formData.value.ownerUserMobile = quotation.ownerUserMobile; formData.value.ownerUserMobile = quotation.ownerUserMobile;
formData.value.ownerUserWechat = quotation.ownerUserWechat; formData.value.ownerUserWechat = quotation.ownerUserWechat;
formData.value.ownerUserEmail = quotation.ownerUserEmail; formData.value.ownerUserEmail = quotation.ownerUserEmail;
formData.value.expanderUserId = quotation.expanderUserId; formData.value.clueDeveloper = quotation.clueDeveloper;
formData.value.signUserId = quotation.signUserId; formData.value.signUserId = quotation.signUserId;
formData.value.signPhoneNumber = quotation.signPhoneNumber; formData.value.signPhoneNumber = quotation.signPhoneNumber;
formData.value.signEmail = quotation.signEmail; formData.value.signEmail = quotation.signEmail;
@ -830,6 +926,11 @@ const onCustomerChange = async (customerId: string) => {
formData.value.socialEmployeeNum = customerRes.socialEmployeeNum; formData.value.socialEmployeeNum = customerRes.socialEmployeeNum;
formData.value.registeredAddress = customerRes.registeredAddress; formData.value.registeredAddress = customerRes.registeredAddress;
formData.value.quotationId = customerRes.quotationId; formData.value.quotationId = customerRes.quotationId;
formData.value.afterSaleUserId = customerRes.maintainer;
formData.value.servicor = customerRes.servicor;
formData.value.clueDeveloper = customerRes.developer;
formData.value.technicalLead = customerRes.technicalLead;
formData.value.settlementLead = customerRes.settlementLead;
await handleQuotationChange(customerRes.quotationId); await handleQuotationChange(customerRes.quotationId);
} catch (err) { } catch (err) {
@ -856,6 +957,25 @@ const onPartnerChange = async (id: string) => {
} }
} }
const changeTime = ()=> {
if(formData.value.startTime && formData.value.contractTerm) {
let year = new Date(formData.value.startTime).getFullYear()
let month = new Date(formData.value.startTime).getMonth() + 1
let day = new Date(formData.value.startTime).getDate()
let addYear = Math.floor(formData.value.contractTerm / 12)
let addMonth = formData.value.contractTerm % 12
let remainMonth = addMonth + month
let lastMonth = remainMonth
if (remainMonth >= 12) {
lastMonth = remainMonth - 12
addYear = addYear + 1
}
let lastYear = addYear + year
formData.value.endTime = lastYear + '-' + lastMonth + '-' + day
}
}
/** 动态获取客户联系人 */ /** 动态获取客户联系人 */
const getContactOptions = computed(() => const getContactOptions = computed(() =>
@ -864,6 +984,8 @@ const getContactOptions = computed(() =>
const route = useRoute(); const route = useRoute();
onMounted(async () => { onMounted(async () => {
formData.value.contractor = useUserStore().getUser.id;
if(!props.changeType) { if(!props.changeType) {
formType.value = props.id || route.query.id formType.value = props.id || route.query.id

View File

@ -31,9 +31,9 @@
</el-table-column> --> </el-table-column> -->
</template> </template>
<template #contractAAuthorizedPersonsauthPersonType> <template #contractAAuthorizedPersonsauthPersonType>
<el-table-column label="授权人类型" min-width="150"> <el-table-column label="授权人类型" min-width="150" prop="authPersonType">
<template #default="{ row, $index }"> <template #default="{ row }">
<el-form-item :prop="`${$index}.authPersonType`" :rules="formRules.authPersonType" class="mb-0px!" v-if="!type"> <!-- <el-form-item :prop="`${$index}.authPersonType`" :rules="formRules.authPersonType" class="mb-0px!" v-if="!type">
<el-select v-model="row.authPersonType" placeholder="请选择授权人类型"> <el-select v-model="row.authPersonType" placeholder="请选择授权人类型">
<el-option <el-option
v-for="dict in getIntDictOptions('auth_person_type')" v-for="dict in getIntDictOptions('auth_person_type')"
@ -41,11 +41,11 @@
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
/> />
</el-select> </el-select> -->
</el-form-item> <!-- </el-form-item> -->
<div v-else> <!-- <div v-else>
{{getName(getIntDictOptions('auth_person_type'), row.authPersonType)}} </div> -->
</div> {{getName(getIntDictOptions(DICT_TYPE.CRM_CONTACT_ROLE_TYPE), row.authPersonType)}}
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@ -206,6 +206,7 @@ const getList = (val: []) => {
val.forEach(item => { val.forEach(item => {
formData.value.push({ formData.value.push({
"customerContactId": item.id, "customerContactId": item.id,
"authPersonType": item.contactRoleType,
"customerName": item.name, "customerName": item.name,
"phoneNumber": item.mobile, "phoneNumber": item.mobile,
"wechat":item. wechat, "wechat":item. wechat,

View File

@ -40,13 +40,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
<template #no> <!-- <template #no>
<el-col :span="8" v-if="formType"> <el-col :span="8" v-if="formType">
<el-form-item label="合同编号" prop="no"> <el-form-item label="合同编号" prop="no">
<el-input v-model="formData.no" disabled placeholder="" /> <el-input v-model="formData.no" disabled placeholder="" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template> -->
<template #quotationId> <template #quotationId>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="报价单编号" prop="quotationId"> <el-form-item label="报价单编号" prop="quotationId">
@ -67,13 +67,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
<template #pricingUserId> <template #contractor>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="方案签约人" prop="pricingUserId"> <el-form-item label="签约人" prop="contractor">
<el-select <el-select
@change="handleQuotationChange" @change="handleQuotationChange"
v-model="formData.pricingUserId" v-model="formData.contractor"
:disabled="formFields.pricingUserId !== 2 || isTrue" :disabled="formFields.contractor !== 2 || isTrue"
placeholder="" placeholder=""
class="w-1/1" class="w-1/1"
> >
@ -307,7 +307,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
<template #ownerUserId> <!-- <template #ownerUserId>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="商务负责人" prop="ownerUserId"> <el-form-item label="商务负责人" prop="ownerUserId">
<el-select <el-select
@ -323,7 +323,7 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<!-- <el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="手机号" prop="mobile"> <el-form-item label="手机号" prop="mobile">
<el-input <el-input
@ -476,7 +476,7 @@
</ContentWrap> </ContentWrap>
</el-col> </el-col>
</template> </template>
<template #settleMethod> <!-- <template #settleMethod>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="财务结算方式" prop="settleMethod"> <el-form-item label="财务结算方式" prop="settleMethod">
<el-radio-group v-model="formData.settleMethod" :disabled="formFields.settleMethod !== 2 || isTrue"> <el-radio-group v-model="formData.settleMethod" :disabled="formFields.settleMethod !== 2 || isTrue">
@ -485,10 +485,10 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template> -->
<template #afterSaleUserId> <template #afterSaleUserId>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="售后维护人" prop="afterSaleUserId"> <el-form-item label="维护人" prop="afterSaleUserId">
<el-select v-model="formData.afterSaleUserId" :disabled="formFields.afterSaleUserId !== 2 || isTrue" placeholder=""> <el-select v-model="formData.afterSaleUserId" :disabled="formFields.afterSaleUserId !== 2 || isTrue" placeholder="">
<el-option <el-option
v-for="dict in userOptions" v-for="dict in userOptions"
@ -500,7 +500,83 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
<template #collUserId> <template #expanderUserId>
<el-col :span="8">
<el-form-item label="拓展人" prop="expanderUserId">
<el-select
class="w-1/1"
placeholder="请选择拓展人"
v-model="formData.expanderUserId"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #servicor>
<el-col :span="8">
<el-form-item label="服务对接人" prop="servicor">
<el-select
class="w-1/1"
placeholder="请选择服务对接人"
v-model="formData.servicor"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #technicalLead>
<el-col :span="8">
<el-form-item label="技术对接人" prop="technicalLead">
<el-select
class="w-1/1"
placeholder="请选择技术对接人"
v-model="formData.technicalLead"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #settlementLead>
<el-col :span="8">
<el-form-item label="结算对接人" prop="settlementLead">
<el-select
class="w-1/1"
placeholder="请选择结算对接人"
v-model="formData.settlementLead"
filterable
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<!-- <template #collUserId>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="协作人" prop="collUserId"> <el-form-item label="协作人" prop="collUserId">
<el-select v-model="formData.collUserId" :disabled="formFields.collUserId !== 2 || isTrue" placeholder=""> <el-select v-model="formData.collUserId" :disabled="formFields.collUserId !== 2 || isTrue" placeholder="">
@ -527,7 +603,7 @@
<el-input v-model="formData.contractAgreement" :disabled="formFields.contractAgreement !== 2 || isTrue" type="textarea" rows="5" placeholder="" /> <el-input v-model="formData.contractAgreement" :disabled="formFields.contractAgreement !== 2 || isTrue" type="textarea" rows="5" placeholder="" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template> -->
<template #other5> <template #other5>
@ -560,14 +636,14 @@
<ContractAAuthorizedPersonForm :type="1" :formFields="formFields" ref="contractAAuthorizedPersonFormRef" :contract-id="formData.id" /> <ContractAAuthorizedPersonForm :type="1" :formFields="formFields" ref="contractAAuthorizedPersonFormRef" :contract-id="formData.id" />
</ContentWrap> </ContentWrap>
</el-col> </el-col>
<ContentWrap style="border: none;font-weight:700"> <!-- <ContentWrap style="border: none;font-weight:700">
合同乙方授权人信息 合同乙方授权人信息
</ContentWrap> </ContentWrap>
<el-col :span="24"> <el-col :span="24">
<ContentWrap> <ContentWrap>
<ContractBAuthorizedPersonForm :type="1" :formFields="formFields" ref="contractBAuthorizedPersonFormRef" :userOptions="userOptions" :contract-id="formData.id" /> <ContractBAuthorizedPersonForm :type="1" :formFields="formFields" ref="contractBAuthorizedPersonFormRef" :userOptions="userOptions" :contract-id="formData.id" />
</ContentWrap> </ContentWrap>
</el-col> </el-col> -->
</template> </template>
</processForm> </processForm>
<!-- 显示在其他页面时的判断type --> <!-- 显示在其他页面时的判断type -->
@ -612,7 +688,7 @@ const formFields = ref({
customerId: 1, customerId: 1,
no: 1, no: 1,
quotationId: 1, quotationId: 1,
pricingUserId: 1, contractor: 1,
creditLimit: 1, creditLimit: 1,
creditMethod: 1, creditMethod: 1,
creditCalcCycle: 1, creditCalcCycle: 1,
@ -645,11 +721,15 @@ const formFields = ref({
penaltyRate: 1, penaltyRate: 1,
latePaymentRate: 1, latePaymentRate: 1,
other4: 1, other4: 1,
settleMethod: 1, // settleMethod: 1,
afterSaleUserId: 1, afterSaleUserId: 1,
collUserId: 1, expanderUserId: 1,
contractBody: 1, servicor: 1,
contractAgreement: 1, technicalLead: 1,
settlementLead: 1,
// collUserId: 1,
// contractBody: 1,
// contractAgreement: 1,
other5: 1, other5: 1,
productsother: 1, productsother: 1,
productsproductName: 1, productsproductName: 1,
@ -722,7 +802,7 @@ const formData = ref({
onlinePrice: undefined, onlinePrice: undefined,
ownerUserId: undefined, ownerUserId: undefined,
expanderUserId: undefined, expanderUserId: undefined,
pricingUserId: undefined, contractor: undefined,
afterSaleUserId: undefined, afterSaleUserId: undefined,
collUserId: undefined, collUserId: undefined,
totalPrice: undefined, totalPrice: undefined,
@ -885,7 +965,7 @@ const resetForm = () => {
onlinePrice: undefined, onlinePrice: undefined,
ownerUserId: undefined, ownerUserId: undefined,
expanderUserId: undefined, expanderUserId: undefined,
pricingUserId: undefined, contractor: undefined,
afterSaleUserId: undefined, afterSaleUserId: undefined,
collUserId: undefined, collUserId: undefined,
totalPrice: undefined, totalPrice: undefined,

View File

@ -58,7 +58,7 @@
<Icon class="mr-5px" icon="ep:plus" /> <Icon class="mr-5px" icon="ep:plus" />
新增 新增
</el-button> </el-button>
<el-button <!-- <el-button
v-hasPermi="['crm:contract:export']" v-hasPermi="['crm:contract:export']"
:loading="exportLoading" :loading="exportLoading"
plain plain
@ -67,18 +67,18 @@
> >
<Icon class="mr-5px" icon="ep:download" /> <Icon class="mr-5px" icon="ep:download" />
导出 导出
</el-button> </el-button> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
</ContentWrap> </ContentWrap>
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<!-- <el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="我负责的" name="1" /> <el-tab-pane label="我负责的" name="1" />
<el-tab-pane label="我参与的" name="2" /> <el-tab-pane label="我参与的" name="2" />
<el-tab-pane label="下属负责的" name="3" /> <el-tab-pane label="下属负责的" name="3" />
</el-tabs> --> </el-tabs>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160"> <el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160">
<template #default="scope"> <template #default="scope">

View File

@ -26,11 +26,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="拓展人" prop="developer"> <el-form-item label="拓展人" prop="clueDeveloper">
<el-select <el-select
class="w-1/1" class="w-1/1"
placeholder="请选择拓展人" placeholder="请选择拓展人"
v-model="formData.developer" v-model="formData.clueDeveloper"
filterable filterable
> >
<el-option <el-option
@ -58,7 +58,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="合作类型" prop="cooperationType"> <el-form-item label="公司类型" prop="cooperationType">
<el-select v-model="formData.cooperationType" filterable placeholder="请选择合作类型" class="w-1/1"> <el-select v-model="formData.cooperationType" filterable placeholder="请选择合作类型" class="w-1/1">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE)"
@ -408,7 +408,7 @@ const formData = ref({
level: undefined, level: undefined,
source: undefined, source: undefined,
remark: undefined, remark: undefined,
developer: undefined, clueDeveloper: undefined,
assist: [], assist: [],
creditNo: undefined, creditNo: undefined,
clueDeveloper: undefined, clueDeveloper: undefined,
@ -422,7 +422,7 @@ const formData = ref({
const formRules = reactive({ const formRules = reactive({
name: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
developer: [{ required: true, message: '商务拓展人不能为空', trigger: 'change' }], clueDeveloper: [{ required: true, message: '拓展人不能为空', trigger: 'change' }],
cooperationType: [{ required: true, message: '合作类型不能为空', trigger: 'change' }], cooperationType: [{ required: true, message: '合作类型不能为空', trigger: 'change' }],
cooperationArea: [{ required: true, message: '合作地区不能为空', trigger: 'change' }], cooperationArea: [{ required: true, message: '合作地区不能为空', trigger: 'change' }],
website: [{ required: true, message: '网站不能为空', trigger: 'change' }], website: [{ required: true, message: '网站不能为空', trigger: 'change' }],
@ -452,7 +452,7 @@ const open = async (type: string, id?: number) => {
// //
if (formType.value === 'create') { if (formType.value === 'create') {
formData.value.ownerUserId = useUserStore().getUser.id formData.value.ownerUserId = useUserStore().getUser.id
formData.value.developer = useUserStore().getUser.id formData.value.clueDeveloper = useUserStore().getUser.id
// formData.value.assist = useUserStore().getUser.id // formData.value.assist = useUserStore().getUser.id
} }
@ -546,7 +546,7 @@ const resetForm = () => {
level: undefined, level: undefined,
source: undefined, source: undefined,
reamark: undefined, reamark: undefined,
developer: undefined, clueDeveloper: undefined,
assist: [], assist: [],
clueDeveloper: undefined, clueDeveloper: undefined,
} }

View File

@ -41,7 +41,7 @@
<!-- <el-descriptions-item label="客户级别"> <!-- <el-descriptions-item label="客户级别">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" /> <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" />
</el-descriptions-item> --> </el-descriptions-item> -->
<el-descriptions-item label="合作类型"><!-- {{ getName(getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE),customer.cooperationType) }} --> <el-descriptions-item label="公司类型"><!-- {{ getName(getIntDictOptions(DICT_TYPE.CRM_COOPERATION_TYPE),customer.cooperationType) }} -->
<dict-tag :type="DICT_TYPE.CRM_COOPERATION_TYPE" :value="customer.cooperationType" /> <dict-tag :type="DICT_TYPE.CRM_COOPERATION_TYPE" :value="customer.cooperationType" />
</el-descriptions-item> </el-descriptions-item>
<!-- <el-descriptions-item label="合作地区">{{ getName(getIntDictOptions(DICT_TYPE.CRM_COOPERATION_AREA),customer.cooperationArea) }}</el-descriptions-item> --> <!-- <el-descriptions-item label="合作地区">{{ getName(getIntDictOptions(DICT_TYPE.CRM_COOPERATION_AREA),customer.cooperationArea) }}</el-descriptions-item> -->

View File

@ -51,7 +51,7 @@
<el-tab-pane label="联系人" lazy name="ContactListRef"> <el-tab-pane label="联系人" lazy name="ContactListRef">
<ContactList ref="ContactListRef" :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" /> <ContactList ref="ContactListRef" :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="团队成员" name="permissionListRef"> <!-- <el-tab-pane label="团队成员" name="permissionListRef">
<PermissionList <PermissionList
ref="permissionListRef" ref="permissionListRef"
:biz-id="customer.id!" :biz-id="customer.id!"
@ -59,7 +59,7 @@
:show-action="!permissionListRef?.isPool || false" :show-action="!permissionListRef?.isPool || false"
@quit-team="close" @quit-team="close"
/> />
</el-tab-pane> </el-tab-pane> -->
<el-tab-pane label="商机" lazy name="BusinessListRef"> <el-tab-pane label="商机" lazy name="BusinessListRef">
<BusinessList ref="BusinessListRef" :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" /> <BusinessList ref="BusinessListRef" :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" />
</el-tab-pane> </el-tab-pane>
@ -230,7 +230,7 @@ const ContractListRef = ref('')
const handleClick = async (val) => { const handleClick = async (val) => {
let name = val.props.name let name = val.props.name
if(!name) return if(!name) return
if (val.props.name) { if (val.props.name) {

View File

@ -150,7 +150,7 @@
{{scope.row.clueDeveloperName || '暂无'}} {{scope.row.clueDeveloperName || '暂无'}}
</template> </template>
</el-table-column> --> </el-table-column> -->
<el-table-column align="center" label="拓展人" prop="developerName" width="120" /> <el-table-column align="center" label="拓展人" prop="clueDeveloperName" width="120" />
<el-table-column align="center" label="签约人" prop="contractorName" width="120"> <el-table-column align="center" label="签约人" prop="contractorName" width="120">
<template #default="scope"> <template #default="scope">
{{scope.row.contractorName || '暂无'}} {{scope.row.contractorName || '暂无'}}

View File

@ -0,0 +1,374 @@
<template>
<ContentWrap class="mt-10px">
<processForm
ref="formRef"
:model="formData"
:rules="formRules"
:fields="formFields"
label-width="120px"
v-loading="formLoading"
>
<template #customerId>
<el-col :span="8">
<el-form-item label="客户名称" prop="customerId">
<SelectComponent :customerList="customerList" :disabled="formFields.customerId !== 2 || isTrue" placeholder="请选择客户名称" v-model="formData.customerId" />
</el-form-item>
</el-col>
</template>
<template #deptId>
<el-col :span="8">
<el-form-item label="所属部门" prop="deptId">
<el-tree-select
v-model="formData.deptId"
:data="deptTree"
:props="defaultProps"
:disabled="formFields.deptId !== 2 || isTrue"
filterable
check-strictly
node-key="id"
placeholder="请选择所属部门"
@change="getSimpleUserList"
/>
</el-form-item>
</el-col>
</template>
<template #contactId>
<el-col :span="8">
<el-form-item label="反馈联系人" prop="contactId">
<el-select
v-model="formData.contactId"
clearable
:disabled="formFields.contactId !== 2 || isTrue"
filterable
lable-key="name"
placeholder="请选择反馈人"
value-key="id"
>
<el-option
v-for="item in userList"
:key="item.id"
:label="item.nickname"
:value="item.id!"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #mobile>
<el-col :span="8">
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="formData.mobile" :disabled="formFields.mobile !== 2 || isTrue" placeholder="请输入联系电话" />
</el-form-item>
</el-col>
</template>
<template #email>
<el-col :span="8">
<el-form-item label="电子邮箱" prop="email">
<el-input v-model="formData.email" :disabled="formFields.email !== 2 || isTrue" placeholder="请输入电子邮箱" />
</el-form-item>
</el-col>
</template>
<template #feedbackType>
<el-col :span="8">
<el-form-item label="反馈类型" prop="feedbackType">
<el-select v-model="formData.feedbackType" :disabled="formFields.feedbackType !== 2 || isTrue" placeholder="请选择反馈类型">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_FEEDBACK_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #feedbackLevel>
<el-col :span="8">
<el-form-item label="反馈级别" prop="feedbackLevel">
<el-select v-model="formData.feedbackLevel" :disabled="formFields.feedbackLevel !== 2 || isTrue" filterable clearable placeholder="请选择反馈级别">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_FEEDBACK_LEVEL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #urgencyLevel>
<el-col :span="8">
<el-form-item label="紧急程度" prop="urgencyLevel">
<el-select v-model="formData.urgencyLevel" :disabled="formFields.urgencyLevel !== 2 || isTrue" filterable clearable placeholder="请选择紧急程度">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_URGENCY_LEVEL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</template>
<template #feedbackTime>
<el-col :span="8">
<el-form-item label="反馈时间" prop="feedbackTime">
<el-date-picker
v-model="formData.feedbackTime"
type="date"
:disabled="formFields.feedbackTime !== 2 || isTrue"
value-format="x"
style="width: 100%"
placeholder="选择反馈时间"
/>
</el-form-item>
</el-col>
</template>
<template #relatedPerson>
<el-col :span="8">
<el-form-item label="当事人用户" prop="relatedPerson">
<el-select
:disabled="formFields.relatedPerson !== 2 || isTrue"
v-model="formData.relatedPerson"
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="customerFeedbackCount">
<el-input v-model="formData.customerFeedbackCount" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入客户累计计数" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="当事人累计计数" prop="relatedPersonFeedbackCount">
<el-input v-model="formData.relatedPersonFeedbackCount" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入当事人累计计数" />
</el-form-item>
</el-col> -->
</template>
<template #feedbackCompanyEntity>
<el-col :span="24">
<el-form-item label="反馈主体" prop="feedbackCompanyEntity">
<el-input type="textarea" :disabled="formFields.feedbackCompanyEntity !== 2 || isTrue" :rows="5" v-model="formData.feedbackCompanyEntity" placeholder="请输入反馈主体" />
</el-form-item>
</el-col>
</template>
<template #feedbackContent>
<el-col :span="24">
<el-form-item label="反馈内容" prop="feedbackContent">
<el-input type="textarea" :disabled="formFields.feedbackContent !== 2 || isTrue" :rows="5" v-model="formData.feedbackContent" placeholder="请输入反馈主体" />
</el-form-item>
</el-col>
</template>
<template #attachment>
<el-col :span="24">
<el-form-item label="附件" prop="attachment">
<UploadFile v-model="formData.attachment" :disabled="formFields.attachment !== 2 || isTrue" :limit="1" :fileType="['doc','docx']"/>
</el-form-item>
</el-col>
</template>
</processForm>
<!-- <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 { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CustomerFeedbackApi, CustomerFeedbackVO } from '@/api/crm/feedback'
import * as CustomerApi from '@/api/crm/customer'
import { defaultProps, handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept'
import * as UserApi from '@/api/system/user'
import { getLimitForm } from '@/api/bpm/form'
/** 客户反馈 表单 */
defineOptions({ name: 'CustomerFeedbackForm' })
const { t } = useI18n() //
const message = useMessage() //
const { proxy }: any = getCurrentInstance();
const isTrue = ref(false)
const userOptions = ref<UserApi.UserVO[]>([]) //
const userList = ref([]) //
const deptTree = ref<Tree[]>([]) //
const customerList = ref([]) //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formFields = ref({
customerId: 1,
deptId: 1,
contactId: 1,
mobile: 1,
email: 1,
feedbackType: 1,
feedbackLevel: 1,
urgencyLevel: 1,
feedbackTime: 1,
relatedPerson: 1,
feedbackCompanyEntity: 1,
feedbackContent: 1,
attachment: 1,
})
const formData = ref({
id: undefined,
customerId: undefined,
contactId: undefined,
mobile: undefined,
email: undefined,
feedbackType: undefined,
feedbackLevel: undefined,
urgencyLevel: undefined,
feedbackTime: undefined,
relatedPerson: undefined,
deptId: undefined,
customerFeedbackCount: undefined,
relatedPersonFeedbackCount: undefined,
feedbackCompanyEntity: undefined,
feedbackContent: undefined,
attachment: undefined,
})
const formRules = reactive({
customerId: [{ required: true, message: '客户ID不能为空', trigger: 'blur' }],
contactId: [{ required: true, message: '反馈联系人ID不能为空', trigger: 'blur' }],
mobile: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }],
feedbackType: [{ required: true, message: '反馈类型不能为空', trigger: 'change' }],
feedbackLevel: [{ required: true, message: '反馈级别不能为空', trigger: 'blur' }],
urgencyLevel: [{ required: true, message: '紧急程度不能为空', trigger: 'blur' }],
feedbackTime: [{ required: true, message: '反馈时间不能为空', trigger: 'blur' }],
feedbackCompanyEntity: [{ required: true, message: '反馈主体不能为空', trigger: 'blur' }],
feedbackContent: [{ required: true, message: '反馈内容不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (id?: number) => {
//
if (id) {
formLoading.value = true
try {
formData.value = await CustomerFeedbackApi.getCustomerFeedback(id)
getSimpleUserList(formData.value.deptId)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 选择部门后,查询用户列表 */
const getSimpleUserList = async (val) => {
const feedbackDeptId = val;
if (feedbackDeptId) {
//
userList.value = await UserApi.getSimpleUserList(feedbackDeptId);
} else {
userList.value = [];
}
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as CustomerFeedbackVO
if (!formType.value) {
await CustomerFeedbackApi.createCustomerFeedback(data)
message.success(t('common.createSuccess'))
} else {
await CustomerFeedbackApi.updateCustomerFeedback(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
goBack()
emit('success')
} finally {
formLoading.value = false
}
}
const goBack = ()=> {
proxy.$router.go(-1)
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
customerId: undefined,
contactId: undefined,
mobile: undefined,
email: undefined,
feedbackType: undefined,
feedbackLevel: undefined,
urgencyLevel: undefined,
feedbackTime: undefined,
relatedPerson: undefined,
deptId: undefined,
customerFeedbackCount: undefined,
relatedPersonFeedbackCount: undefined,
feedbackCompanyEntity: undefined,
feedbackContent: undefined,
attachment: undefined,
}
formRef.value?.resetFields()
}
//
const getLimit = async () => {
let data = {
modelNodeId: route.query.taskDefinitionKey,
processDefinitionId: route.query.processDefinitionId
}
let field = await getLimitForm(data)
for(let key in formFields.value) {
if(formFields.value.hasOwnProperty(key)) {
field.fields.map( v => {
let newKey = v.field
if(v.field.indexOf('.') > -1) {
newKey = v.field.split('.')[0] + v.field.split('.')[1]
}
if(newKey === key) formFields.value[key] = v.permission
})
}
}
}
const route = useRoute();
onMounted(async() => {
isTrue.value = !!route.query.isDetail
formType.value = route.query.id
if (formType.value) await open(formType.value)
if(route.query.processDefinitionId) getLimit()
//
customerList.value = await CustomerApi.getSelfCustomerSimpleList()
const deptData = await DeptApi.getSimpleDeptList()
deptTree.value = handleTree(deptData) //
//
userOptions.value = await UserApi.getSimpleUserList()
})
</script>

View File

@ -0,0 +1,314 @@
<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="customerId">
<SelectComponent :customerList="customerList" placeholder="请选择客户名称" v-model="formData.customerId" />
</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="请选择所属部门"
@change="getSimpleUserList"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="反馈联系人" prop="contactId">
<el-select
v-model="formData.contactId"
clearable
filterable
lable-key="name"
placeholder="请选择反馈人"
value-key="id"
>
<el-option
v-for="item in userList"
: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="mobile">
<el-input v-model="formData.mobile" placeholder="请输入联系电话" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电子邮箱" prop="email">
<el-input v-model="formData.email" placeholder="请输入电子邮箱" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="反馈类型" prop="feedbackType">
<el-select v-model="formData.feedbackType" placeholder="请选择反馈类型">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_FEEDBACK_TYPE)"
: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="feedbackLevel">
<el-select v-model="formData.feedbackLevel" filterable clearable placeholder="请选择反馈级别">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_FEEDBACK_LEVEL)"
: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="urgencyLevel">
<el-select v-model="formData.urgencyLevel" filterable clearable placeholder="请选择紧急程度">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_URGENCY_LEVEL)"
: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="feedbackTime">
<el-date-picker
v-model="formData.feedbackTime"
type="date"
value-format="x"
style="width: 100%"
placeholder="选择反馈时间"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="当事人用户ID" prop="relatedPerson">
<el-select
v-model="formData.relatedPerson"
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="customerFeedbackCount">
<el-input v-model="formData.customerFeedbackCount" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入客户累计计数" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="当事人累计计数" prop="relatedPersonFeedbackCount">
<el-input v-model="formData.relatedPersonFeedbackCount" oninput = "value=value.replace(/[^\d]/g,'')" placeholder="请输入当事人累计计数" />
</el-form-item>
</el-col> -->
<el-col :span="24">
<el-form-item label="反馈主体" prop="feedbackCompanyEntity">
<el-input type="textarea" :rows="5" v-model="formData.feedbackCompanyEntity" placeholder="请输入反馈主体" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="反馈内容" prop="feedbackContent">
<el-input type="textarea" :rows="5" v-model="formData.feedbackContent" placeholder="请输入反馈主体" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="附件" prop="attachment">
<UploadFile v-model="formData.attachment" :limit="1" :fileType="['doc','docx']"/>
</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 { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CustomerFeedbackApi, CustomerFeedbackVO } from '@/api/crm/feedback'
import * as CustomerApi from '@/api/crm/customer'
import { defaultProps, handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept'
import * as UserApi from '@/api/system/user'
/** 客户反馈 表单 */
defineOptions({ name: 'CustomerFeedbackForm' })
const { t } = useI18n() //
const message = useMessage() //
const { proxy }: any = getCurrentInstance();
const userOptions = ref<UserApi.UserVO[]>([]) //
const userList = ref([]) //
const deptTree = ref<Tree[]>([]) //
const customerList = ref([]) //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
customerId: undefined,
contactId: undefined,
mobile: undefined,
email: undefined,
feedbackType: undefined,
feedbackLevel: undefined,
urgencyLevel: undefined,
feedbackTime: undefined,
relatedPerson: undefined,
deptId: undefined,
customerFeedbackCount: undefined,
relatedPersonFeedbackCount: undefined,
feedbackCompanyEntity: undefined,
feedbackContent: undefined,
attachment: undefined,
})
const formRules = reactive({
customerId: [{ required: true, message: '客户ID不能为空', trigger: 'blur' }],
contactId: [{ required: true, message: '反馈联系人ID不能为空', trigger: 'blur' }],
mobile: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }],
feedbackType: [{ required: true, message: '反馈类型不能为空', trigger: 'change' }],
feedbackLevel: [{ required: true, message: '反馈级别不能为空', trigger: 'blur' }],
urgencyLevel: [{ required: true, message: '紧急程度不能为空', trigger: 'blur' }],
feedbackTime: [{ required: true, message: '反馈时间不能为空', trigger: 'blur' }],
feedbackCompanyEntity: [{ required: true, message: '反馈主体不能为空', trigger: 'blur' }],
feedbackContent: [{ required: true, message: '反馈内容不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (id?: number) => {
//
if (id) {
formLoading.value = true
try {
formData.value = await CustomerFeedbackApi.getCustomerFeedback(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 选择部门后,查询用户列表 */
const getSimpleUserList = async (val) => {
const feedbackDeptId = val;
if (feedbackDeptId) {
//
userList.value = await UserApi.getSimpleUserList(feedbackDeptId);
} else {
userList.value = [];
}
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as CustomerFeedbackVO
if (!formType.value) {
await CustomerFeedbackApi.createCustomerFeedback(data)
message.success(t('common.createSuccess'))
} else {
await CustomerFeedbackApi.updateCustomerFeedback(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
goBack()
emit('success')
} finally {
formLoading.value = false
}
}
const goBack = ()=> {
proxy.$router.go(-1)
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
customerId: undefined,
contactId: undefined,
mobile: undefined,
email: undefined,
feedbackType: undefined,
feedbackLevel: undefined,
urgencyLevel: undefined,
feedbackTime: undefined,
relatedPerson: undefined,
deptId: undefined,
customerFeedbackCount: undefined,
relatedPersonFeedbackCount: undefined,
feedbackCompanyEntity: undefined,
feedbackContent: undefined,
attachment: undefined,
}
formRef.value?.resetFields()
}
const route = useRoute();
onMounted(async() => {
formType.value = route.query.id
if (formType.value) await open(formType.value)
//
customerList.value = await CustomerApi.getSelfCustomerSimpleList()
const deptData = await DeptApi.getSimpleDeptList()
deptTree.value = handleTree(deptData) //
//
userOptions.value = await UserApi.getSimpleUserList()
})
</script>

View File

@ -0,0 +1,313 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="客户名称" prop="customerName">
<el-input
v-model="queryParams.customerName"
placeholder="请输入客户名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="反馈级别" prop="feedbackLevel">
<el-select v-model="queryParams.feedbackLevel" filterable clearable placeholder="请输入反馈级别" class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_FEEDBACK_LEVEL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="紧急程度" prop="urgencyLevel">
<el-select v-model="queryParams.urgencyLevel" filterable clearable placeholder="请输入反馈级别" class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_URGENCY_LEVEL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openFormAdd('create')"
v-hasPermi="['crm:customer-feedback:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['crm:customer-feedback:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="客户名称" align="center" prop="customerId" />
<el-table-column label="反馈联系人" align="center" prop="contactId" />
<el-table-column label="联系电话" align="center" prop="mobile" />
<el-table-column label="电子邮箱" align="center" prop="email" />
<el-table-column label="反馈类型" align="center" prop="feedbackType">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_FEEDBACK_TYPE" :value="scope.row.feedbackType" />
</template>
</el-table-column>
<el-table-column label="反馈级别" align="center" prop="feedbackLevel">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_FEEDBACK_LEVEL" :value="scope.row.feedbackLevel" />
</template>
</el-table-column>
<el-table-column label="紧急程度" align="center" prop="urgencyLevel">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_URGENCY_LEVEL" :value="scope.row.urgencyLevel" />
</template>
</el-table-column>
<el-table-column
label="反馈时间"
align="center"
prop="feedbackTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="当事人" align="center" prop="relatedPerson" />
<el-table-column label="所属部门" align="center" prop="deptId" />
<el-table-column label="客户累计计数" align="center" prop="customerFeedbackCount" />
<el-table-column label="当事人累计计数" align="center" prop="relatedPersonFeedbackCount" />
<el-table-column label="反馈主体" align="center" prop="feedbackCompanyEntity" />
<el-table-column label="反馈内容" align="center" prop="feedbackContent" />
<el-table-column label="附件" align="center" prop="attachment">
<template #default="scope">
<el-link
v-if="scope.row.attachment"
:underline="false"
type="primary"
@click="previewFile(scope.row.attachment)"
>
预览
</el-link>
<span v-else></span>
</template>
</el-table-column>
<!-- <el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/> -->
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<!-- <el-button
link
type="primary"
@click="openFormEdit(scope.row)"
v-hasPermi="['crm:customer-feedback:update']"
>
编辑
</el-button> -->
<el-button
v-hasPermi="['crm:customer-feedback:query']"
link
type="primary"
@click="openDetail(scope.row)"
>
详情
</el-button>
<el-button
v-if="scope.row.auditStatus !== 0"
link
v-hasPermi="['crm:customer-feedback:query']"
type="primary"
@click="handleProcessDetail(scope.row)"
>
进度
</el-button>
<!-- <el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['crm:customer-feedback:delete']"
>
删除
</el-button> -->
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<!-- <CustomerFeedbackForm ref="formRef" @success="getList" /> -->
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { CustomerFeedbackApi, CustomerFeedbackVO } from '@/api/crm/feedback'
import CustomerFeedbackForm from './CustomerFeedbackForm.vue'
/** 客户反馈 列表 */
defineOptions({ name: 'CustomerFeedback' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<CustomerFeedbackVO[]>([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
customerId: undefined,
contactId: undefined,
mobile: undefined,
email: undefined,
feedbackType: undefined,
feedbackLevel: undefined,
urgencyLevel: undefined,
feedbackTime: [],
relatedPerson: undefined,
deptId: undefined,
customerFeedbackCount: undefined,
relatedPersonFeedbackCount: undefined,
feedbackCompanyEntity: undefined,
feedbackContent: undefined,
attachment: undefined,
createTime: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await CustomerFeedbackApi.getCustomerFeedbackPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
//
const previewFile = (fileUrls) => {
// // fileUrls URL
if (!fileUrls) {
message.error('没有附件');
return;
}
//
const fileExtension = fileUrls.split('.').pop().toLowerCase();
router.push({
name: 'FileTemplatePreview',
query: {
src: encodeURIComponent(fileUrls),
type: fileExtension
}
})
}
/** 添加/修改操作 */
const formRef = ref()
// const openForm = (type: string, id?: number) => {
// formRef.value.open(type, id)
// }
const router = useRouter() //
const openFormAdd = () => {
router.push({ name: 'CustomerFeedbackCreate' })
}
const openFormEdit = (row: Object) => {
router.push({ name: 'CustomerFeedbackEdit', query: { id: row.id} })
}
const openDetail = (row: Object) => {
router.push({ name: 'CustomerFeedbackDetail', query: { id: row.id } })
}
/** 查看审批 */
const handleProcessDetail = (row) => {
router.push({ name: 'BpmProcessInstanceDetail', query: { id: row.processInstanceId } })
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await CustomerFeedbackApi.deleteCustomerFeedback(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await CustomerFeedbackApi.exportCustomerFeedback(queryParams)
download.excel(data, '客户反馈.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
onActivated(()=>{
getList()
})
</script>

View File

@ -114,7 +114,7 @@
</el-col> --> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="被告记录" prop="defendantRecord"> <el-form-item label="被告记录" prop="defendantRecord">
<el-radio-group v-model="formData.defendantRecord"> <el-radio-group v-model="formData.defendantRecord" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -122,7 +122,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="经营异常" prop="abnormalService"> <el-form-item label="经营异常" prop="abnormalService">
<el-radio-group v-model="formData.abnormalService"> <el-radio-group v-model="formData.abnormalService" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -130,7 +130,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="股权出质" prop="equityPledge"> <el-form-item label="股权出质" prop="equityPledge">
<el-radio-group v-model="formData.equityPledge"> <el-radio-group v-model="formData.equityPledge" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -138,7 +138,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="失信记录" prop="dishonestyRecord"> <el-form-item label="失信记录" prop="dishonestyRecord">
<el-radio-group v-model="formData.dishonestyRecord"> <el-radio-group v-model="formData.dishonestyRecord" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -146,7 +146,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="融资记录" prop="financeRecord"> <el-form-item label="融资记录" prop="financeRecord">
<el-radio-group v-model="formData.financeRecord"> <el-radio-group v-model="formData.financeRecord" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -154,7 +154,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="被执行记录" prop="judgmentRecord"> <el-form-item label="被执行记录" prop="judgmentRecord">
<el-radio-group v-model="formData.judgmentRecord"> <el-radio-group v-model="formData.judgmentRecord" disabled>
<el-radio :label="1"></el-radio> <el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio> <el-radio :label="0"></el-radio>
</el-radio-group> </el-radio-group>
@ -168,7 +168,7 @@
<el-form-item label="合作类型" prop="partnerType"> <el-form-item label="合作类型" prop="partnerType">
<el-select v-model="formData.partnerType" clearable placeholder="请选择合作类型"> <el-select v-model="formData.partnerType" clearable placeholder="请选择合作类型">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PARTNER_TYPE)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PARTNER_TYPE1)"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
:value="dict.value" :value="dict.value"
@ -338,8 +338,22 @@
</el-select> --> </el-select> -->
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<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="quotationTimes">
<el-input v-model="formData.quotationTimes" disabled placeholder="请输入报价次数" />
</el-form-item>
</el-col>
<!-- <el-col :span="8">
<el-form-item label="票据模板" prop="invoiceTemplateId"> <el-form-item label="票据模板" prop="invoiceTemplateId">
<el-select v-model="formData.invoiceTemplateId" :disabled="!formData.businessId" @change="changeTemplate" placeholder="请选择票据模板"> <el-select v-model="formData.invoiceTemplateId" :disabled="!formData.businessId" @change="changeTemplate" placeholder="请选择票据模板">
<el-option <el-option
@ -350,22 +364,14 @@
/> />
</el-select> </el-select>
</el-form-item> </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" placeholder="请输入授信额度" />
</el-form-item>
</el-col> --> </el-col> -->
</el-row> <el-col :span="24">
<el-row> <ContentWrap style="border: none; font-weight: 700">需求信息</ContentWrap>
<el-col :span="8"> </el-col>
<el-col :span="8">
<el-form-item label="服务费收取方式" prop="serviceFeeCollectionMethodId"> <el-form-item label="服务费收取方式" prop="serviceFeeCollectionMethodId">
<el-select v-model="formData.serviceFeeCollectionMethodId" @change="changeQuotationTimes" placeholder="请选择服务费收取方式"> <el-select v-model="formData.serviceFeeCollectionMethodId" @change="changeQuotation" placeholder="请选择服务费收取方式">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_COLLECTION_METHOD)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_COLLECTION_METHOD)"
:key="dict.value" :key="dict.value"
@ -375,15 +381,32 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8" v-if="formData.serviceFeeCollectionMethodId == 3">
<el-form-item label="基础服务费合计" prop="onlinePrice"> <el-form-item label="保险类型" prop="insuranceId">
<el-input <el-select v-model="formData.insuranceId" @change="changeInsuranceId" placeholder="请选择保险类型">
disabled <el-option
v-model="formData.onlinePrice" v-for="dict in insuranceList"
:formatter="erpPriceInputFormatter" :key="dict.id"
/> :label="dict.productDetail"
:value="dict.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="toop">
{{remark}}
<!-- <el-form-item label="" prop="platformId">
</el-form-item> -->
</el-col>
<!-- <el-col :span="8">
<el-form-item label="授信额度" prop="creditLimit">
<el-input v-model="formData.creditLimit" placeholder="请输入授信额度" />
</el-form-item>
</el-col> -->
</el-row>
<!-- <el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="线下总金额" prop="offlinePrice"> <el-form-item label="线下总金额" prop="offlinePrice">
<el-input <el-input
@ -393,24 +416,15 @@
/> />
</el-form-item> </el-form-item>
</el-col> --> </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> </el-form>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<el-tabs v-model="subTabsName" @tab-Click="handleClick"> <el-tabs v-model="subTabsName" @tab-Click="handleClick">
<el-tab-pane label="报价产品关联" name="quotationProduct"> <el-tab-pane label="报价产品关联" name="quotationProduct">
<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" /> <QuotationProductForm ref="quotationProductFormRef" :formFields="formFields" :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>
<el-tab-pane label="营收分析" name="RevenueAnalysis"> <el-tab-pane label="营收分析" name="RevenueAnalysis">
<RevenueAnalysis ref="RevenueAnalysisFormRef" :quotation-id="formData.id" :products="formData.products" /> <RevenueAnalysis ref="RevenueAnalysisFormRef" :formFields="formFields" :quotation-id="formData.id" :products="formData.products" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<div style="text-align: right"> <div style="text-align: right">
@ -440,6 +454,11 @@ defineOptions({ name: 'QuotationForm' })
const props = defineProps({ const props = defineProps({
id: propTypes.number.def(undefined), id: propTypes.number.def(undefined),
}) })
const serviceDesc = ref({
1:'按单项产品的订单量(机票/张,酒店/间夜,火车票/张、用车/单)分别收取服务费',
2: '按订单总金额乘以比例收取服务费用',
3: ''
})
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
const customerList = ref([]) // const customerList = ref([]) //
@ -450,8 +469,8 @@ const deptTree = ref() // 部门树形结构
const deptList = ref() // const deptList = ref() //
const orgList = ref([]) const orgList = ref([])
const handleType = ref('') const handleType = ref('')
const serverMethodList = ref([]) const insuranceList = ref([])
const remark = ref('')
const invoiceTemplateList = ref([]) const invoiceTemplateList = ref([])
const { proxy }: any = getCurrentInstance(); const { proxy }: any = getCurrentInstance();
@ -459,6 +478,69 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // const dialogTitle = ref('') //
const formLoading = ref(false) // 12 const formLoading = ref(false) // 12
const formType = ref('') // create - update - const formType = ref('') // create - update -
const formFields = ref({ //,
businessId: 1,
no: 1,
other: 1,
creditAmount: 1,
creditLimitNum: 1,
creditLimit: 1,
customerId: 1,
cooperationType: 1,
regType: 1,
financingInfo: 1,
actualCapital: 1,
socialEmployeeNum: 1,
startDate: 1,
defendantRecord: 1,
abnormalService: 1,
equityPledge: 1,
dishonestyRecord: 1,
financeRecord: 1,
judgmentRecord: 1,
other1: 1,
partnerCompanyId: 1,
creditCode: 1,
bankName: 1,
bankAccount: 1,
legalRepresentative: 1,
deptId: 1,
ownerUserId: 1,
pricingUserId: 1,
paymentTerm: 1,
creditMethod: 1,
creditCalcCycle: 1,
invoiceTemplateId: 1,
quotationTimes: 1,
creditLimit1: 1,
serviceFeeCollectionMethodId: 1,
onlinePrice: 1,
totalPrice: 1,
productsother: 1,
productscategory: 1,
productsdetailType: 1,
productsproductUnit: 1,
productsbasicServiceFee: 1,
productsadvancePaymentServiceFee: 1,
productsbookingPaymentServiceFee: 1,
productsbillSortingServiceFee: 1,
productstotalServiceFee: 1,
productsproductInvoice: 1,
productsproductInvoiceItem: 1,
productsserviceInvoice: 1,
productsserviceInvoiceItem: 1,
quotationProductscategory: 1,
quotationProductsdetailType: 1,
quotationProductsrevenueAnalysisVOsalesVolume: 1,
quotationProductsrevenueAnalysisVOtotalOrderVolume: 1,
quotationProductsrevenueAnalysisVOtotalIncome: 1,
quotationProductsrevenueAnalysisVOincomeInterestRate: 1,
quotationProductsrevenueAnalysisVOdeductibleCost: 1,
quotationProductsrevenueAnalysisVOprofit: 1,
quotationProductsrevenueAnalysisVOprofitRate: 1,
quotationProductsrevenueAnalysisVOprofitSharingRatio: 1,
quotationProductsrevenueAnalysisVOprofitSharingIncome: 1,
})
const formData = ref({ const formData = ref({
no: undefined, no: undefined,
customerId: undefined, customerId: undefined,
@ -529,6 +611,7 @@ const formRules = reactive({
creditCalcCycle: [{ required: true, message: '授信计算周期不能为空', trigger: 'change' }], creditCalcCycle: [{ required: true, message: '授信计算周期不能为空', trigger: 'change' }],
quotationTimes: [{ required: true, message: '第几次报价不能为空', trigger: 'change' }], quotationTimes: [{ required: true, message: '第几次报价不能为空', trigger: 'change' }],
serviceFeeCollectionMethodId: [{ required: true, message: '服务费收取方式不能为空', trigger: 'change' }], serviceFeeCollectionMethodId: [{ required: true, message: '服务费收取方式不能为空', trigger: 'change' }],
insuranceId: [{ required: true, message: '保险类型不能为空', trigger: 'change' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
@ -567,7 +650,24 @@ const setSuccess = (val) => {
formData.value.products = val formData.value.products = val
} }
const changeQuotationTimes = async() => { const changeInsuranceId = (val) => {
let arr = insuranceList.value.filter(v => v.id === val)
remark.value = (arr.length && arr[0]['describes']) ? '注:' + arr[0]['describes'] : ''
}
const changeQuotation = (val) => {
if(serviceDesc.value[val]) {
remark.value = '注:' + serviceDesc.value[val]
} else {
remark.value = ''
}
formData.value.insuranceId = ''
changeQuotationTimes(val)
}
const changeQuotationTimes = async(val) => {
if(formData.value.serviceFeeCollectionMethodId && formData.value.businessId) { if(formData.value.serviceFeeCollectionMethodId && formData.value.businessId) {
newProducts.value = [] newProducts.value = []
formData.value.products.forEach( item => { formData.value.products.forEach( item => {
@ -833,8 +933,8 @@ onMounted(async () => {
// //
deptTree.value = handleTree(await DeptApi.getSimpleDeptList()) deptTree.value = handleTree(await DeptApi.getSimpleDeptList())
// //
let serverList = await QuotationApi.getServerMethodList({pageNo: 1, pageSize: 1000}) insuranceList.value = await QuotationApi.getInsuranceList()
serverMethodList.value = serverList.list
const org = await ContractApi.getOrg({ const org = await ContractApi.getOrg({
pageNo: 1, pageNo: 1,
pageSize: 1000 pageSize: 1000
@ -842,3 +942,12 @@ onMounted(async () => {
orgList.value = org.list orgList.value = org.list
}); });
</script> </script>
<style scoped>
.toop {
line-height: 32px;
font-size: 12px;
font-weight: 500;
padding-left: 10px;
}
</style>

View File

@ -84,9 +84,9 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品票据" min-width="150"> <el-table-column label="产品票据" align="center" min-width="150">
<template #default="{ row, $index }"> <template #default>
<el-form-item :prop="`${$index}.productInvoice`" :rules="formRules.productInvoice" class="mb-0px!"> <!-- <el-form-item :prop="`${$index}.productInvoice`" :rules="formRules.productInvoice" class="mb-0px!">
<el-select v-model="row.productInvoice" placeholder="请选择状态" clearable class="!w-240px"> <el-select v-model="row.productInvoice" placeholder="请选择状态" clearable class="!w-240px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_INVOICE)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_INVOICE)"
@ -95,12 +95,13 @@
:value="dict.value" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_INVOICE" :value="1" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品开具项目" min-width="220"> <el-table-column label="产品开具项目" align="center" min-width="220">
<template #default="{ row, $index }"> <template #default>
<el-form-item :prop="`${$index}.productInvoiceItem`" :rules="formRules.productInvoiceItem" class="mb-0px!"> <!-- <el-form-item :prop="`${$index}.productInvoiceItem`" :rules="formRules.productInvoiceItem" class="mb-0px!">
<el-select v-model="row.productInvoiceItem" placeholder="请选择状态" clearable class="!w-240px"> <el-select v-model="row.productInvoiceItem" placeholder="请选择状态" clearable class="!w-240px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_INVOICE_ITEMS)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_INVOICE_ITEMS)"
@ -109,12 +110,13 @@
:value="dict.value" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_INVOICE_ITEMS" :value="1" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="服务费票据" min-width="150"> <el-table-column label="服务费票据" align="center" min-width="150">
<template #default="{ row, $index }"> <template #default>
<el-form-item :prop="`${$index}.serviceInvoice`" :rules="formRules.serviceInvoice" class="mb-0px!"> <!-- <el-form-item :prop="`${$index}.serviceInvoice`" :rules="formRules.serviceInvoice" class="mb-0px!">
<el-select v-model="row.serviceInvoice" placeholder="请选择状态" clearable class="!w-240px"> <el-select v-model="row.serviceInvoice" placeholder="请选择状态" clearable class="!w-240px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_INVOICE)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_INVOICE)"
@ -123,12 +125,13 @@
:value="dict.value" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<dict-tag :type="DICT_TYPE.CRM_SERVICE_FEE_INVOICE" :value="1" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="服务开具项目" min-width="240"> <el-table-column label="服务开具项目" align="center" min-width="240">
<template #default="{ row, $index }"> <template #default>
<el-form-item :prop="`${$index}.serviceInvoiceItem`" :rules="formRules.serviceInvoiceItem" class="mb-0px!"> <!-- <el-form-item :prop="`${$index}.serviceInvoiceItem`" :rules="formRules.serviceInvoiceItem" class="mb-0px!">
<el-select v-model="row.serviceInvoiceItem" placeholder="请选择状态" clearable class="!w-240px"> <el-select v-model="row.serviceInvoiceItem" placeholder="请选择状态" clearable class="!w-240px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_INVOICE_ITEMS)" v-for="dict in getIntDictOptions(DICT_TYPE.CRM_SERVICE_FEE_INVOICE_ITEMS)"
@ -137,7 +140,8 @@
:value="dict.value" :value="dict.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<dict-tag :type="DICT_TYPE.CRM_SERVICE_FEE_INVOICE_ITEMS" :value="1" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column align="center" fixed="right" label="操作" width="60"> <!-- <el-table-column align="center" fixed="right" label="操作" width="60">
@ -174,8 +178,8 @@ const formRules = reactive({
productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }], productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
category: [{ required: true, message: '产品类型不能为空', trigger: 'blur' }], category: [{ required: true, message: '产品类型不能为空', trigger: 'blur' }],
detailType: [{ required: true, message: '产品明细类型不能为空', trigger: 'blur' }], detailType: [{ required: true, message: '产品明细类型不能为空', trigger: 'blur' }],
productUnit: [{ required: true, message: '产品单位不能为空', trigger: 'blur' }], // productUnit: [{ required: true, message: '', trigger: 'blur' }],
basicServiceFee: [{ required: true, message: '基础服务费不能为空', trigger: 'blur' }], // basicServiceFee: [{ required: true, message: '', trigger: 'blur' }],
// offlinePrice: [{ 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' }], productInvoiceItem: [{ required: true, message: '产品开具项目不能为空', trigger: 'blur' }],

View File

@ -36,6 +36,36 @@
/> />
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
<el-form-item label="维护人" prop="expandingUserId">
<el-select
v-model="queryParams.expandingUserId"
placeholder="请选择维护人"
clearable
class="!w-240px"
>
<el-option
v-for="dict in userOptions"
:key="dict.id"
:label="dict.nickname"
:value="dict.id"
/>
</el-select>
</el-form-item>
<el-form-item label="扩展人" prop="expandingUserId">
<el-select
v-model="queryParams.expandingUserId"
placeholder="请选择扩展人"
clearable
class="!w-240px"
>
<el-option
v-for="dict in userOptions"
:key="dict.id"
:label="dict.nickname"
:value="dict.id"
/>
</el-select>
</el-form-item>
<el-form-item label="客户确认状态" prop="confirmStatus"> <el-form-item label="客户确认状态" prop="confirmStatus">
<el-select <el-select
v-model="queryParams.confirmStatus" v-model="queryParams.confirmStatus"
@ -88,11 +118,11 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<!-- <el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="我负责的" name="1" /> <el-tab-pane label="我负责的" name="1" />
<el-tab-pane label="我参与的" name="2" /> <el-tab-pane label="我参与的" name="2" />
<el-tab-pane label="下属负责的" name="3" /> <el-tab-pane label="下属负责的" name="3" />
</el-tabs> --> </el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="客户名称" align="center" prop="customerId" width="250"> <el-table-column label="客户名称" align="center" prop="customerId" width="250">
<template #default="scope"> <template #default="scope">
@ -163,10 +193,33 @@
label="创建时间" label="创建时间"
align="center" align="center"
prop="createTime" prop="createTime"
:formatter="dateFormatter"
width="180px" width="180px"
/> >
<el-table-column label="操作" align="center" fixed="right" min-width="180px"> {{ moment(createTime).format('YYYY-MM-DD')}}
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" min-width="180px" v-if="activeName == 2 || activeName == 3">
<template #default="scope">
<div style="display:flex">
<el-button
link
type="primary"
@click="openFormDetail(scope.row)"
>
详情
</el-button>
<el-button
link
type="primary"
@click="handleProcessDetail(scope.row)"
v-hasPermi="['crm:customer-suggestion:query']"
v-if="scope.row.auditStatus != 0"
>
进度
</el-button>
</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" min-width="180px" v-if="activeName == 1">
<template #default="scope"> <template #default="scope">
<div style="display:flex"> <div style="display:flex">
<el-button <el-button
@ -285,6 +338,7 @@ import * as UserApi from '@/api/system/user'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import { TabsPaneContext } from 'element-plus' import { TabsPaneContext } from 'element-plus'
import { checkPermi } from '@/utils/permission' import { checkPermi } from '@/utils/permission'
import moment from 'moment';
// //
/** CRM 方案报价 列表 */ /** CRM 方案报价 列表 */

View File

@ -132,6 +132,7 @@ const formRules = reactive<FormRules>({
nickname: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }], nickname: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }], password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
postIds: [{ required: true, message: '岗位不能为空', trigger: 'blur' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'blur' }],
deptId: [{ required: true, message: '归属部门不能为空', trigger: 'change' }],
email: [ email: [
{ {
type: 'email', type: 'email',