feat(crm/customerInfo): 添加客户信息出差交流记录功能

dev
Yangk 6 days ago
parent 75af8f63c7
commit e86eddc031

@ -180,6 +180,19 @@ export const constantRoutes: RouteRecordRaw[] = [
meta: { title: '项目预算申请', activeMenu: '/erp/budgetInfo' } meta: { title: '项目预算申请', activeMenu: '/erp/budgetInfo' }
} }
] ]
},
{
path: '/customer',
component: Layout,
hidden: true,
children: [
{
path: 'tripHistory',
component: () => import('@/views/oa/crm/customerInfo/tripHistory.vue'),
name: 'CustomerTripHistory',
meta: { title: '客户出差交流记录', activeMenu: '/oa/crm/customerInfo' }
}
]
} }
]; ];

@ -25,12 +25,12 @@
<el-form-item label="出差地点" prop="tripLocation"> <el-form-item label="出差地点" prop="tripLocation">
<el-input v-model="queryParams.tripLocation" placeholder="请输入出差地点" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.tripLocation" placeholder="请输入出差地点" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="开始日期" prop="startTime">--> <!-- <el-form-item label="开始日期" prop="startTime">-->
<!-- <el-date-picker clearable v-model="queryParams.startTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开始日期" />--> <!-- <el-date-picker clearable v-model="queryParams.startTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择开始日期" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- <el-form-item label="结束日期" prop="endTime">--> <!-- <el-form-item label="结束日期" prop="endTime">-->
<!-- <el-date-picker clearable v-model="queryParams.endTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择结束日期" />--> <!-- <el-date-picker clearable v-model="queryParams.endTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择结束日期" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="业务方向" prop="businessDirection"> <el-form-item label="业务方向" prop="businessDirection">
<el-select v-model="queryParams.businessDirection" placeholder="请选择业务方向" clearable filterable style="width: 200px"> <el-select v-model="queryParams.businessDirection" placeholder="请选择业务方向" clearable filterable style="width: 200px">
<el-option v-for="dict in business_direction" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in business_direction" :key="dict.value" :label="dict.label" :value="dict.value" />
@ -112,7 +112,7 @@
<el-table-column label="出差事由" align="center" prop="tripReason" width="200" show-overflow-tooltip v-if="columns[12].visible" /> <el-table-column label="出差事由" align="center" prop="tripReason" width="200" show-overflow-tooltip v-if="columns[12].visible" />
<el-table-column label="项目ID" align="center" prop="projectId" width="80" v-if="columns[13].visible" /> <el-table-column label="项目ID" align="center" prop="projectId" width="80" v-if="columns[13].visible" />
<!-- <el-table-column label="客户ID" align="center" prop="customerId" v-if="columns[14].visible" /> --> <!-- <el-table-column label="客户ID" align="center" prop="customerId" v-if="columns[14].visible" /> -->
<el-table-column label="交流对象" align="center" prop="exchangeObject" width="150" show-overflow-tooltip v-if="columns[15].visible" /> <el-table-column label="交流对象" align="center" prop="customerName" width="150" show-overflow-tooltip v-if="columns[15].visible" />
<el-table-column label="业务方向" align="center" prop="businessDirection" width="120" v-if="columns[16].visible"> <el-table-column label="业务方向" align="center" prop="businessDirection" width="120" v-if="columns[16].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="business_direction" :value="scope.row.businessDirection" /> <dict-tag :options="business_direction" :value="scope.row.businessDirection" />
@ -155,15 +155,15 @@
v-hasPermi="['oa/crm:businessTripApply:edit']" v-hasPermi="['oa/crm:businessTripApply:edit']"
></el-button> ></el-button>
</el-tooltip> </el-tooltip>
<!-- <el-tooltip content="删除" placement="top">--> <!-- <el-tooltip content="删除" placement="top">-->
<!-- <el-button--> <!-- <el-button-->
<!-- link--> <!-- link-->
<!-- type="primary"--> <!-- type="primary"-->
<!-- icon="Delete"--> <!-- icon="Delete"-->
<!-- @click="handleDelete(scope.row)"--> <!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['oa/crm:businessTripApply:remove']"--> <!-- v-hasPermi="['oa/crm:businessTripApply:remove']"-->
<!-- ></el-button>--> <!-- ></el-button>-->
<!-- </el-tooltip>--> <!-- </el-tooltip>-->
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

@ -11,33 +11,33 @@
<el-input v-model="queryParams.mnemonicName" placeholder="请输入助记名称" clearable @keyup.enter="handleQuery" /> <el-input v-model="queryParams.mnemonicName" placeholder="请输入助记名称" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item label="所属行业" prop="industryId"> <el-form-item label="所属行业" prop="industryId">
<el-select v-model="queryParams.industryId" placeholder="请选择所属行业" clearable > <el-select v-model="queryParams.industryId" placeholder="请选择所属行业" clearable>
<el-option v-for="dict in industry_id" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in industry_id" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户类型" prop="customerType"> <el-form-item label="客户类型" prop="customerType">
<el-select v-model="queryParams.customerType" placeholder="请选择客户类型" clearable > <el-select v-model="queryParams.customerType" placeholder="请选择客户类型" clearable>
<el-option v-for="dict in customer_type" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in customer_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户状态" prop="customerStatus"> <el-form-item label="客户状态" prop="customerStatus">
<el-select v-model="queryParams.customerStatus" placeholder="请选择客户状态" clearable > <el-select v-model="queryParams.customerStatus" placeholder="请选择客户状态" clearable>
<el-option v-for="dict in customer_status" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in customer_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户级别" prop="customerLevel"> <el-form-item label="客户级别" prop="customerLevel">
<el-select v-model="queryParams.customerLevel" placeholder="请选择客户级别" clearable > <el-select v-model="queryParams.customerLevel" placeholder="请选择客户级别" clearable>
<el-option v-for="dict in customer_level" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in customer_level" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="客户来源" prop="customerSource"> <el-form-item label="客户来源" prop="customerSource">
<el-select v-model="queryParams.customerSource" placeholder="请选择客户来源" clearable > <el-select v-model="queryParams.customerSource" placeholder="请选择客户来源" clearable>
<el-option v-for="dict in customer_source" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in customer_source" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="企业规模" prop="customerScale"> <el-form-item label="企业规模" prop="customerScale">
<el-select v-model="queryParams.customerScale" placeholder="请选择企业规模" clearable > <el-select v-model="queryParams.customerScale" placeholder="请选择企业规模" clearable>
<el-option v-for="dict in customer_scale" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in customer_scale" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -56,10 +56,14 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['oa/crm:customerInfo:add']"></el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['oa/crm:customerInfo:add']"></el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['oa/crm:customerInfo:edit']"></el-button> <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['oa/crm:customerInfo:edit']"
>修改</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['oa/crm:customerInfo:remove']"></el-button> <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['oa/crm:customerInfo:remove']"
>删除</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['oa/crm:customerInfo:export']"></el-button> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['oa/crm:customerInfo:export']"></el-button>
@ -70,58 +74,85 @@
<el-table v-loading="loading" border :data="customerInfoList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" border :data="customerInfoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户ID" align="center" prop="customerId" width="80" v-if="columns[0].visible"/> <el-table-column label="客户ID" align="center" prop="customerId" width="80" v-if="columns[0].visible" />
<el-table-column label="客户名称" align="center" prop="customerName" width="200" v-if="columns[2].visible" show-overflow-tooltip/> <el-table-column label="客户名称" align="center" prop="customerName" width="200" v-if="columns[2].visible" show-overflow-tooltip>
<el-table-column label="助记名称" align="center" prop="mnemonicName" width="130" v-if="columns[3].visible" show-overflow-tooltip/> <template #default="scope">
<el-link type="primary" underline @click="handleTripHistory(scope.row)">
{{ scope.row.customerName }}
</el-link>
</template>
</el-table-column>
<el-table-column label="助记名称" align="center" prop="mnemonicName" width="130" v-if="columns[3].visible" show-overflow-tooltip />
<el-table-column label="所属行业" align="center" prop="industryId" width="110" v-if="columns[4].visible"> <el-table-column label="所属行业" align="center" prop="industryId" width="110" v-if="columns[4].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="industry_id" :value="scope.row.industryId"/> <dict-tag :options="industry_id" :value="scope.row.industryId" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户类型" align="center" prop="customerType" width="110" v-if="columns[5].visible"> <el-table-column label="客户类型" align="center" prop="customerType" width="110" v-if="columns[5].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_type" :value="scope.row.customerType"/> <dict-tag :options="customer_type" :value="scope.row.customerType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户状态" align="center" prop="customerStatus" width="120" v-if="columns[6].visible"> <el-table-column label="客户状态" align="center" prop="customerStatus" width="120" v-if="columns[6].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_status" :value="scope.row.customerStatus"/> <dict-tag :options="customer_status" :value="scope.row.customerStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户级别" align="center" prop="customerLevel" width="110" v-if="columns[7].visible"> <el-table-column label="客户级别" align="center" prop="customerLevel" width="110" v-if="columns[7].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_level" :value="scope.row.customerLevel"/> <dict-tag :options="customer_level" :value="scope.row.customerLevel" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户来源" align="center" prop="customerSource" width="130" v-if="columns[8].visible"> <el-table-column label="客户来源" align="center" prop="customerSource" width="130" v-if="columns[8].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_source" :value="scope.row.customerSource"/> <dict-tag :options="customer_source" :value="scope.row.customerSource" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户经理" align="center" prop="ownerName" width="120" v-if="columns[9].visible" show-overflow-tooltip/> <el-table-column label="客户经理" align="center" prop="ownerName" width="120" v-if="columns[9].visible" show-overflow-tooltip />
<el-table-column label="办公地" align="center" prop="detailedAddress" width="200" v-if="columns[10].visible" show-overflow-tooltip/> <el-table-column label="办公地" align="center" prop="detailedAddress" width="200" v-if="columns[10].visible" show-overflow-tooltip />
<el-table-column label="注册地" align="center" prop="registeredAddress" width="200" v-if="columns[28].visible" show-overflow-tooltip/> <el-table-column label="注册地" align="center" prop="registeredAddress" width="200" v-if="columns[28].visible" show-overflow-tooltip />
<el-table-column label="商务联系人" align="center" prop="businessContact" width="120" v-if="columns[29].visible" show-overflow-tooltip/> <el-table-column label="商务联系人" align="center" prop="businessContact" width="120" v-if="columns[29].visible" show-overflow-tooltip />
<el-table-column label="商务联系人电话" align="center" prop="businessContactPhone" width="150" v-if="columns[30].visible" show-overflow-tooltip/> <el-table-column
<el-table-column label="技术联系人" align="center" prop="technicalContact" width="120" v-if="columns[31].visible" show-overflow-tooltip/> label="商务联系人电话"
<el-table-column label="技术联系人电话" align="center" prop="technicalContactPhone" width="150" v-if="columns[32].visible" show-overflow-tooltip/> align="center"
prop="businessContactPhone"
width="150"
v-if="columns[30].visible"
show-overflow-tooltip
/>
<el-table-column label="技术联系人" align="center" prop="technicalContact" width="120" v-if="columns[31].visible" show-overflow-tooltip />
<el-table-column
label="技术联系人电话"
align="center"
prop="technicalContactPhone"
width="150"
v-if="columns[32].visible"
show-overflow-tooltip
/>
<el-table-column label="企业规模" align="center" prop="customerScale" width="120" v-if="columns[11].visible"> <el-table-column label="企业规模" align="center" prop="customerScale" width="120" v-if="columns[11].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_scale" :value="scope.row.customerScale"/> <dict-tag :options="customer_scale" :value="scope.row.customerScale" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="上级客户" align="center" prop="parentCustomerId" width="100" v-if="columns[12].visible"/> <el-table-column label="上级客户" align="center" prop="parentCustomerId" width="100" v-if="columns[12].visible" />
<el-table-column label="客户关系" align="center" prop="customerRelationship" width="120" v-if="columns[13].visible" show-overflow-tooltip/> <el-table-column label="客户关系" align="center" prop="customerRelationship" width="120" v-if="columns[13].visible" show-overflow-tooltip />
<el-table-column label="法定代表人" align="center" prop="legalRepresentative" width="130" v-if="columns[14].visible" show-overflow-tooltip/> <el-table-column label="法定代表人" align="center" prop="legalRepresentative" width="130" v-if="columns[14].visible" show-overflow-tooltip />
<el-table-column label="营业执照号码" align="center" prop="businessLicenseNumber" width="150" v-if="columns[15].visible" show-overflow-tooltip/> <el-table-column
<el-table-column label="税号" align="center" prop="taxNumber" width="150" v-if="columns[16].visible" show-overflow-tooltip/> label="营业执照号码"
<el-table-column label="开户银行" align="center" prop="bankAccountOpening" width="180" v-if="columns[17].visible" show-overflow-tooltip/> align="center"
<el-table-column label="银行账号" align="center" prop="bankNumber" width="180" v-if="columns[18].visible" show-overflow-tooltip/> prop="businessLicenseNumber"
<el-table-column label="附件ID" align="center" prop="ossId" width="100" v-if="columns[19].visible"/> width="150"
<el-table-column label="备注" align="center" prop="remark" width="200" v-if="columns[20].visible" show-overflow-tooltip/> v-if="columns[15].visible"
show-overflow-tooltip
/>
<el-table-column label="税号" align="center" prop="taxNumber" width="150" v-if="columns[16].visible" show-overflow-tooltip />
<el-table-column label="开户银行" align="center" prop="bankAccountOpening" width="180" v-if="columns[17].visible" show-overflow-tooltip />
<el-table-column label="银行账号" align="center" prop="bankNumber" width="180" v-if="columns[18].visible" show-overflow-tooltip />
<el-table-column label="附件ID" align="center" prop="ossId" width="100" v-if="columns[19].visible" />
<el-table-column label="备注" align="center" prop="remark" width="200" v-if="columns[20].visible" show-overflow-tooltip />
<el-table-column label="激活标识" align="center" prop="activeFlag" width="100" v-if="columns[21].visible"> <el-table-column label="激活标识" align="center" prop="activeFlag" width="100" v-if="columns[21].visible">
<template #default="scope"> <template #default="scope">
<dict-tag :options="active_flag" :value="scope.row.activeFlag"/> <dict-tag :options="active_flag" :value="scope.row.activeFlag" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="180" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" fixed="right" width="180" class-name="small-padding fixed-width">
@ -160,24 +191,14 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="所属行业" prop="industryId"> <el-form-item label="所属行业" prop="industryId">
<el-select v-model="form.industryId" placeholder="请选择所属行业" style="width: 100%"> <el-select v-model="form.industryId" placeholder="请选择所属行业" style="width: 100%">
<el-option <el-option v-for="dict in industry_id" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in industry_id"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户类型" prop="customerType"> <el-form-item label="客户类型" prop="customerType">
<el-select v-model="form.customerType" placeholder="请选择客户类型" style="width: 100%"> <el-select v-model="form.customerType" placeholder="请选择客户类型" style="width: 100%">
<el-option <el-option v-for="dict in customer_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in customer_type"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -186,24 +207,14 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户状态" prop="customerStatus"> <el-form-item label="客户状态" prop="customerStatus">
<el-select v-model="form.customerStatus" placeholder="请选择客户状态" style="width: 100%"> <el-select v-model="form.customerStatus" placeholder="请选择客户状态" style="width: 100%">
<el-option <el-option v-for="dict in customer_status" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in customer_status"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户级别" prop="customerLevel"> <el-form-item label="客户级别" prop="customerLevel">
<el-select v-model="form.customerLevel" placeholder="请选择客户级别" style="width: 100%"> <el-select v-model="form.customerLevel" placeholder="请选择客户级别" style="width: 100%">
<el-option <el-option v-for="dict in customer_level" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in customer_level"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -212,12 +223,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="客户来源" prop="customerSource"> <el-form-item label="客户来源" prop="customerSource">
<el-select v-model="form.customerSource" placeholder="请选择客户来源" style="width: 100%"> <el-select v-model="form.customerSource" placeholder="请选择客户来源" style="width: 100%">
<el-option <el-option v-for="dict in customer_source" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in customer_source"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -233,12 +239,7 @@
style="width: 100%" style="width: 100%"
clearable clearable
> >
<el-option <el-option v-for="user in userOptions" :key="user.userId" :label="user.nickName" :value="user.userId">
v-for="user in userOptions"
:key="user.userId"
:label="user.nickName"
:value="user.userId"
>
<span style="float: left">{{ user.nickName }}</span> <span style="float: left">{{ user.nickName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ user.userName }}</span> <span style="float: right; color: #8492a6; font-size: 13px">{{ user.userName }}</span>
</el-option> </el-option>
@ -288,12 +289,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="企业规模" prop="customerScale"> <el-form-item label="企业规模" prop="customerScale">
<el-select v-model="form.customerScale" placeholder="请选择企业规模" style="width: 100%"> <el-select v-model="form.customerScale" placeholder="请选择企业规模" style="width: 100%">
<el-option <el-option v-for="dict in customer_scale" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
v-for="dict in customer_scale"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -307,12 +303,7 @@
style="width: 100%" style="width: 100%"
clearable clearable
> >
<el-option <el-option v-for="customer in customerOptions" :key="customer.customerId" :label="customer.customerName" :value="customer.customerId">
v-for="customer in customerOptions"
:key="customer.customerId"
:label="customer.customerName"
:value="customer.customerId"
>
<span style="float: left">{{ customer.customerName }}</span> <span style="float: left">{{ customer.customerName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ customer.mnemonicName }}</span> <span style="float: right; color: #8492a6; font-size: 13px">{{ customer.mnemonicName }}</span>
</el-option> </el-option>
@ -370,15 +361,15 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- <el-form-item label="激活标识" prop="activeFlag">--> <!-- <el-form-item label="激活标识" prop="activeFlag">-->
<!-- <el-radio-group v-model="form.activeFlag">--> <!-- <el-radio-group v-model="form.activeFlag">-->
<!-- <el-radio--> <!-- <el-radio-->
<!-- v-for="dict in active_flag"--> <!-- v-for="dict in active_flag"-->
<!-- :key="dict.value"--> <!-- :key="dict.value"-->
<!-- :value="dict.value"--> <!-- :value="dict.value"-->
<!-- >{{dict.label}}</el-radio>--> <!-- >{{dict.label}}</el-radio>-->
<!-- </el-radio-group>--> <!-- </el-radio-group>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -392,38 +383,36 @@
<el-dialog title="客户关系" v-model="relationDialog.visible" width="1000px" append-to-body> <el-dialog title="客户关系" v-model="relationDialog.visible" width="1000px" append-to-body>
<div v-loading="relationLoading"> <div v-loading="relationLoading">
<!-- 当前客户信息卡片 --> <!-- 当前客户信息卡片 -->
<el-card shadow="hover" style="margin-bottom: 20px;"> <el-card shadow="hover" style="margin-bottom: 20px">
<template #header> <template #header>
<div style="display: flex; align-items: center; justify-content: space-between;"> <div style="display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 16px; font-weight: bold; color: #409EFF;"> <span style="font-size: 16px; font-weight: bold; color: #409eff"> 当前客户 </span>
当前客户
</span>
</div> </div>
</template> </template>
<el-descriptions :column="3" border> <el-descriptions :column="3" border>
<el-descriptions-item label="客户名称" :span="2"> <el-descriptions-item label="客户名称" :span="2">
<strong style="font-size: 16px; color: #303133;">{{ currentCustomer.customerName }}</strong> <strong style="font-size: 16px; color: #303133">{{ currentCustomer.customerName }}</strong>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="助记名称"> <el-descriptions-item label="助记名称">
{{ currentCustomer.mnemonicName || '-' }} {{ currentCustomer.mnemonicName || '-' }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户类型"> <el-descriptions-item label="客户类型">
<dict-tag :options="customer_type" :value="currentCustomer.customerType"/> <dict-tag :options="customer_type" :value="currentCustomer.customerType" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户状态"> <el-descriptions-item label="客户状态">
<dict-tag :options="customer_status" :value="currentCustomer.customerStatus"/> <dict-tag :options="customer_status" :value="currentCustomer.customerStatus" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户级别"> <el-descriptions-item label="客户级别">
<dict-tag :options="customer_level" :value="currentCustomer.customerLevel"/> <dict-tag :options="customer_level" :value="currentCustomer.customerLevel" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户经理"> <el-descriptions-item label="客户经理">
{{ currentCustomer.ownerName || '-' }} {{ currentCustomer.ownerName || '-' }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="所属行业"> <el-descriptions-item label="所属行业">
<dict-tag :options="industry_id" :value="currentCustomer.industryId"/> <dict-tag :options="industry_id" :value="currentCustomer.industryId" />
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="企业规模"> <el-descriptions-item label="企业规模">
<dict-tag :options="customer_scale" :value="currentCustomer.customerScale"/> <dict-tag :options="customer_scale" :value="currentCustomer.customerScale" />
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
</el-card> </el-card>
@ -434,10 +423,8 @@
<el-col :span="12"> <el-col :span="12">
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
<div style="display: flex; align-items: center; justify-content: space-between;"> <div style="display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 14px; font-weight: bold;"> <span style="font-size: 14px; font-weight: bold"> 上级客户 </span>
上级客户
</span>
<el-tag type="success" size="small">{{ parentCustomerList.length }} </el-tag> <el-tag type="success" size="small">{{ parentCustomerList.length }} </el-tag>
</div> </div>
</template> </template>
@ -445,31 +432,31 @@
<el-table :data="parentCustomerList" border size="small" max-height="400"> <el-table :data="parentCustomerList" border size="small" max-height="400">
<el-table-column label="客户名称" prop="customerName" min-width="150" show-overflow-tooltip> <el-table-column label="客户名称" prop="customerName" min-width="150" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<el-link type="primary" @click="handleViewRelation(scope.row)" style="font-weight: 500;"> <el-link type="primary" @click="handleViewRelation(scope.row)" style="font-weight: 500">
{{ scope.row.customerName }} {{ scope.row.customerName }}
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="助记名称" prop="mnemonicName" width="120" show-overflow-tooltip/> <el-table-column label="助记名称" prop="mnemonicName" width="120" show-overflow-tooltip />
<el-table-column label="客户类型" prop="customerType" width="100"> <el-table-column label="客户类型" prop="customerType" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_type" :value="scope.row.customerType"/> <dict-tag :options="customer_type" :value="scope.row.customerType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户状态" prop="customerStatus" width="100"> <el-table-column label="客户状态" prop="customerStatus" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_status" :value="scope.row.customerStatus"/> <dict-tag :options="customer_status" :value="scope.row.customerStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户级别" prop="customerLevel" width="100"> <el-table-column label="客户级别" prop="customerLevel" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_level" :value="scope.row.customerLevel"/> <dict-tag :options="customer_level" :value="scope.row.customerLevel" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户经理" prop="ownerName" width="100" show-overflow-tooltip/> <el-table-column label="客户经理" prop="ownerName" width="100" show-overflow-tooltip />
</el-table> </el-table>
</div> </div>
<el-empty v-else description="暂无上级客户" :image-size="60" style="padding: 40px 0;"> <el-empty v-else description="暂无上级客户" :image-size="60" style="padding: 40px 0">
<el-text type="info" size="small">该客户没有上级客户</el-text> <el-text type="info" size="small">该客户没有上级客户</el-text>
</el-empty> </el-empty>
</el-card> </el-card>
@ -479,10 +466,8 @@
<el-col :span="12"> <el-col :span="12">
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
<div style="display: flex; align-items: center; justify-content: space-between;"> <div style="display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 14px; font-weight: bold;"> <span style="font-size: 14px; font-weight: bold"> 下级客户 </span>
下级客户
</span>
<el-tag type="warning" size="small">{{ childCustomerList.length }} </el-tag> <el-tag type="warning" size="small">{{ childCustomerList.length }} </el-tag>
</div> </div>
</template> </template>
@ -490,31 +475,31 @@
<el-table :data="childCustomerList" border size="small" max-height="400"> <el-table :data="childCustomerList" border size="small" max-height="400">
<el-table-column label="客户名称" prop="customerName" min-width="150" show-overflow-tooltip> <el-table-column label="客户名称" prop="customerName" min-width="150" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<el-link type="primary" @click="handleViewRelation(scope.row)" style="font-weight: 500;"> <el-link type="primary" @click="handleViewRelation(scope.row)" style="font-weight: 500">
{{ scope.row.customerName }} {{ scope.row.customerName }}
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="助记名称" prop="mnemonicName" width="120" show-overflow-tooltip/> <el-table-column label="助记名称" prop="mnemonicName" width="120" show-overflow-tooltip />
<el-table-column label="客户类型" prop="customerType" width="100"> <el-table-column label="客户类型" prop="customerType" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_type" :value="scope.row.customerType"/> <dict-tag :options="customer_type" :value="scope.row.customerType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户状态" prop="customerStatus" width="100"> <el-table-column label="客户状态" prop="customerStatus" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_status" :value="scope.row.customerStatus"/> <dict-tag :options="customer_status" :value="scope.row.customerStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户级别" prop="customerLevel" width="100"> <el-table-column label="客户级别" prop="customerLevel" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :options="customer_level" :value="scope.row.customerLevel"/> <dict-tag :options="customer_level" :value="scope.row.customerLevel" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="客户经理" prop="ownerName" width="100" show-overflow-tooltip/> <el-table-column label="客户经理" prop="ownerName" width="100" show-overflow-tooltip />
</el-table> </el-table>
</div> </div>
<el-empty v-else description="暂无下级客户" :image-size="60" style="padding: 40px 0;"> <el-empty v-else description="暂无下级客户" :image-size="60" style="padding: 40px 0">
<el-text type="info" size="small">该客户没有下级客户</el-text> <el-text type="info" size="small">该客户没有下级客户</el-text>
</el-empty> </el-empty>
</el-card> </el-card>
@ -545,8 +530,12 @@ import { listUser, optionSelect } from '@/api/system/user';
import { UserVO } from '@/api/system/user/types'; import { UserVO } from '@/api/system/user/types';
import FileUpload from '@/components/FileUpload/index.vue'; import FileUpload from '@/components/FileUpload/index.vue';
const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { customer_type, active_flag, industry_id, customer_source, customer_scale, customer_status, customer_level } = toRefs<any>(proxy?.useDict('customer_type', 'active_flag', 'industry_id', 'customer_source', 'customer_scale', 'customer_status', 'customer_level')); const { customer_type, active_flag, industry_id, customer_source, customer_scale, customer_status, customer_level } = toRefs<any>(
proxy?.useDict('customer_type', 'active_flag', 'industry_id', 'customer_source', 'customer_scale', 'customer_status', 'customer_level')
);
const customerInfoList = ref<CustomerInfoVO[]>([]); const customerInfoList = ref<CustomerInfoVO[]>([]);
const buttonLoading = ref(false); const buttonLoading = ref(false);
@ -655,10 +644,10 @@ const initFormData: CustomerInfoForm = {
ossId: undefined, ossId: undefined,
remark: undefined, remark: undefined,
activeFlag: undefined, activeFlag: undefined,
ourCompanyFlag: undefined, ourCompanyFlag: undefined
} };
const data = reactive<PageData<CustomerInfoForm, CustomerInfoQuery>>({ const data = reactive<PageData<CustomerInfoForm, CustomerInfoQuery>>({
form: {...initFormData}, form: { ...initFormData },
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@ -687,11 +676,9 @@ const data = reactive<PageData<CustomerInfoForm, CustomerInfoQuery>>({
ossId: undefined, ossId: undefined,
activeFlag: undefined, activeFlag: undefined,
ourCompanyFlag: '0', ourCompanyFlag: '0',
params: { params: {}
}
}, },
rules: { rules: {}
}
}); });
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
@ -703,40 +690,40 @@ const getList = async () => {
customerInfoList.value = res.rows; customerInfoList.value = res.rows;
total.value = res.total; total.value = res.total;
loading.value = false; loading.value = false;
} };
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
reset(); reset();
dialog.visible = false; dialog.visible = false;
} };
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
form.value = {...initFormData}; form.value = { ...initFormData };
customerInfoFormRef.value?.resetFields(); customerInfoFormRef.value?.resetFields();
userOptions.value = []; userOptions.value = [];
customerOptions.value = []; customerOptions.value = [];
} };
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.value.pageNum = 1; queryParams.value.pageNum = 1;
getList(); getList();
} };
/** 重置按钮操作 */ /** 重置按钮操作 */
const resetQuery = () => { const resetQuery = () => {
queryFormRef.value?.resetFields(); queryFormRef.value?.resetFields();
handleQuery(); handleQuery();
} };
/** 多选框选中数据 */ /** 多选框选中数据 */
const handleSelectionChange = (selection: CustomerInfoVO[]) => { const handleSelectionChange = (selection: CustomerInfoVO[]) => {
ids.value = selection.map(item => item.customerId); ids.value = selection.map((item) => item.customerId);
single.value = selection.length != 1; single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
} };
/** 加载客户列表 */ /** 加载客户列表 */
const loadCustomerList = async () => { const loadCustomerList = async () => {
@ -744,9 +731,7 @@ const loadCustomerList = async () => {
try { try {
const res = await getCrmCustomerInfoList(null); const res = await getCrmCustomerInfoList(null);
// //
const filteredList = res.data?.filter((customer: CustomerInfoVO) => const filteredList = res.data?.filter((customer: CustomerInfoVO) => customer.customerId !== form.value.customerId) || [];
customer.customerId !== form.value.customerId
) || [];
customerOptions.value = filteredList; customerOptions.value = filteredList;
} catch (error) { } catch (error) {
console.error('加载客户列表失败:', error); console.error('加载客户列表失败:', error);
@ -754,7 +739,7 @@ const loadCustomerList = async () => {
} finally { } finally {
customerLoading.value = false; customerLoading.value = false;
} }
} };
/** 新增按钮操作 */ /** 新增按钮操作 */
const handleAdd = async () => { const handleAdd = async () => {
@ -763,22 +748,20 @@ const handleAdd = async () => {
customerOptions.value = []; customerOptions.value = [];
await loadCustomerList(); await loadCustomerList();
dialog.visible = true; dialog.visible = true;
dialog.title = "添加客户信息"; dialog.title = '添加客户信息';
} };
/** 修改按钮操作 */ /** 修改按钮操作 */
const handleUpdate = async (row?: CustomerInfoVO) => { const handleUpdate = async (row?: CustomerInfoVO) => {
reset(); reset();
const _customerId = row?.customerId || ids.value[0] const _customerId = row?.customerId || ids.value[0];
const res = await getCustomerInfo(_customerId); const res = await getCustomerInfo(_customerId);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
// //
await loadCustomerList(); await loadCustomerList();
// //
if (form.value.parentCustomerId) { if (form.value.parentCustomerId) {
const exists = customerOptions.value.some( const exists = customerOptions.value.some((customer: CustomerInfoVO) => customer.customerId === form.value.parentCustomerId);
(customer: CustomerInfoVO) => customer.customerId === form.value.parentCustomerId
);
if (!exists) { if (!exists) {
try { try {
const customerRes = await getCustomerInfo(form.value.parentCustomerId); const customerRes = await getCustomerInfo(form.value.parentCustomerId);
@ -795,8 +778,8 @@ const handleUpdate = async (row?: CustomerInfoVO) => {
await loadSelectedUser(form.value.ownerId); await loadSelectedUser(form.value.ownerId);
} }
dialog.visible = true; dialog.visible = true;
dialog.title = "修改客户信息"; dialog.title = '修改客户信息';
} };
/** 加载已选用户信息 */ /** 加载已选用户信息 */
const loadSelectedUser = async (userId: string | number) => { const loadSelectedUser = async (userId: string | number) => {
@ -808,7 +791,7 @@ const loadSelectedUser = async (userId: string | number) => {
} catch (error) { } catch (error) {
console.error('加载用户信息失败:', error); console.error('加载用户信息失败:', error);
} }
} };
/** 远程搜索用户 */ /** 远程搜索用户 */
const remoteUserMethod = async (query: string) => { const remoteUserMethod = async (query: string) => {
@ -835,8 +818,7 @@ const remoteUserMethod = async (query: string) => {
await loadSelectedUser(form.value.ownerId); await loadSelectedUser(form.value.ownerId);
} }
} }
} };
/** 提交按钮 */ /** 提交按钮 */
const submitForm = () => { const submitForm = () => {
@ -844,32 +826,36 @@ const submitForm = () => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
if (form.value.customerId) { if (form.value.customerId) {
await updateCustomerInfo(form.value).finally(() => buttonLoading.value = false); await updateCustomerInfo(form.value).finally(() => (buttonLoading.value = false));
} else { } else {
await addCustomerInfo(form.value).finally(() => buttonLoading.value = false); await addCustomerInfo(form.value).finally(() => (buttonLoading.value = false));
} }
proxy?.$modal.msgSuccess("操作成功"); proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false; dialog.visible = false;
await getList(); await getList();
} }
}); });
} };
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: CustomerInfoVO) => { const handleDelete = async (row?: CustomerInfoVO) => {
const _customerIds = row?.customerId || ids.value; const _customerIds = row?.customerId || ids.value;
await proxy?.$modal.confirm('是否确认删除客户信息编号为"' + _customerIds + '"的数据项?').finally(() => loading.value = false); await proxy?.$modal.confirm('是否确认删除客户信息编号为"' + _customerIds + '"的数据项?').finally(() => (loading.value = false));
await delCustomerInfo(_customerIds); await delCustomerInfo(_customerIds);
proxy?.$modal.msgSuccess("删除成功"); proxy?.$modal.msgSuccess('删除成功');
await getList(); await getList();
} };
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = () => { const handleExport = () => {
proxy?.download('oa/crm/customerInfo/export', { proxy?.download(
...queryParams.value 'oa/crm/customerInfo/export',
}, `customerInfo_${new Date().getTime()}.xlsx`) {
} ...queryParams.value
},
`customerInfo_${new Date().getTime()}.xlsx`
);
};
/** 查看客户关系 */ /** 查看客户关系 */
const handleViewRelation = async (row: CustomerInfoVO) => { const handleViewRelation = async (row: CustomerInfoVO) => {
@ -907,7 +893,18 @@ const handleViewRelation = async (row: CustomerInfoVO) => {
relationLoading.value = false; relationLoading.value = false;
relationDialog.visible = true; relationDialog.visible = true;
} }
} };
/** 查看客户出差交流记录 */
const handleTripHistory = (row: CustomerInfoVO) => {
router.push({
path: '/customer/tripHistory',
query: {
customerId: row.customerId,
customerName: row.customerName
}
});
};
onMounted(() => { onMounted(() => {
getList(); getList();

@ -0,0 +1,119 @@
<template>
<div class="p-2">
<el-card shadow="never">
<template #header>
<div class="flex justify-between items-center">
<span class="card-title">{{ customerName }} - 市场交流出差记录</span>
<el-button type="primary" plain icon="Back" @click="goBack"></el-button>
</div>
</template>
<el-table v-loading="loading" border :data="tripList">
<el-table-column label="申请编号" align="center" prop="applyCode" width="140" />
<el-table-column label="申请人" align="center" prop="applicantName" width="100" />
<el-table-column label="部门" align="center" prop="deptName" width="120" />
<el-table-column label="出差地点" align="center" prop="tripLocation" width="150" />
<el-table-column label="开始日期" align="center" prop="startTime" width="110">
<template #default="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="结束日期" align="center" prop="endTime" width="110">
<template #default="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="时长(天)" align="center" prop="durationDays" width="80" />
<el-table-column label="业务方向" align="center" prop="businessDirection" width="120">
<template #default="scope">
<dict-tag :options="business_direction" :value="scope.row.businessDirection" />
</template>
</el-table-column>
<el-table-column label="交流目的" align="center" prop="exchangePurpose" width="150" show-overflow-tooltip />
<el-table-column label="交流过程简述" align="center" prop="exchangeProcess" width="200" show-overflow-tooltip />
<el-table-column label="结果反馈" align="center" prop="feedback" width="200" show-overflow-tooltip />
<el-table-column label="流程状态" align="center" prop="flowStatus" width="100">
<template #default="scope">
<el-tag v-if="scope.row.flowStatus === 'finish'" type="success"></el-tag>
<el-tag v-else-if="scope.row.flowStatus === 'running'" type="warning">审批中</el-tag>
<el-tag v-else-if="scope.row.flowStatus === 'draft'" type="info">草稿</el-tag>
<el-tag v-else-if="scope.row.flowStatus === 'back'" type="danger">已退回</el-tag>
<el-tag v-else type="info">{{ scope.row.flowStatus }}</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" width="200" show-overflow-tooltip />
<el-table-column label="操作" align="center" fixed="right" width="100">
<template #default="scope">
<el-button link type="primary" @click="handleView(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup name="CustomerTripHistory" lang="ts">
import { listBusinessTripApply } from '@/api/oa/crm/businessTripApply';
import { BusinessTripApplyVO } from '@/api/oa/crm/businessTripApply/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
const { business_direction } = toRefs<any>(proxy?.useDict('business_direction'));
const loading = ref(false);
const tripList = ref<BusinessTripApplyVO[]>([]);
const total = ref(0);
const customerId = ref<string | number>('');
const customerName = ref<string>('');
const queryParams = ref({
pageNum: 1,
pageSize: 20,
tripType: '2', //
customerId: undefined as string | number | undefined
});
/** 获取出差记录列表 */
const getList = async () => {
loading.value = true;
try {
const res = await listBusinessTripApply(queryParams.value);
tripList.value = res.rows;
total.value = res.total;
} catch (error) {
console.error('查询出差记录失败:', error);
} finally {
loading.value = false;
}
};
/** 查看详情 */
const handleView = (row: BusinessTripApplyVO) => {
router.push({
path: '/tripapply/businessTripApply/edit',
query: {
id: row.tripId,
type: 'view'
}
});
};
/** 返回客户列表 */
const goBack = () => {
router.push('/crm/customerInfo');
};
onMounted(() => {
//
customerId.value = route.query.customerId as string;
customerName.value = (route.query.customerName as string) || '未知客户';
queryParams.value.customerId = customerId.value;
if (customerId.value) {
getList();
}
});
</script>
Loading…
Cancel
Save