!334 feat: 客户配置 review 修改

* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
* feat: 客户配置 review 修改
This commit is contained in:
wanwan 2023-11-26 12:02:08 +00:00 committed by YunaiV
parent c5b2fdecd5
commit 85810c0786
12 changed files with 181 additions and 144 deletions

View File

@ -9,6 +9,20 @@ export interface CustomerLimitConfigVO {
dealCountEnabled?: boolean dealCountEnabled?: boolean
} }
/**
*
*/
export enum LimitConfType {
/**
*
*/
CUSTOMER_QUANTITY_LIMIT = 1,
/**
*
*/
CUSTOMER_LOCK_LIMIT = 2
}
// 查询客户限制配置列表 // 查询客户限制配置列表
export const getCustomerLimitConfigPage = async (params) => { export const getCustomerLimitConfigPage = async (params) => {
return await request.get({ url: `/crm/customer-limit-config/page`, params }) return await request.get({ url: `/crm/customer-limit-config/page`, params })

View File

@ -1,4 +1,5 @@
import request from '@/config/axios' import request from '@/config/axios'
import { ConfigVO } from '@/api/infra/config'
export interface CustomerPoolConfigVO { export interface CustomerPoolConfigVO {
enabled?: boolean enabled?: boolean
@ -14,6 +15,6 @@ export const getCustomerPoolConfig = async () => {
} }
// 更新客户公海规则设置 // 更新客户公海规则设置
export const updateCustomerPoolConfig = async (data: ConfigVO) => { export const saveCustomerPoolConfig = async (data: ConfigVO) => {
return await request.put({ url: `/crm/customer-pool-config/update`, data }) return await request.put({ url: `/crm/customer-pool-config/save`, data })
} }

View File

@ -10,9 +10,15 @@
<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>
<!-- TODO wanwan 客户选择 -->
<el-form-item label="客户" prop="customerId"> <el-form-item label="客户" prop="customerId">
<el-input v-model="formData.customerId" placeholder="请选择客户" /> <el-select v-model="formData.customerId" clearable placeholder="请选择客户">
<el-option
v-for="item in customerList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="下次联系时间" prop="contactNextTime"> <el-form-item label="下次联系时间" prop="contactNextTime">
<el-date-picker <el-date-picker
@ -47,6 +53,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as ClueApi from '@/api/crm/clue' import * as ClueApi from '@/api/crm/clue'
import * as CustomerApi from '@/api/crm/customer'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
@ -55,6 +62,7 @@ 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 customerList = ref([]) //
const formData = ref({ const formData = ref({
id: undefined, id: undefined,
name: undefined, name: undefined,
@ -79,6 +87,12 @@ const open = async (type: string, id?: number) => {
dialogTitle.value = t('action.' + type) dialogTitle.value = t('action.' + type)
formType.value = type formType.value = type
resetForm() resetForm()
const customerData = await CustomerApi.getCustomerPage({
pageNo: 1,
pageSize: 100,
pool: false
})
customerList.value = customerData.list
// //
if (id) { if (id) {
formLoading.value = true formLoading.value = true

View File

@ -57,11 +57,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as CustomerLimitConfigApi from '@/api/crm/customerLimitConfig' import * as CustomerLimitConfigApi from '@/api/crm/customerLimitConfig'
import { LimitConfType } from '@/views/crm/customerLimitConfig/customerLimitConf'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
import * as UserApi from '@/api/system/user' import * as UserApi from '@/api/system/user'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { LimitConfType } from '@/api/crm/customerLimitConfig'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //

View File

@ -19,8 +19,16 @@
> >
<el-table-column label="编号" align="center" prop="id" /> <el-table-column label="编号" align="center" prop="id" />
<el-table-column label="规则类型" align="center" prop="type" /> <el-table-column label="规则类型" align="center" prop="type" />
<el-table-column label="规则适用人群" align="center" prop="userNames" /> <el-table-column
<el-table-column label="规则适用部门" align="center" prop="deptNames" /> label="规则适用人群"
align="center"
:formatter="(row) => row.users?.map((user: any) => user.nickname).join('')"
/>
<el-table-column
label="规则适用部门"
align="center"
:formatter="(row) => row.depts?.map((dept: any) => dept.name).join('')"
/>
<el-table-column <el-table-column
:label=" :label="
confType === LimitConfType.CUSTOMER_QUANTITY_LIMIT ? '拥有客户数上限' : '锁定客户数上限' confType === LimitConfType.CUSTOMER_QUANTITY_LIMIT ? '拥有客户数上限' : '锁定客户数上限'
@ -80,11 +88,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import * as CustomerLimitConfigApi from '@/api/crm/customerLimitConfig' import * as CustomerLimitConfigApi from '@/api/crm/customerLimitConfig'
import CustomerLimitConfigForm from '@/views/crm/customerLimitConfig/CustomerLimitConfigForm.vue' import CustomerLimitConfigForm from '@/views/crm/config/customerLimitConfig/CustomerLimitConfigForm.vue'
import { LimitConfType } from '@/views/crm/customerLimitConfig/customerLimitConf'
import { DICT_TYPE } from '@/utils/dict' import { DICT_TYPE } from '@/utils/dict'
import { LimitConfType } from '@/api/crm/customerLimitConfig'
defineOptions({ name: 'CustomerLimitConfDetails' }) defineOptions({ name: 'CustomerLimitConfigList' })
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //

View File

@ -0,0 +1,4 @@
// TODO 可以挪到它对应的 api.ts 文件里哈
/**
*
*/

View File

@ -0,0 +1,19 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-tabs>
<el-tab-pane label="拥有客户数限制">
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_QUANTITY_LIMIT" />
</el-tab-pane>
<el-tab-pane label="锁定客户数限制">
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_LOCK_LIMIT" />
</el-tab-pane>
</el-tabs>
</ContentWrap>
</template>
<script setup lang="ts">
import CustomerLimitConfigList from '@/views/crm/config/customerLimitConfig/CustomerLimitConfigList.vue'
import { LimitConfType } from '@/api/crm/customerLimitConfig'
defineOptions({ name: 'CrmCustomerLimitConfig' })
</script>

View File

@ -23,7 +23,7 @@
</template> </template>
<!-- 表单 --> <!-- 表单 -->
<el-form-item label="客户公海规则设置" prop="enabled"> <el-form-item label="客户公海规则设置" prop="enabled">
<el-radio-group v-model="formData.enabled" class="ml-4"> <el-radio-group v-model="formData.enabled" @change="changeEnable" class="ml-4">
<el-radio :label="false" size="large">不启用</el-radio> <el-radio :label="false" size="large">不启用</el-radio>
<el-radio :label="true" size="large">启用</el-radio> <el-radio :label="true" size="large">启用</el-radio>
</el-radio-group> </el-radio-group>
@ -36,7 +36,11 @@
天未成交 天未成交
</el-form-item> </el-form-item>
<el-form-item label="提前提醒设置" prop="notifyEnabled"> <el-form-item label="提前提醒设置" prop="notifyEnabled">
<el-radio-group v-model="formData.notifyEnabled" class="ml-4"> <el-radio-group
v-model="formData.notifyEnabled"
@change="changeNotifyEnable"
class="ml-4"
>
<el-radio :label="false" size="large">不提醒</el-radio> <el-radio :label="false" size="large">不提醒</el-radio>
<el-radio :label="true" size="large">提醒</el-radio> <el-radio :label="true" size="large">提醒</el-radio>
</el-radio-group> </el-radio-group>
@ -52,11 +56,10 @@
</ContentWrap> </ContentWrap>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as CustomerPoolConfApi from '@/api/crm/customerPoolConf' import * as CustomerPoolConfigApi from '@/api/crm/customerPoolConfig'
import { CardTitle } from '@/components/Card' import { CardTitle } from '@/components/Card'
// TODO @wanwanCustomerPoolConf = CustomerPoolConfig crm config customerPoolConfig customerLimitConfig defineOptions({ name: 'CrmCustomerPoolConfig' })
defineOptions({ name: 'CustomerPoolConf' })
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //
@ -78,7 +81,7 @@ const formRef = ref() // 表单 Ref
const getConfig = async () => { const getConfig = async () => {
try { try {
formLoading.value = true formLoading.value = true
const data = await CustomerPoolConfApi.getCustomerPoolConfig() const data = await CustomerPoolConfigApi.getCustomerPoolConfig()
if (data === null) { if (data === null) {
return return
} }
@ -97,8 +100,8 @@ const onSubmit = async () => {
// //
formLoading.value = true formLoading.value = true
try { try {
const data = formData.value as unknown as CustomerPoolConfApi.CustomerPoolConfigVO const data = formData.value as unknown as CustomerPoolConfigApi.CustomerPoolConfigVO
await CustomerPoolConfApi.updateCustomerPoolConfig(data) await CustomerPoolConfigApi.saveCustomerPoolConfig(data)
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
await getConfig() await getConfig()
formLoading.value = false formLoading.value = false
@ -107,27 +110,22 @@ const onSubmit = async () => {
} }
} }
// TODO @wanwanel-radio-group /** 更改客户公海规则设置 */
watch( const changeEnable = () => {
() => formData.value.enabled, if (!formData.value.enabled) {
(val: boolean) => {
if (!val) {
formData.value.contactExpireDays = undefined formData.value.contactExpireDays = undefined
formData.value.dealExpireDays = undefined formData.value.dealExpireDays = undefined
formData.value.notifyEnabled = false formData.value.notifyEnabled = false
formData.value.notifyDays = undefined formData.value.notifyDays = undefined
} }
} }
)
// TODO @wanwanel-radio-group /** 更改提前提醒设置 */
watch( const changeNotifyEnable = () => {
() => formData.value.notifyEnabled, if (!formData.value.notifyEnabled) {
(val: boolean) => {
if (!val) {
formData.value.notifyDays = undefined formData.value.notifyDays = undefined
} }
} }
)
onMounted(() => { onMounted(() => {
getConfig() getConfig()

View File

@ -0,0 +1,85 @@
<template>
<div v-loading="loading">
<div class="flex items-start justify-between">
<div>
<!-- 左上客户基本信息 -->
<CustomerBasicInfo :customer="customer" />
</div>
<div>
<!-- 右上按钮 -->
<el-button v-hasPermi="['crm:customer:update']" @click="openForm('update', customer.id)">
编辑
</el-button>
<el-button>更改成交状态</el-button>
</div>
</div>
<el-row class="mt-10px">
<el-button>
<Icon class="mr-5px" icon="ph:calendar-fill" />
创建任务
</el-button>
<el-button>
<Icon class="mr-5px" icon="carbon:email" />
发送邮件
</el-button>
<el-button>
<Icon class="mr-5px" icon="system-uicons:contacts" />
创建联系人
</el-button>
<el-button>
<Icon class="mr-5px" icon="ep:opportunity" />
创建商机
</el-button>
<el-button>
<Icon class="mr-5px" icon="clarity:contract-line" />
创建合同
</el-button>
<el-button>
<Icon class="mr-5px" icon="icon-park:income-one" />
创建回款
</el-button>
<el-button>
<Icon class="mr-5px" icon="fluent:people-team-add-20-filled" />
添加团队成员
</el-button>
</el-row>
</div>
<ContentWrap class="mt-10px">
<el-descriptions :column="5" direction="vertical">
<el-descriptions-item label="客户级别">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" />
</el-descriptions-item>
<el-descriptions-item label="成交状态">
{{ customer.dealStatus ? '已成交' : '未成交' }}
</el-descriptions-item>
<el-descriptions-item label="负责人">
{{ customer.ownerUserName }}
</el-descriptions-item>
<!-- TODO wanwan 首要联系人? -->
<el-descriptions-item label="首要联系人" />
<!-- TODO wanwan 首要联系人电话? -->
<el-descriptions-item label="首要联系人电话">
{{ customer.mobile }}
</el-descriptions-item>
</el-descriptions>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<CustomerForm ref="formRef" @success="emit('refresh')" />
</template>
<script setup lang="ts">
import * as CustomerApi from '@/api/crm/customer'
import { DICT_TYPE } from '@/utils/dict'
import CustomerBasicInfo from '@/views/crm/customer/detail/CustomerBasicInfo.vue'
import CustomerForm from '@/views/crm/customer/CustomerForm.vue'
const { customer, loading } = defineProps<{ customer: CustomerApi.CustomerVO; loading: boolean }>()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
const formRef = ref()
const emit = defineEmits(['refresh']) // success
</script>

View File

@ -1,69 +1,5 @@
<template> <template>
<!-- TODO @wanwan要不要把上面这一整块搞成一个组件就是把 下面 + Details + BasitcInfo 合并成一个 --> <CustomerDetailsTop :customer="customer" :loading="loading" @refresh="getCustomerData(id)" />
<div v-loading="loading">
<div class="flex items-start justify-between">
<div>
<!-- 左上客户基本信息 -->
<CustomerBasicInfo :customer="customer" />
</div>
<div>
<!-- 右上按钮 -->
<el-button v-hasPermi="['crm:customer:update']" @click="openForm('update', customer.id)">
编辑
</el-button>
<el-button>更改成交状态</el-button>
</div>
</div>
<el-row class="mt-10px">
<el-button>
<Icon class="mr-5px" icon="ph:calendar-fill" />
创建任务
</el-button>
<el-button>
<Icon class="mr-5px" icon="carbon:email" />
发送邮件
</el-button>
<el-button>
<Icon class="mr-5px" icon="system-uicons:contacts" />
创建联系人
</el-button>
<el-button>
<Icon class="mr-5px" icon="ep:opportunity" />
创建商机
</el-button>
<el-button>
<Icon class="mr-5px" icon="clarity:contract-line" />
创建合同
</el-button>
<el-button>
<Icon class="mr-5px" icon="icon-park:income-one" />
创建回款
</el-button>
<el-button>
<Icon class="mr-5px" icon="fluent:people-team-add-20-filled" />
添加团队成员
</el-button>
</el-row>
</div>
<ContentWrap class="mt-10px">
<el-descriptions :column="5" direction="vertical">
<el-descriptions-item label="客户级别">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="customer.level" />
</el-descriptions-item>
<el-descriptions-item label="成交状态">
{{ customer.dealStatus ? '已成交' : '未成交' }}
</el-descriptions-item>
<el-descriptions-item label="负责人">
{{ customer.ownerUserName }}
</el-descriptions-item>
<!-- TODO wanwan 首要联系人? -->
<el-descriptions-item label="首要联系人" />
<!-- TODO wanwan 首要联系人电话? -->
<el-descriptions-item label="首要联系人电话">
{{ customer.mobile }}
</el-descriptions-item>
</el-descriptions>
</ContentWrap>
<el-col> <el-col>
<el-tabs> <el-tabs>
<el-tab-pane label="详细资料"> <el-tab-pane label="详细资料">
@ -107,9 +43,6 @@
<el-tab-pane label="发票" lazy> 发票</el-tab-pane> <el-tab-pane label="发票" lazy> 发票</el-tab-pane>
</el-tabs> </el-tabs>
</el-col> </el-col>
<!-- 表单弹窗添加/修改 -->
<CustomerForm ref="formRef" @success="getCustomerData(id)" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -145,11 +78,6 @@ const getCustomerData = async (id: number) => {
} }
} }
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** /**
* 初始化 * 初始化
*/ */

View File

@ -1,14 +0,0 @@
// TODO 可以挪到它对应的 api.ts 文件里哈
/**
*
*/
export enum LimitConfType {
/**
*
*/
CUSTOMER_QUANTITY_LIMIT = 1,
/**
*
*/
CUSTOMER_LOCK_LIMIT = 2
}

View File

@ -1,20 +0,0 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-tabs>
<el-tab-pane label="拥有客户数限制">
<!-- TODO @wanwanCustomerLimitConfigList因为它是列表哈 -->
<CustomerLimitConfDetails :confType="LimitConfType.CUSTOMER_QUANTITY_LIMIT" />
</el-tab-pane>
<el-tab-pane label="锁定客户数限制">
<CustomerLimitConfDetails :confType="LimitConfType.CUSTOMER_LOCK_LIMIT" />
</el-tab-pane>
</el-tabs>
</ContentWrap>
</template>
<script setup lang="ts">
import CustomerLimitConfDetails from '@/views/crm/customerLimitConfig/CustomerLimitConfDetails.vue'
import { LimitConfType } from '@/views/crm/customerLimitConfig/customerLimitConf'
defineOptions({ name: 'CrmCustomerLimitConfig' })
</script>