feat(customer): 新增接待人员选择功能
- 为 ShopDealerApply 模型增加接待人员 ID 和姓名字段 - dealer/customer/add 页面引入 Popup、SearchBar 及图标组件 - 实现接待人员选择弹层及搜索功能 - 表单中新增接待人员展示及清除操作 - 编辑模式下回填接待人员信息 - 提交表单时携带接待人员相关字段 feat(index): 新增首页品牌画册展示组件 - 创建 CatalogShowcase 组件及样式文件 - 展示品牌画册封面及标题说明 - “点击查看”按钮复制链接并提示用户打开浏览器查看 - 在首页主视图添加 CatalogShowcase 组件显示 fix(webview): 优化 webview 页面 URL 获取逻辑 - 使用 useRouter Hook 获取参数替代直接调用 Taro.getCurrentPages -
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import {useEffect, useState, useRef} from "react";
|
||||
import {Loading, CellGroup, Cell, Input, Form, Calendar} from '@nutui/nutui-react-taro'
|
||||
import {Edit, Calendar as CalendarIcon} from '@nutui/icons-react-taro'
|
||||
import {Loading, CellGroup, Cell, Input, Form, Calendar, Popup, SearchBar} from '@nutui/nutui-react-taro'
|
||||
import {Edit, Calendar as CalendarIcon, ArrowRight, Del} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {View, Text} from '@tarojs/components'
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
extractDateForCalendar, formatDateForDisplay
|
||||
} from "@/utils/dateUtils";
|
||||
import {ShopDealerUser} from "@/api/shop/shopDealerUser/model";
|
||||
import {getShopDealerUser} from "@/api/shop/shopDealerUser";
|
||||
import {getShopDealerUser, pageShopDealerUser} from "@/api/shop/shopDealerUser";
|
||||
|
||||
const AddShopDealerApply = () => {
|
||||
const {params} = useRouter();
|
||||
@@ -62,6 +62,13 @@ const AddShopDealerApply = () => {
|
||||
const [applyTime, setApplyTime] = useState<string>('')
|
||||
const [contractTime, setContractTime] = useState<string>('')
|
||||
|
||||
// 接待人员选择状态
|
||||
const [showReceptionistPicker, setShowReceptionistPicker] = useState<boolean>(false)
|
||||
const [receptionistSearch, setReceptionistSearch] = useState<string>('')
|
||||
const [receptionistList, setReceptionistList] = useState<ShopDealerUser[]>([])
|
||||
const [receptionistLoading, setReceptionistLoading] = useState<boolean>(false)
|
||||
const [selectedReceptionist, setSelectedReceptionist] = useState<ShopDealerUser | null>(null)
|
||||
|
||||
// 获取审核状态文字
|
||||
const getApplyStatusText = (status?: number) => {
|
||||
switch (status) {
|
||||
@@ -133,6 +140,15 @@ const AddShopDealerApply = () => {
|
||||
setContractTime(extractDateForCalendar(dealerApply.contractTime))
|
||||
}
|
||||
|
||||
// 回填接待人员
|
||||
if (dealerApply.receptionistId) {
|
||||
setSelectedReceptionist({
|
||||
userId: dealerApply.receptionistId,
|
||||
dealerName: dealerApply.receptionistName || '',
|
||||
realName: dealerApply.receptionistName || '',
|
||||
})
|
||||
}
|
||||
|
||||
Taro.setNavigationBarTitle({title: '签约'})
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -143,6 +159,43 @@ const AddShopDealerApply = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载接待人员列表
|
||||
const loadReceptionistList = async (keyword?: string) => {
|
||||
setReceptionistLoading(true)
|
||||
try {
|
||||
const res = await pageShopDealerUser({keywords: keyword || '', limit: 50, page: 1})
|
||||
setReceptionistList(res?.list || [])
|
||||
} catch (e) {
|
||||
console.error('加载接待人员失败:', e)
|
||||
} finally {
|
||||
setReceptionistLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 打开接待人员选择
|
||||
const openReceptionistPicker = () => {
|
||||
setReceptionistSearch('')
|
||||
loadReceptionistList()
|
||||
setShowReceptionistPicker(true)
|
||||
}
|
||||
|
||||
// 搜索接待人员
|
||||
const handleReceptionistSearch = (val: string) => {
|
||||
setReceptionistSearch(val)
|
||||
loadReceptionistList(val)
|
||||
}
|
||||
|
||||
// 选择接待人员
|
||||
const handleSelectReceptionist = (user: ShopDealerUser) => {
|
||||
setSelectedReceptionist(user)
|
||||
setShowReceptionistPicker(false)
|
||||
}
|
||||
|
||||
// 清除接待人员
|
||||
const handleClearReceptionist = () => {
|
||||
setSelectedReceptionist(null)
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
// 计算保护期过期时间(15天后)
|
||||
const calculateExpirationTime = (): string => {
|
||||
@@ -455,7 +508,10 @@ const AddShopDealerApply = () => {
|
||||
expirationTime: expirationTime,
|
||||
// 确保日期数据正确提交(使用数据库格式)
|
||||
applyTime: values.applyTime || (applyTime ? formatDateForDatabase(applyTime) : ''),
|
||||
contractTime: values.contractTime || (contractTime ? formatDateForDatabase(contractTime) : '')
|
||||
contractTime: values.contractTime || (contractTime ? formatDateForDatabase(contractTime) : ''),
|
||||
// 接待人员
|
||||
receptionistId: selectedReceptionist?.userId || undefined,
|
||||
receptionistName: selectedReceptionist ? (selectedReceptionist.realName || selectedReceptionist.dealerName || '') : undefined,
|
||||
};
|
||||
|
||||
// 调试信息
|
||||
@@ -566,6 +622,31 @@ const AddShopDealerApply = () => {
|
||||
<Form.Item name="mobile" label="手机号" initialValue={FormData?.mobile} required>
|
||||
<Input placeholder="手机号" disabled={isEditMode} maxLength={11}/>
|
||||
</Form.Item>
|
||||
{/* 接待人员选择 */}
|
||||
<Cell
|
||||
title="接待人员"
|
||||
extra={
|
||||
<View className="flex items-center">
|
||||
{selectedReceptionist ? (
|
||||
<View className="flex items-center">
|
||||
<Text className="text-sm text-gray-800 mr-2">
|
||||
{selectedReceptionist.realName || selectedReceptionist.dealerName || '已选择'}
|
||||
</Text>
|
||||
<View
|
||||
onClick={(e) => { e.stopPropagation(); handleClearReceptionist(); }}
|
||||
className="flex items-center px-1"
|
||||
>
|
||||
<Del size={14} color="#999"/>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<Text className="text-sm text-gray-400">请选择</Text>
|
||||
)}
|
||||
<ArrowRight size={14} color="#ccc"/>
|
||||
</View>
|
||||
}
|
||||
onClick={openReceptionistPicker}
|
||||
/>
|
||||
{isEditMode && (
|
||||
<>
|
||||
<Form.Item name="money" label="签约价格" initialValue={FormData?.money} required>
|
||||
@@ -628,6 +709,59 @@ const AddShopDealerApply = () => {
|
||||
onConfirm={handleContractTimeConfirm}
|
||||
/>
|
||||
|
||||
{/* 接待人员选择弹出层 */}
|
||||
<Popup
|
||||
visible={showReceptionistPicker}
|
||||
position="bottom"
|
||||
round
|
||||
onClose={() => setShowReceptionistPicker(false)}
|
||||
style={{height: '70%'}}
|
||||
>
|
||||
<View className="flex flex-col h-full">
|
||||
{/* 标题栏 */}
|
||||
<View className="flex items-center justify-between px-4 py-3 border-b border-gray-100">
|
||||
<Text className="text-base font-semibold text-gray-800">选择接待人员</Text>
|
||||
<View onClick={() => setShowReceptionistPicker(false)}>
|
||||
<Text className="text-sm text-blue-500">取消</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/* 搜索框 */}
|
||||
<View className="px-3 py-2">
|
||||
<SearchBar
|
||||
value={receptionistSearch}
|
||||
placeholder="搜索姓名/手机号"
|
||||
onChange={handleReceptionistSearch}
|
||||
/>
|
||||
</View>
|
||||
{/* 列表 */}
|
||||
<View className="flex-1 overflow-y-auto">
|
||||
{receptionistLoading ? (
|
||||
<View className="flex justify-center items-center py-8">
|
||||
<Loading>加载中</Loading>
|
||||
</View>
|
||||
) : receptionistList.length === 0 ? (
|
||||
<View className="flex justify-center items-center py-8">
|
||||
<Text className="text-sm text-gray-400">暂无数据</Text>
|
||||
</View>
|
||||
) : (
|
||||
receptionistList.map((user) => (
|
||||
<Cell
|
||||
key={user.userId}
|
||||
title={user.realName || user.dealerName || '未知'}
|
||||
description={user.mobile || user.dealerPhone || ''}
|
||||
extra={
|
||||
selectedReceptionist?.userId === user.userId ? (
|
||||
<Text className="text-sm text-blue-500">已选</Text>
|
||||
) : null
|
||||
}
|
||||
onClick={() => handleSelectReceptionist(user)}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</Popup>
|
||||
|
||||
{/* 审核状态显示(仅在编辑模式下显示) */}
|
||||
{isEditMode && (
|
||||
<CellGroup>
|
||||
|
||||
Reference in New Issue
Block a user