feat: 完善部分详情
parent
6edd0826a6
commit
4f219881c2
|
@ -1,5 +1,3 @@
|
|||
import type { PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace CrmPermissionApi {
|
||||
|
@ -57,7 +55,7 @@ export enum PermissionLevelEnum {
|
|||
|
||||
/** 获得数据权限列表(查询团队成员列表) */
|
||||
export function getPermissionList(params: CrmPermissionApi.PermissionListReq) {
|
||||
return requestClient.get<PageResult<CrmPermissionApi.Permission>>(
|
||||
return requestClient.get<CrmPermissionApi.Permission[]>(
|
||||
'/crm/permission/list',
|
||||
{ params },
|
||||
);
|
||||
|
|
|
@ -5,16 +5,18 @@ import { defineAsyncComponent, onMounted, ref } from 'vue';
|
|||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { useTabs } from '@vben/hooks';
|
||||
import { ArrowLeft } from '@vben/icons';
|
||||
|
||||
import { Button, Card, Modal, Tabs } from 'ant-design-vue';
|
||||
|
||||
import { getClue, transformClue } from '#/api/crm/clue';
|
||||
import { BizTypeEnum } from '#/api/crm/permission';
|
||||
import { useDescription } from '#/components/description';
|
||||
import { PermissionList, TransferForm } from '#/views/crm/permission';
|
||||
|
||||
import { useDetailSchema } from '../data';
|
||||
import ClueForm from './form.vue';
|
||||
import TransferForm from './transfer.vue';
|
||||
|
||||
const ClueDetailsInfo = defineAsyncComponent(() => import('./detail-info.vue'));
|
||||
|
||||
|
@ -22,6 +24,7 @@ const loading = ref(false);
|
|||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const tabs = useTabs();
|
||||
|
||||
const clueId = ref(0);
|
||||
|
||||
|
@ -58,6 +61,7 @@ async function loadClueDetail() {
|
|||
|
||||
/** 返回列表页 */
|
||||
function handleBack() {
|
||||
tabs.closeCurrentTab();
|
||||
router.push('/crm/clue');
|
||||
}
|
||||
|
||||
|
@ -68,7 +72,7 @@ function handleEdit() {
|
|||
|
||||
/** 转移线索 */
|
||||
function handleTransfer() {
|
||||
transferModalApi.setData({ id: clueId }).open();
|
||||
transferModalApi.setData({ bizType: BizTypeEnum.CRM_CLUE }).open();
|
||||
}
|
||||
|
||||
/** 转化为客户 */
|
||||
|
@ -141,7 +145,13 @@ onMounted(async () => {
|
|||
<ClueDetailsInfo :clue="clue" />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="团队成员" key="3">
|
||||
<div>团队成员</div>
|
||||
<PermissionList
|
||||
ref="permissionListRef"
|
||||
:biz-id="clue.id!"
|
||||
:biz-type="BizTypeEnum.CRM_CLUE"
|
||||
:show-action="true"
|
||||
@quit-team="handleBack"
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="操作日志" key="4">
|
||||
<div>操作日志</div>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<div>detail-info</div>
|
||||
</template>
|
|
@ -1,7 +1,209 @@
|
|||
<script lang="ts" setup></script>
|
||||
<script setup lang="ts">
|
||||
import type { CrmCustomerApi } from '#/api/crm/customer';
|
||||
import type { SystemOperateLogApi } from '#/api/system/operate-log';
|
||||
|
||||
import { defineAsyncComponent, onMounted, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { Button, Card, Modal, Tabs } from 'ant-design-vue';
|
||||
|
||||
import { getCustomer, updateCustomerDealStatus } from '#/api/crm/customer';
|
||||
import { getOperateLogPage } from '#/api/crm/operateLog';
|
||||
import { BizTypeEnum } from '#/api/crm/permission';
|
||||
import { useDescription } from '#/components/description';
|
||||
import { OperateLog } from '#/components/operate-log';
|
||||
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const CustomerDetailsInfo = defineAsyncComponent(
|
||||
() => import('./detail-info.vue'),
|
||||
);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const customerId = ref(0);
|
||||
|
||||
const customer = ref<CrmCustomerApi.Customer>({} as CrmCustomerApi.Customer);
|
||||
const permissionListRef = ref(); // 团队成员列表 Ref
|
||||
|
||||
const [Description] = useDescription({
|
||||
componentProps: {
|
||||
bordered: false,
|
||||
column: 4,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
/** 加载详情 */
|
||||
async function loadCustomerDetail() {
|
||||
loading.value = true;
|
||||
customerId.value = Number(route.params.id);
|
||||
const data = await getCustomer(customerId.value);
|
||||
await getOperateLog();
|
||||
customer.value = data;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/** 编辑 */
|
||||
function handleEdit() {
|
||||
// formModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 转移线索 */
|
||||
function handleTransfer() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 锁定客户 */
|
||||
function handleLock() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 解锁客户 */
|
||||
function handleUnlock() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 领取客户 */
|
||||
function handleReceive() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 分配客户 */
|
||||
function handleDistributeForm() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 客户放入公海 */
|
||||
function handlePutPool() {
|
||||
// transferModalApi.setData({ id: clueId }).open();
|
||||
}
|
||||
|
||||
/** 更新成交状态操作 */
|
||||
async function handleUpdateDealStatus() {
|
||||
const dealStatus = !customer.value.dealStatus;
|
||||
try {
|
||||
await Modal.confirm({
|
||||
title: '提示',
|
||||
content: `确定更新成交状态为【${dealStatus ? '已成交' : '未成交'}】吗?`,
|
||||
});
|
||||
await updateCustomerDealStatus(customerId.value, dealStatus);
|
||||
Modal.success({
|
||||
title: '成功',
|
||||
content: '更新成交状态成功',
|
||||
});
|
||||
await loadCustomerDetail();
|
||||
} catch {
|
||||
// 用户取消操作
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取操作日志 */
|
||||
const logList = ref<SystemOperateLogApi.OperateLog[]>([]); // 操作日志列表
|
||||
async function getOperateLog() {
|
||||
if (!customerId.value) {
|
||||
return;
|
||||
}
|
||||
const data = await getOperateLogPage({
|
||||
bizType: BizTypeEnum.CRM_CUSTOMER,
|
||||
bizId: customerId.value,
|
||||
});
|
||||
logList.value = data.list;
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
onMounted(async () => {
|
||||
await loadCustomerDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p>待完成</p>
|
||||
</div>
|
||||
<Page auto-content-height :title="customer?.name" :loading="loading">
|
||||
<template #extra>
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
v-if="permissionListRef?.validateWrite"
|
||||
type="primary"
|
||||
@click="handleEdit"
|
||||
v-access:code="['crm:customer:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
</Button>
|
||||
<Button
|
||||
v-if="permissionListRef?.validateOwnerUser"
|
||||
type="primary"
|
||||
@click="handleTransfer"
|
||||
>
|
||||
转移
|
||||
</Button>
|
||||
<Button
|
||||
v-if="permissionListRef?.validateWrite"
|
||||
@click="handleUpdateDealStatus"
|
||||
>
|
||||
更改成交状态
|
||||
</Button>
|
||||
<Button
|
||||
v-if="customer.lockStatus && permissionListRef?.validateOwnerUser"
|
||||
@click="handleUnlock"
|
||||
>
|
||||
解锁
|
||||
</Button>
|
||||
<Button
|
||||
v-if="!customer.lockStatus && permissionListRef?.validateOwnerUser"
|
||||
@click="handleLock"
|
||||
>
|
||||
锁定
|
||||
</Button>
|
||||
<Button v-if="!customer.ownerUserId" @click="handleReceive">
|
||||
领取
|
||||
</Button>
|
||||
<Button v-if="!customer.ownerUserId" @click="handleDistributeForm">
|
||||
分配
|
||||
</Button>
|
||||
<Button
|
||||
v-if="customer.ownerUserId && permissionListRef?.validateOwnerUser"
|
||||
@click="handlePutPool"
|
||||
>
|
||||
放入公海
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
<Card>
|
||||
<Description :data="customer" />
|
||||
</Card>
|
||||
<Card class="mt-4">
|
||||
<Tabs>
|
||||
<Tabs.TabPane tab="跟进记录" key="1">
|
||||
<div>跟进记录</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="基本信息" key="2">
|
||||
<CustomerDetailsInfo />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="联系人" key="3">
|
||||
<div>联系人</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="团队成员" key="4">
|
||||
<div>团队成员</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="商机" key="5">
|
||||
<div>商机</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="合同" key="6">
|
||||
<div>合同</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="回款" key="7">
|
||||
<div>回款</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="操作日志" key="8">
|
||||
<OperateLog :log-list="logList" />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
</Page>
|
||||
</template>
|
||||
|
|
|
@ -114,7 +114,8 @@ const [Modal, modalApi] = useVbenModal({
|
|||
}
|
||||
modalApi.lock();
|
||||
// 提交表单
|
||||
const data = (await formApi.getValues()) as CrmPermissionApi.Permission;
|
||||
let data = (await formApi.getValues()) as CrmPermissionApi.Permission;
|
||||
data = Object.assign(data, formData.value);
|
||||
try {
|
||||
await (formData.value?.ids
|
||||
? updatePermission(data)
|
||||
|
|
|
@ -33,6 +33,8 @@ const emits = defineEmits<{
|
|||
(e: 'quitTeam'): void;
|
||||
}>();
|
||||
|
||||
const gridData = ref<CrmPermissionApi.Permission[]>([]);
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Form,
|
||||
destroyOnClose: true,
|
||||
|
@ -67,6 +69,14 @@ function handleCreate() {
|
|||
}
|
||||
|
||||
function handleEdit() {
|
||||
if (checkedIds.value.length === 0) {
|
||||
message.error('请先选择团队成员后操作!');
|
||||
return;
|
||||
}
|
||||
if (checkedIds.value.length > 1) {
|
||||
message.error('只能选择一个团队成员进行编辑!');
|
||||
return;
|
||||
}
|
||||
formModalApi
|
||||
.setData({
|
||||
bizType: props.bizType,
|
||||
|
@ -112,7 +122,7 @@ async function handleQuit() {
|
|||
.getData()
|
||||
.find(
|
||||
(item) =>
|
||||
item.id === userStore.userInfo?.userId &&
|
||||
item.id === userStore.userInfo?.id &&
|
||||
item.level === PermissionLevelEnum.OWNER,
|
||||
);
|
||||
if (permission) {
|
||||
|
@ -122,7 +132,7 @@ async function handleQuit() {
|
|||
|
||||
const userPermission = gridApi.grid
|
||||
.getData()
|
||||
.find((item) => item.id === userStore.userInfo?.userId);
|
||||
.find((item) => item.id === userStore.userInfo?.id);
|
||||
if (!userPermission) {
|
||||
message.warning('你不是团队成员!');
|
||||
return;
|
||||
|
@ -176,6 +186,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
bizId: props.bizId,
|
||||
bizType: props.bizType,
|
||||
});
|
||||
gridData.value = res;
|
||||
return res;
|
||||
},
|
||||
},
|
||||
|
@ -201,19 +212,19 @@ defineExpose({
|
|||
validateWrite,
|
||||
isPool,
|
||||
});
|
||||
|
||||
watch(
|
||||
() => gridApi.grid.getData(),
|
||||
() => gridData.value,
|
||||
(data) => {
|
||||
isPool.value = false;
|
||||
if (data.length > 0) {
|
||||
isPool.value = gridApi.grid
|
||||
.getData()
|
||||
.some((item) => item.level === PermissionLevelEnum.OWNER);
|
||||
isPool.value = data.some(
|
||||
(item) => item.level === PermissionLevelEnum.OWNER,
|
||||
);
|
||||
validateOwnerUser.value = false;
|
||||
validateWrite.value = false;
|
||||
const userId = userStore.userInfo?.userId;
|
||||
gridApi.grid
|
||||
.getData()
|
||||
const userId = userStore.userInfo?.id;
|
||||
gridData.value
|
||||
.filter((item) => item.userId === userId)
|
||||
.forEach((item) => {
|
||||
if (item.level === PermissionLevelEnum.OWNER) {
|
||||
|
|
Loading…
Reference in New Issue