feat(dealer): 调整客户报备功能以支持房号信息管理

- 移除 useUser hook 的使用,不再依赖用户信息
- 新增房号信息处理函数:buildHouseKey、buildHouseDisplay 和 parseHouseKey
- 添加房号相关必填字段校验(小区、楼栋号、房号、姓名)
- 修改报备逻辑:使用房号作为唯一键进行重复检查
- 优化报备保护期逻辑:区分已签约/已取消和跟进中的状态
- 调整表单字段:将公司信息改为小区楼栋房号信息
- 更新数据提交格式:dealerName 存储展示文案,dealerCode 存储唯一键
- 添加编辑模式下房号信息的回填功能
- 移除对用户ID的依赖,简化报备流程
This commit is contained in:
2026-01-21 17:42:45 +08:00
parent 12858c6a3e
commit 8d67732c7a
2 changed files with 124 additions and 44 deletions

View File

@@ -57,6 +57,7 @@ export interface ShopDealerApplyParam extends PageParam {
applyId?: number;
type?: number;
dealerName?: string;
dealerCode?: string;
mobile?: string;
userId?: number;
keywords?: string;

View File

@@ -5,7 +5,6 @@ import Taro from '@tarojs/taro'
import {useRouter} from '@tarojs/taro'
import {View, Text} from '@tarojs/components'
import FixedButton from "@/components/FixedButton";
import {useUser} from "@/hooks/useUser";
import {ShopDealerApply} from "@/api/shop/shopDealerApply/model";
import {
addShopDealerApply, getShopDealerApply, pageShopDealerApply,
@@ -19,7 +18,6 @@ import {ShopDealerUser} from "@/api/shop/shopDealerUser/model";
import {getShopDealerUser, pageShopDealerUser} from "@/api/shop/shopDealerUser";
const AddShopDealerApply = () => {
const {user} = useUser()
const {params} = useRouter();
const [loading, setLoading] = useState<boolean>(true)
const [FormData, setFormData] = useState<ShopDealerApply>()
@@ -28,6 +26,33 @@ const AddShopDealerApply = () => {
const [existingApply, setExistingApply] = useState<ShopDealerApply | null>(null)
const [referee, setReferee] = useState<ShopDealerUser>()
// 房号信息:用 dealerCode 存储唯一键dealerName 存储展示文案
const buildHouseKey = (community: string, buildingNo: string, unitNo: string | undefined, roomNo: string) => {
const c = (community || '').trim();
const b = (buildingNo || '').trim();
const u = (unitNo || '').trim();
const r = (roomNo || '').trim();
return [c, b, u, r].join('|');
};
const buildHouseDisplay = (community: string, buildingNo: string, unitNo: string | undefined, roomNo: string) => {
const c = (community || '').trim();
const b = (buildingNo || '').trim();
const u = (unitNo || '').trim();
const r = (roomNo || '').trim();
return `${c}${b ? `${b}` : ''}${u ? `${u}单元` : ''}${r ? `${r}` : ''}`;
};
const parseHouseKey = (key?: string) => {
const parts = (key || '').split('|');
return {
community: parts[0] || '',
buildingNo: parts[1] || '',
unitNo: parts[2] || '',
roomNo: parts[3] || '',
};
};
// 日期选择器状态
const [showApplyTimePicker, setShowApplyTimePicker] = useState<boolean>(false)
const [showContractTimePicker, setShowContractTimePicker] = useState<boolean>(false)
@@ -136,6 +161,24 @@ const AddShopDealerApply = () => {
const submitSucceed = async (values: any) => {
try {
// 房号相关必填校验
if (!values.address || values.address.trim() === '') {
Taro.showToast({title: '请选择/填写小区', icon: 'error'});
return;
}
if (!values.buildingNo || values.buildingNo.trim() === '') {
Taro.showToast({title: '请填写楼栋号', icon: 'error'});
return;
}
if (!values.roomNo || values.roomNo.trim() === '') {
Taro.showToast({title: '请填写房号', icon: 'error'});
return;
}
if (!values.realName || values.realName.trim() === '') {
Taro.showToast({title: '请填写姓名', icon: 'error'});
return;
}
// 验证必填字段
if (!values.mobile || values.mobile.trim() === '') {
Taro.showToast({
@@ -167,51 +210,63 @@ const AddShopDealerApply = () => {
}
}
// 检查客户是否已存在
const res = await pageShopDealerApply({dealerName: values.dealerName, type: 4, applyStatus: 10});
const houseKey = buildHouseKey(values.address, values.buildingNo, values.unitNo, values.roomNo);
const houseDisplay = buildHouseDisplay(values.address, values.buildingNo, values.unitNo, values.roomNo);
// 检查房号是否已报备
const res = await pageShopDealerApply({dealerCode: houseKey, type: 4});
if (res && res.count > 0) {
const existingCustomer = res.list[0];
// 检查是否在7天保护期内
if (!isEditMode && existingCustomer.applyTime) {
// 将申请时间字符串转换为时间戳进行比较
if (!isEditMode) {
// 已签约/已取消:直接提示已报备
if (existingCustomer.applyStatus && existingCustomer.applyStatus !== 10) {
Taro.showToast({
title: `该房号信息已报备(${getApplyStatusText(existingCustomer.applyStatus)}`,
icon: 'none',
duration: 2500
});
return false;
}
// 跟进中:保留 7 天保护期逻辑
if (existingCustomer.applyTime) {
const applyTimeStamp = new Date(existingCustomer.applyTime).getTime();
const currentTimeStamp = new Date().getTime();
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000; // 7天的毫秒数
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000;
// 如果在7天保护期内不允许重复添加
if (currentTimeStamp - applyTimeStamp < sevenDaysInMs) {
const remainingDays = Math.ceil((sevenDaysInMs - (currentTimeStamp - applyTimeStamp)) / (24 * 60 * 60 * 1000));
Taro.showToast({
title: `客户还在保护期,还需等待${remainingDays}后才能重新添加`,
title: `房号信息已报备,保护期剩余${remainingDays}`,
icon: 'none',
duration: 3000
});
return false;
} else {
// 超过7天保护期可以重新添加显示确认对话框
}
// 超过保护期:询问是否重新报备
const modalResult = await new Promise<boolean>((resolve) => {
Taro.showModal({
title: '提示',
content: '该客户已超过7天保护期是否重新添加跟进?',
content: '该房号已超过7天保护期是否重新报备跟进?',
showCancel: true,
cancelText: '取消',
confirmText: '确定',
success: (modalRes) => {
resolve(modalRes.confirm);
},
fail: () => {
resolve(false);
}
success: (modalRes) => resolve(modalRes.confirm),
fail: () => resolve(false)
});
});
if (!modalResult) {
return false; // 用户取消,不继续执行
}
// 用户确认后继续执行添加逻辑
if (!modalResult) return false;
} else {
Taro.showToast({
title: '该房号信息已报备',
icon: 'none',
duration: 2500
});
return false;
}
}
}
@@ -221,10 +276,17 @@ const AddShopDealerApply = () => {
const expirationTime = isEditMode ? existingApply?.expirationTime : calculateExpirationTime();
// 准备提交的数据
// 避免把表单里的楼栋/单元/房号等临时字段原样提交给后端
const {buildingNo, unitNo, roomNo, ...restValues} = values;
const submitData = {
...values,
...restValues,
type: 4,
realName: values.realName || user?.nickname,
// 展示用:小区+楼栋+单元+房号
dealerName: houseDisplay,
// 唯一键:用于后续重复报备提示
dealerCode: houseKey,
// 客户姓名/手机号
realName: values.realName,
mobile: values.mobile,
refereeId: referee?.refereeId,
applyStatus: isEditMode ? 20 : 10,
@@ -296,6 +358,21 @@ const AddShopDealerApply = () => {
})
}, []); // 依赖用户ID当用户变化时重新加载
// 编辑模式下,从 dealerCode 反解出楼栋/单元/房号,回填表单(只读展示)
useEffect(() => {
if (!formRef.current || !FormData) return;
const parsed = parseHouseKey(FormData.dealerCode);
formRef.current.setFieldsValue({
address: parsed.community || FormData.address,
buildingNo: parsed.buildingNo,
unitNo: parsed.unitNo,
roomNo: parsed.roomNo,
realName: FormData.realName,
mobile: FormData.mobile,
userId: FormData.userId
});
}, [FormData]);
if (loading) {
return <Loading className={'px-2'}></Loading>
}
@@ -312,21 +389,24 @@ const AddShopDealerApply = () => {
>
<View className={'bg-gray-100 h-3'}></View>
<CellGroup style={{padding: '4px 0'}}>
<Form.Item name="dealerName" label="公司名称" initialValue={FormData?.dealerName} required>
<Input placeholder="公司名称" disabled={isEditMode}/>
<Form.Item name="address" label="小区" initialValue={FormData?.address} required>
<Input placeholder="请选择/填写小区" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="realName" label="联系人" initialValue={FormData?.realName} required>
<Input placeholder="请输入联系人" disabled={isEditMode}/>
<Form.Item name="buildingNo" label="楼栋号" required>
<Input placeholder="请输入楼栋号" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="mobile" label="联系方式" initialValue={FormData?.mobile} required>
<Form.Item name="unitNo" label="单元号">
<Input placeholder="选填" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="roomNo" label="房号" required>
<Input placeholder="请输入房号" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="realName" label="姓名" initialValue={FormData?.realName} required>
<Input placeholder="请输入客户姓名" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="mobile" label="手机号" initialValue={FormData?.mobile} required>
<Input placeholder="请输入手机号" disabled={isEditMode} maxLength={11}/>
</Form.Item>
<Form.Item name="address" label="公司地址" initialValue={FormData?.address} required>
<Input placeholder="请输入详细地址" disabled={isEditMode}/>
</Form.Item>
<Form.Item name="dealerCode" label="户号" initialValue={FormData?.dealerCode} required>
<Input placeholder="请填写户号" disabled={isEditMode}/>
</Form.Item>
{isEditMode && (
<>
<Form.Item name="money" label="签约价格" initialValue={FormData?.money} required>
@@ -368,7 +448,6 @@ const AddShopDealerApply = () => {
placeholder="自己报备请留空"
disabled={isEditMode}
type="number"
value={(FormData?.userId)?.toString() || ''}
/>
</Form.Item>
</CellGroup>