refactor(customer): 优化客户数据查询和表单字段校验
- 移除新增客户页面对手机号的必填和格式校验 - 修改手机号字段标签为“手机号/微信号”,取消必填和长度限制 - 新增判断当前用户是否为超级管理员逻辑 - 抽取并统一构建客户查询参数方法,根据权限动态设置筛选条件 - 优化客户列表数据获取逻辑,支持超级管理员查看全部客户 - 调整依赖项,更新使用了新构建的查询参数函数 - 增强状态统计接口参数构建,统一调用参数生成函数 - 优化副作用 Hook 依赖,保证数据加载时机正确
This commit is contained in:
@@ -3,7 +3,7 @@ import {Loading, CellGroup, Cell, Input, Form, Calendar, Popup, SearchBar} from
|
|||||||
import {Edit, Calendar as CalendarIcon, ArrowRight, Del} from '@nutui/icons-react-taro'
|
import {Edit, Calendar as CalendarIcon, ArrowRight, Del} from '@nutui/icons-react-taro'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import {useRouter} from '@tarojs/taro'
|
import {useRouter} from '@tarojs/taro'
|
||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text, ScrollView} from '@tarojs/components'
|
||||||
import FixedButton from "@/components/FixedButton";
|
import FixedButton from "@/components/FixedButton";
|
||||||
import {ShopDealerApply} from "@/api/shop/shopDealerApply/model";
|
import {ShopDealerApply} from "@/api/shop/shopDealerApply/model";
|
||||||
import {
|
import {
|
||||||
@@ -699,9 +699,9 @@ const AddShopDealerApply = () => {
|
|||||||
position="bottom"
|
position="bottom"
|
||||||
round
|
round
|
||||||
onClose={() => setShowReceptionistPicker(false)}
|
onClose={() => setShowReceptionistPicker(false)}
|
||||||
style={{height: '70%'}}
|
style={{height: '70vh'}}
|
||||||
>
|
>
|
||||||
<View className="flex flex-col h-full">
|
<View style={{height: '100%', display: 'flex', flexDirection: 'column'}}>
|
||||||
{/* 标题栏 */}
|
{/* 标题栏 */}
|
||||||
<View className="flex items-center justify-between px-4 py-3 border-b border-gray-100">
|
<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>
|
<Text className="text-base font-semibold text-gray-800">选择接待人员</Text>
|
||||||
@@ -718,7 +718,10 @@ const AddShopDealerApply = () => {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{/* 列表 */}
|
{/* 列表 */}
|
||||||
<View className="flex-1 overflow-y-auto">
|
<ScrollView
|
||||||
|
scrollY
|
||||||
|
style={{flex: 1, minHeight: 0, height: 'calc(70vh - 112px)'}}
|
||||||
|
>
|
||||||
{receptionistLoading ? (
|
{receptionistLoading ? (
|
||||||
<View className="flex justify-center items-center py-8">
|
<View className="flex justify-center items-center py-8">
|
||||||
<Loading>加载中</Loading>
|
<Loading>加载中</Loading>
|
||||||
@@ -742,7 +745,7 @@ const AddShopDealerApply = () => {
|
|||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</View>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useState, useEffect, useCallback} from 'react'
|
import {useState, useEffect, useCallback, useMemo, useRef} from 'react'
|
||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import Taro, {useDidShow} from '@tarojs/taro'
|
import Taro, {useDidShow} from '@tarojs/taro'
|
||||||
import {Loading, InfiniteLoading, Empty, Space, Tabs, TabPane, Tag, Button, SearchBar} from '@nutui/nutui-react-taro'
|
import {Loading, InfiniteLoading, Empty, Space, Tabs, TabPane, Tag, Button, SearchBar} from '@nutui/nutui-react-taro'
|
||||||
@@ -24,6 +24,10 @@ interface CustomerUser extends UserType {
|
|||||||
protectDays?: number; // 剩余保护天数
|
protectDays?: number; // 剩余保护天数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PAGE_LIMIT = 10;
|
||||||
|
const COUNT_LIMIT = 1;
|
||||||
|
const COUNT_REFRESH_DELAY = 300;
|
||||||
|
|
||||||
const CustomerIndex = () => {
|
const CustomerIndex = () => {
|
||||||
const [list, setList] = useState<CustomerUser[]>([])
|
const [list, setList] = useState<CustomerUser[]>([])
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
@@ -32,33 +36,58 @@ const CustomerIndex = () => {
|
|||||||
const [displaySearchValue, setDisplaySearchValue] = useState<string>('')
|
const [displaySearchValue, setDisplaySearchValue] = useState<string>('')
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [hasMore, setHasMore] = useState(true)
|
const [hasMore, setHasMore] = useState(true)
|
||||||
|
const [statusCounts, setStatusCounts] = useState({
|
||||||
|
all: 0,
|
||||||
|
pending: 0,
|
||||||
|
signed: 0,
|
||||||
|
cancelled: 0
|
||||||
|
});
|
||||||
|
const requestSeqRef = useRef(0)
|
||||||
|
const didShowReadyRef = useRef(false)
|
||||||
|
const countRefreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
|
||||||
// 权限检查:只要登录就能查看客户列表
|
// 权限检查:只要登录就能查看客户列表
|
||||||
const {user, loading: userLoading} = useUser()
|
const {user, loading: userLoading} = useUser()
|
||||||
const roleCheckFinished = !userLoading
|
const roleCheckFinished = !userLoading
|
||||||
const isLoggedIn = roleCheckFinished && user !== null
|
const isLoggedIn = roleCheckFinished && user !== null
|
||||||
const isSuperAdmin = user?.isSuperAdmin === true
|
const isSuperAdmin = user?.isSuperAdmin === true
|
||||||
|
const isAdminRole = user?.isAdmin === true || user?.roles?.some(role => role.roleCode === 'admin') === true
|
||||||
|
const canViewAllCustomers = isSuperAdmin || isAdminRole
|
||||||
|
const currentUserId = Number(Taro.getStorageSync('UserId')) || user?.userId || 0
|
||||||
|
|
||||||
// Tab配置
|
// Tab配置
|
||||||
const tabList = getStatusOptions();
|
const tabList = getStatusOptions();
|
||||||
|
|
||||||
const buildCustomerQueryParams = useCallback((currentPage?: number) => {
|
const buildCustomerQueryParams = useCallback((currentPage?: number, limit?: number) => {
|
||||||
const currentUserId = Number(Taro.getStorageSync('UserId')) || user?.userId || 0;
|
|
||||||
const params: any = {
|
const params: any = {
|
||||||
type: 4
|
type: 4
|
||||||
};
|
};
|
||||||
|
|
||||||
if (currentPage !== undefined) {
|
if (currentPage !== undefined) {
|
||||||
params.page = currentPage;
|
params.page = currentPage;
|
||||||
|
params.limit = limit || PAGE_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSuperAdmin) {
|
if (!canViewAllCustomers) {
|
||||||
params.userId = currentUserId;
|
params.userId = currentUserId;
|
||||||
params.receptionistId = currentUserId;
|
params.receptionistId = currentUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}, [isSuperAdmin, user?.userId]);
|
}, [canViewAllCustomers, currentUserId]);
|
||||||
|
|
||||||
|
const canHandleCustomer = useCallback((customer: ShopDealerApply) => {
|
||||||
|
if (isSuperAdmin) return true;
|
||||||
|
return Number(customer.receptionistId) === currentUserId;
|
||||||
|
}, [currentUserId, isSuperAdmin]);
|
||||||
|
|
||||||
|
const updateStatusCount = useCallback((status: CustomerStatus, count?: number) => {
|
||||||
|
if (count === undefined) return;
|
||||||
|
setStatusCounts(prev => ({
|
||||||
|
...prev,
|
||||||
|
[status]: count
|
||||||
|
}));
|
||||||
|
}, []);
|
||||||
|
|
||||||
// 复制手机号
|
// 复制手机号
|
||||||
const copyPhone = (phone: string) => {
|
const copyPhone = (phone: string) => {
|
||||||
@@ -148,12 +177,6 @@ const CustomerIndex = () => {
|
|||||||
// 转换为天数,向上取整
|
// 转换为天数,向上取整
|
||||||
const remainingDays = Math.ceil(remainingMs / (1000 * 60 * 60 * 24));
|
const remainingDays = Math.ceil(remainingMs / (1000 * 60 * 60 * 24));
|
||||||
|
|
||||||
console.log('=== 基于过期时间计算 ===');
|
|
||||||
console.log('过期时间:', expirationTime);
|
|
||||||
console.log('当前时间:', now.toLocaleString());
|
|
||||||
console.log('剩余天数:', remainingDays);
|
|
||||||
console.log('======================');
|
|
||||||
|
|
||||||
return Math.max(0, remainingDays);
|
return Math.max(0, remainingDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,12 +207,6 @@ const CustomerIndex = () => {
|
|||||||
// 计算剩余保护天数
|
// 计算剩余保护天数
|
||||||
const remainingDays = protectionPeriod - daysPassed;
|
const remainingDays = protectionPeriod - daysPassed;
|
||||||
|
|
||||||
console.log('=== 基于申请时间计算 ===');
|
|
||||||
console.log('申请时间:', applyTime);
|
|
||||||
console.log('已过去天数:', daysPassed);
|
|
||||||
console.log('剩余保护天数:', remainingDays);
|
|
||||||
console.log('======================');
|
|
||||||
|
|
||||||
return Math.max(0, remainingDays);
|
return Math.max(0, remainingDays);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('日期计算错误:', error);
|
console.error('日期计算错误:', error);
|
||||||
@@ -200,19 +217,24 @@ const CustomerIndex = () => {
|
|||||||
|
|
||||||
// 获取客户数据
|
// 获取客户数据
|
||||||
const fetchCustomerData = useCallback(async (statusFilter?: CustomerStatus, resetPage = false, targetPage?: number) => {
|
const fetchCustomerData = useCallback(async (statusFilter?: CustomerStatus, resetPage = false, targetPage?: number) => {
|
||||||
|
const requestSeq = ++requestSeqRef.current;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const currentPage = resetPage ? 1 : (targetPage || 1);
|
const currentPage = resetPage ? 1 : (targetPage || 1);
|
||||||
|
|
||||||
// 构建API参数,根据状态筛选
|
// 构建API参数,根据状态筛选
|
||||||
// 非超管查看自己提交的(userId)或分配给自己的(receptionistId)的客户;超管查询全部
|
// 非管理员查看自己提交的(userId)或分配给自己的(receptionistId)的客户;管理员查询全部
|
||||||
const params = buildCustomerQueryParams(currentPage);
|
const currentStatus = statusFilter || activeTab;
|
||||||
const applyStatus = mapCustomerStatusToApplyStatus(statusFilter || activeTab);
|
const params = buildCustomerQueryParams(currentPage, PAGE_LIMIT);
|
||||||
|
const applyStatus = mapCustomerStatusToApplyStatus(currentStatus);
|
||||||
if (applyStatus !== undefined) {
|
if (applyStatus !== undefined) {
|
||||||
params.applyStatus = applyStatus;
|
params.applyStatus = applyStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await pageShopDealerApply(params);
|
const res = await pageShopDealerApply(params);
|
||||||
|
if (requestSeq !== requestSeqRef.current) return;
|
||||||
|
|
||||||
|
updateStatusCount(currentStatus, res?.count);
|
||||||
|
|
||||||
if (res?.list && res.list.length > 0) {
|
if (res?.list && res.list.length > 0) {
|
||||||
// 正确映射状态并计算保护天数
|
// 正确映射状态并计算保护天数
|
||||||
@@ -230,7 +252,7 @@ const CustomerIndex = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 正确判断是否还有更多数据
|
// 正确判断是否还有更多数据
|
||||||
const hasMoreData = res.list.length >= 10; // 假设每页10条数据
|
const hasMoreData = currentPage * PAGE_LIMIT < (res.count || 0);
|
||||||
setHasMore(hasMoreData);
|
setHasMore(hasMoreData);
|
||||||
} else {
|
} else {
|
||||||
if (resetPage || currentPage === 1) {
|
if (resetPage || currentPage === 1) {
|
||||||
@@ -247,9 +269,11 @@ const CustomerIndex = () => {
|
|||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
if (requestSeq === requestSeqRef.current) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [activeTab, buildCustomerQueryParams]);
|
}, [activeTab, buildCustomerQueryParams, updateStatusCount]);
|
||||||
|
|
||||||
const reloadMore = async () => {
|
const reloadMore = async () => {
|
||||||
if (loading || !hasMore) return; // 防止重复加载
|
if (loading || !hasMore) return; // 防止重复加载
|
||||||
@@ -268,56 +292,63 @@ const CustomerIndex = () => {
|
|||||||
}, [searchValue]);
|
}, [searchValue]);
|
||||||
|
|
||||||
// 根据搜索条件筛选数据(状态筛选已在API层面处理)
|
// 根据搜索条件筛选数据(状态筛选已在API层面处理)
|
||||||
const getFilteredList = () => {
|
const filteredList = useMemo(() => {
|
||||||
let filteredList = list;
|
const keyword = displaySearchValue.trim().toLowerCase();
|
||||||
|
if (!keyword) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
// 按搜索关键词筛选
|
return list.filter(customer =>
|
||||||
if (displaySearchValue.trim()) {
|
|
||||||
const keyword = displaySearchValue.trim().toLowerCase();
|
|
||||||
filteredList = filteredList.filter(customer =>
|
|
||||||
(customer.realName && customer.realName.toLowerCase().includes(keyword)) ||
|
(customer.realName && customer.realName.toLowerCase().includes(keyword)) ||
|
||||||
(customer.dealerName && customer.dealerName.toLowerCase().includes(keyword)) ||
|
(customer.dealerName && customer.dealerName.toLowerCase().includes(keyword)) ||
|
||||||
(customer.dealerCode && customer.dealerCode.toLowerCase().includes(keyword)) ||
|
(customer.dealerCode && customer.dealerCode.toLowerCase().includes(keyword)) ||
|
||||||
(customer.mobile && customer.mobile.includes(keyword)) ||
|
(customer.mobile && customer.mobile.includes(keyword)) ||
|
||||||
(customer.userId && customer.userId.toString().includes(keyword))
|
(customer.userId && customer.userId.toString().includes(keyword))
|
||||||
);
|
);
|
||||||
}
|
}, [displaySearchValue, list]);
|
||||||
|
|
||||||
return filteredList;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取各状态的统计数量
|
|
||||||
const [statusCounts, setStatusCounts] = useState({
|
|
||||||
all: 0,
|
|
||||||
pending: 0,
|
|
||||||
signed: 0,
|
|
||||||
cancelled: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取所有状态的统计数量
|
// 获取所有状态的统计数量
|
||||||
const fetchStatusCounts = useCallback(async () => {
|
const fetchStatusCounts = useCallback(async (skipStatus?: CustomerStatus) => {
|
||||||
try {
|
try {
|
||||||
const baseParams = buildCustomerQueryParams();
|
const baseParams = buildCustomerQueryParams();
|
||||||
|
const countParams = {
|
||||||
|
...baseParams,
|
||||||
|
page: 1,
|
||||||
|
limit: COUNT_LIMIT
|
||||||
|
};
|
||||||
|
const countRequestConfigs = [
|
||||||
|
{status: 'all' as CustomerStatus, params: {...countParams}},
|
||||||
|
{status: 'pending' as CustomerStatus, params: {...countParams, applyStatus: 10}},
|
||||||
|
{status: 'signed' as CustomerStatus, params: {...countParams, applyStatus: 20}},
|
||||||
|
{status: 'cancelled' as CustomerStatus, params: {...countParams, applyStatus: 30}}
|
||||||
|
].filter(item => item.status !== skipStatus);
|
||||||
|
|
||||||
// 并行获取各状态的数量
|
const countResponses = await Promise.all(
|
||||||
const [allRes, pendingRes, signedRes, cancelledRes] = await Promise.all([
|
countRequestConfigs.map(item => pageShopDealerApply(item.params))
|
||||||
pageShopDealerApply({...baseParams}), // 全部
|
);
|
||||||
pageShopDealerApply({...baseParams, applyStatus: 10}), // 跟进中
|
|
||||||
pageShopDealerApply({...baseParams, applyStatus: 20}), // 已签约
|
|
||||||
pageShopDealerApply({...baseParams, applyStatus: 30}) // 已取消
|
|
||||||
]);
|
|
||||||
|
|
||||||
setStatusCounts({
|
setStatusCounts(prev => {
|
||||||
all: allRes?.count || 0,
|
const next = {...prev};
|
||||||
pending: pendingRes?.count || 0,
|
countRequestConfigs.forEach((item, index) => {
|
||||||
signed: signedRes?.count || 0,
|
next[item.status] = countResponses[index]?.count || 0;
|
||||||
cancelled: cancelledRes?.count || 0
|
});
|
||||||
|
return next;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取状态统计失败:', error);
|
console.error('获取状态统计失败:', error);
|
||||||
}
|
}
|
||||||
}, [buildCustomerQueryParams]);
|
}, [buildCustomerQueryParams]);
|
||||||
|
|
||||||
|
const scheduleStatusCountsRefresh = useCallback((skipStatus?: CustomerStatus) => {
|
||||||
|
if (countRefreshTimerRef.current) {
|
||||||
|
clearTimeout(countRefreshTimerRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
countRefreshTimerRef.current = setTimeout(() => {
|
||||||
|
fetchStatusCounts(skipStatus).then();
|
||||||
|
}, COUNT_REFRESH_DELAY);
|
||||||
|
}, [fetchStatusCounts]);
|
||||||
|
|
||||||
const getStatusCounts = () => statusCounts;
|
const getStatusCounts = () => statusCounts;
|
||||||
|
|
||||||
// 取消操作
|
// 取消操作
|
||||||
@@ -335,7 +366,7 @@ const CustomerIndex = () => {
|
|||||||
setPage(1);
|
setPage(1);
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
fetchCustomerData(activeTab, true).then();
|
fetchCustomerData(activeTab, true).then();
|
||||||
fetchStatusCounts().then();
|
scheduleStatusCountsRefresh(activeTab);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -351,15 +382,18 @@ const CustomerIndex = () => {
|
|||||||
setPage(1);
|
setPage(1);
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
fetchCustomerData(activeTab, true).then();
|
fetchCustomerData(activeTab, true).then();
|
||||||
fetchStatusCounts().then();
|
scheduleStatusCountsRefresh(activeTab);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化统计数据
|
// 清理延迟统计刷新定时器
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoggedIn) return;
|
return () => {
|
||||||
fetchStatusCounts().then();
|
if (countRefreshTimerRef.current) {
|
||||||
}, [fetchStatusCounts, isLoggedIn]);
|
clearTimeout(countRefreshTimerRef.current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
// 当activeTab变化时重新获取数据
|
// 当activeTab变化时重新获取数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -368,155 +402,166 @@ const CustomerIndex = () => {
|
|||||||
setPage(1); // 重置页码
|
setPage(1); // 重置页码
|
||||||
setHasMore(true); // 重置加载状态
|
setHasMore(true); // 重置加载状态
|
||||||
fetchCustomerData(activeTab, true);
|
fetchCustomerData(activeTab, true);
|
||||||
}, [activeTab, fetchCustomerData, isLoggedIn]);
|
scheduleStatusCountsRefresh(activeTab);
|
||||||
|
}, [activeTab, fetchCustomerData, isLoggedIn, scheduleStatusCountsRefresh]);
|
||||||
|
|
||||||
// 监听页面显示,当从其他页面返回时刷新数据
|
// 监听页面显示,当从其他页面返回时刷新数据
|
||||||
useDidShow(() => {
|
useDidShow(() => {
|
||||||
if (!isLoggedIn) return;
|
if (!isLoggedIn) return;
|
||||||
|
if (!didShowReadyRef.current) {
|
||||||
|
didShowReadyRef.current = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 刷新当前tab的数据和统计信息
|
// 刷新当前tab的数据和统计信息
|
||||||
setList([]);
|
setList([]);
|
||||||
setPage(1);
|
setPage(1);
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
fetchCustomerData(activeTab, true);
|
fetchCustomerData(activeTab, true);
|
||||||
fetchStatusCounts();
|
scheduleStatusCountsRefresh(activeTab);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 渲染客户项
|
// 渲染客户项
|
||||||
const renderCustomerItem = (customer: CustomerUser) => (
|
const renderCustomerItem = (customer: CustomerUser) => {
|
||||||
<View key={customer.userId} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
|
const canHandle = canHandleCustomer(customer);
|
||||||
<View className="flex items-center mb-3">
|
|
||||||
<View className="flex-1">
|
|
||||||
<View className="flex items-center justify-between mb-1">
|
|
||||||
<Text className="font-semibold text-gray-800 mr-2">
|
|
||||||
{customer.dealerName}
|
|
||||||
</Text>
|
|
||||||
{customer.customerStatus && (
|
|
||||||
<Tag type={getStatusTagType(customer.customerStatus)}>
|
|
||||||
{getStatusText(customer.customerStatus)}
|
|
||||||
</Tag>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<View className="flex items-center mb-1">
|
|
||||||
<Space direction="vertical">
|
|
||||||
<Text className="text-xs text-gray-500">联系人:{customer.realName}</Text>
|
|
||||||
<View className="flex items-center">
|
|
||||||
<Text className="text-xs text-gray-500" onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
makePhoneCall(customer.mobile || '');
|
|
||||||
}}>联系电话:{customer.mobile}</Text>
|
|
||||||
<View className="flex items-center ml-2">
|
|
||||||
<Phone
|
|
||||||
size={12}
|
|
||||||
className="text-green-500 mr-2"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
makePhoneCall(customer.mobile || '');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Text
|
|
||||||
className="text-xs text-blue-500 cursor-pointer"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
copyPhone(customer.mobile || '');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
复制
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<Text className="text-xs text-gray-500">
|
|
||||||
添加时间:{customer.createTime}
|
|
||||||
</Text>
|
|
||||||
</Space>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* 保护天数显示 */}
|
return (
|
||||||
{customer.applyStatus === 10 && (
|
<View key={customer.userId} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
|
||||||
<View className="flex items-center my-1">
|
<View className="flex items-center mb-3">
|
||||||
<Text className="text-xs text-gray-500 mr-2">保护期:</Text>
|
<View className="flex-1">
|
||||||
{customer.protectDays && customer.protectDays > 0 ? (
|
<View className="flex items-center justify-between mb-1">
|
||||||
<Text className={`text-xs px-2 py-1 rounded ${
|
<Text className="font-semibold text-gray-800 mr-2">
|
||||||
customer.protectDays <= 2
|
{customer.dealerName}
|
||||||
? 'bg-red-100 text-red-600'
|
</Text>
|
||||||
: customer.protectDays <= 4
|
{customer.customerStatus && (
|
||||||
? 'bg-orange-100 text-orange-600'
|
<Tag type={getStatusTagType(customer.customerStatus)}>
|
||||||
: 'bg-green-100 text-green-600'
|
{getStatusText(customer.customerStatus)}
|
||||||
}`}>
|
</Tag>
|
||||||
剩余{customer.protectDays}天
|
|
||||||
</Text>
|
|
||||||
) : (
|
|
||||||
<Text className="text-xs px-2 py-1 rounded bg-gray-100 text-gray-500">
|
|
||||||
已过期
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
<View className="flex items-center mb-1">
|
||||||
|
<Space direction="vertical">
|
||||||
<View className={'flex items-center gap-2'}>
|
<Text className="text-xs text-gray-500">联系人:{customer.realName}</Text>
|
||||||
<Text className="text-xs text-gray-500">报备人:{customer?.nickName}</Text>
|
<View className="flex items-center">
|
||||||
<AngleDoubleLeft size={12} className={'text-blue-500'} />
|
<Text className="text-xs text-gray-500" onClick={(e) => {
|
||||||
<Text className={'text-xs text-gray-500'}>{customer?.refereeName}</Text>
|
e.stopPropagation();
|
||||||
</View>
|
makePhoneCall(customer.mobile || '');
|
||||||
|
}}>联系电话:{customer.mobile}</Text>
|
||||||
{/* 接待人员 */}
|
<View className="flex items-center ml-2">
|
||||||
{customer.receptionistName && (
|
<Phone
|
||||||
<View className="flex items-center my-1">
|
size={12}
|
||||||
<Text className="text-xs text-gray-500">接待人员:{customer.receptionistName}</Text>
|
className="text-green-500 mr-2"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
makePhoneCall(customer.mobile || '');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
className="text-xs text-blue-500 cursor-pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
copyPhone(customer.mobile || '');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
复制
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text className="text-xs text-gray-500">
|
||||||
|
添加时间:{customer.createTime}
|
||||||
|
</Text>
|
||||||
|
</Space>
|
||||||
</View>
|
</View>
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 显示 comments 字段 */}
|
{/* 保护天数显示 */}
|
||||||
<Space className="flex items-center">
|
{customer.applyStatus === 10 && (
|
||||||
<Text className="text-xs text-gray-500">跟进情况:{customer.comments || '暂无'}</Text>
|
<View className="flex items-center my-1">
|
||||||
<Text
|
<Text className="text-xs text-gray-500 mr-2">保护期:</Text>
|
||||||
className="text-xs text-blue-500 cursor-pointer"
|
{customer.protectDays && customer.protectDays > 0 ? (
|
||||||
onClick={(e) => {
|
<Text className={`text-xs px-2 py-1 rounded ${
|
||||||
e.stopPropagation();
|
customer.protectDays <= 2
|
||||||
editComments(customer);
|
? 'bg-red-100 text-red-600'
|
||||||
}}
|
: customer.protectDays <= 4
|
||||||
>
|
? 'bg-orange-100 text-orange-600'
|
||||||
编辑
|
: 'bg-green-100 text-green-600'
|
||||||
</Text>
|
}`}>
|
||||||
</Space>
|
剩余{customer.protectDays}天
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text className="text-xs px-2 py-1 rounded bg-gray-100 text-gray-500">
|
||||||
|
已过期
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<View className={'flex items-center gap-2'}>
|
||||||
|
<Text className="text-xs text-gray-500">报备人:{customer?.nickName}</Text>
|
||||||
|
<AngleDoubleLeft size={12} className={'text-blue-500'} />
|
||||||
|
<Text className={'text-xs text-gray-500'}>{customer?.refereeName}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 接待人员 */}
|
||||||
|
{customer.receptionistName && (
|
||||||
|
<View className="flex items-center my-1">
|
||||||
|
<Text className="text-xs text-gray-500">接待人员:{customer.receptionistName}</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 显示 comments 字段 */}
|
||||||
|
<Space className="flex items-center">
|
||||||
|
<Text className="text-xs text-gray-500">跟进情况:{customer.comments || '暂无'}</Text>
|
||||||
|
{canHandle && (
|
||||||
|
<Text
|
||||||
|
className="text-xs text-blue-500 cursor-pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
editComments(customer);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* 跟进中状态显示操作按钮 */}
|
{/* 跟进中状态仅接待人员/超管显示操作按钮 */}
|
||||||
{(customer.applyStatus === 10 && customer.userId == Taro.getStorageSync('UserId')) && (
|
{(customer.applyStatus === 10 && canHandle) && (
|
||||||
<Space className="flex justify-end">
|
<Space className="flex justify-end">
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => navTo(`/dealer/customer/add?id=${customer.applyId}`, true)}
|
onClick={() => navTo(`/dealer/customer/add?id=${customer.applyId}`, true)}
|
||||||
style={{marginRight: '8px', backgroundColor: '#52c41a', color: 'white'}}
|
style={{marginRight: '8px', backgroundColor: '#52c41a', color: 'white'}}
|
||||||
>
|
>
|
||||||
签约
|
签约
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => handleCancel(customer)}
|
onClick={() => handleCancel(customer)}
|
||||||
style={{backgroundColor: '#ff4d4f', color: 'white'}}
|
style={{backgroundColor: '#ff4d4f', color: 'white'}}
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
{(customer.applyStatus === 30 && customer.userId == Taro.getStorageSync('UserId')) && (
|
{(customer.applyStatus === 30 && canHandle) && (
|
||||||
<Space className="flex justify-end">
|
<Space className="flex justify-end">
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => handleDelete(customer)}
|
onClick={() => handleDelete(customer)}
|
||||||
style={{backgroundColor: '#ff4d4f', color: 'white'}}
|
style={{backgroundColor: '#ff4d4f', color: 'white'}}
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染客户列表
|
// 渲染客户列表
|
||||||
const renderCustomerList = () => {
|
const renderCustomerList = () => {
|
||||||
const filteredList = getFilteredList();
|
|
||||||
const isSearching = displaySearchValue.trim().length > 0;
|
const isSearching = displaySearchValue.trim().length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -151,15 +151,14 @@ function UserCard() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={'header-bg pt-20'}>
|
<View className={'header-bg'}>
|
||||||
<View className={'p-4'}>
|
<View className={'user-card-wrap'}>
|
||||||
<View
|
<View
|
||||||
className={'user-card w-full flex flex-col justify-around rounded-xl shadow-sm'}
|
className={'w-full flex flex-col justify-around'}
|
||||||
style={{
|
style={{
|
||||||
background: 'linear-gradient(to bottom, #ffffff, #ffffff)', // 这种情况建议使用类名来控制样式(引入外联样式)
|
|
||||||
// width: '720rpx',
|
// width: '720rpx',
|
||||||
// margin: '10px auto 0px auto',
|
// margin: '10px auto 0px auto',
|
||||||
height: '120px',
|
height: '124px',
|
||||||
// borderRadius: '22px 22px 0 0',
|
// borderRadius: '22px 22px 0 0',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -174,8 +173,8 @@ function UserCard() {
|
|||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<View className={'user-info flex flex-col px-2'}>
|
<View className={'user-info flex flex-col px-3'}>
|
||||||
<View className={'py-1 text-black font-bold max-w-28'}>{getDisplayName()}</View>
|
<View className={'user-card__name py-1 font-bold max-w-28'}>{getDisplayName()}</View>
|
||||||
{isLoggedIn ? (
|
{isLoggedIn ? (
|
||||||
<View className={'grade text-xs py-0'}>
|
<View className={'grade text-xs py-0'}>
|
||||||
<Tag type="success">{getRoleName()}</Tag>
|
<Tag type="success">{getRoleName()}</Tag>
|
||||||
@@ -184,8 +183,8 @@ function UserCard() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={'gap-2 flex items-center'}>
|
<View className={'gap-2 flex items-center'}>
|
||||||
{isAdmin() && <Scan className={'text-gray-900'} size={24} onClick={() => navTo('/user/store/verification', true)} />}
|
{isAdmin() && <Scan className={'user-card__scan'} size={24} onClick={() => navTo('/user/store/verification', true)} />}
|
||||||
<View className={'mr-4 text-sm px-3 py-1 text-black border-gray-400 border-solid border-2 rounded-3xl'}
|
<View className={'user-card__profile mr-4 text-sm px-3 py-1'}
|
||||||
onClick={() => navTo('/user/profile/profile', true)}>
|
onClick={() => navTo('/user/profile/profile', true)}>
|
||||||
{'个人资料'}
|
{'个人资料'}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {Cell} from '@nutui/nutui-react-taro'
|
|||||||
import navTo from "@/utils/common";
|
import navTo from "@/utils/common";
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import {ArrowRight, LogisticsError, Tips, Ask} from '@nutui/icons-react-taro'
|
import {ArrowRight, LogisticsError} from '@nutui/icons-react-taro'
|
||||||
import {useUser} from '@/hooks/useUser'
|
import {useUser} from '@/hooks/useUser'
|
||||||
|
|
||||||
const UserCell = () => {
|
const UserCell = () => {
|
||||||
@@ -26,13 +26,36 @@ const UserCell = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View className={'px-4'}>
|
<View className={'p-4'}>
|
||||||
|
|
||||||
<Cell.Group divider={true} description={
|
<Cell.Group divider={true}>
|
||||||
<View style={{display: 'inline-flex', alignItems: 'center'}}>
|
<Cell
|
||||||
<Text style={{marginTop: '12px'}}>我的服务</Text>
|
className="nutui-cell-clickable"
|
||||||
</View>
|
title="后台管理"
|
||||||
}>
|
align="center"
|
||||||
|
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||||
|
onClick={() => Taro.reLaunch({url: '/pages/index/index'})}
|
||||||
|
/>
|
||||||
|
</Cell.Group>
|
||||||
|
|
||||||
|
<Cell.Group divider={true}>
|
||||||
|
<Cell
|
||||||
|
className="nutui-cell-clickable"
|
||||||
|
title="个人资料"
|
||||||
|
align="center"
|
||||||
|
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||||
|
onClick={() => navTo('/user/profile/profile', true)}
|
||||||
|
/>
|
||||||
|
</Cell.Group>
|
||||||
|
<Cell.Group divider={true}>
|
||||||
|
<Cell
|
||||||
|
className="nutui-cell-clickable"
|
||||||
|
title="退出登录"
|
||||||
|
align="center"
|
||||||
|
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||||
|
onClick={onLogout}
|
||||||
|
/>
|
||||||
|
</Cell.Group>
|
||||||
<Cell
|
<Cell
|
||||||
className="nutui-cell-clickable"
|
className="nutui-cell-clickable"
|
||||||
style={{
|
style={{
|
||||||
@@ -81,62 +104,42 @@ const UserCell = () => {
|
|||||||
{/* navTo('/user/userVerify/index', true)*/}
|
{/* navTo('/user/userVerify/index', true)*/}
|
||||||
{/* }}*/}
|
{/* }}*/}
|
||||||
{/*/>*/}
|
{/*/>*/}
|
||||||
<Cell
|
{/* <Cell*/}
|
||||||
className="nutui-cell-clickable"
|
{/* className="nutui-cell-clickable"*/}
|
||||||
title={
|
{/* title={*/}
|
||||||
<View style={{display: 'inline-flex', alignItems: 'center'}}>
|
{/* <View style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||||
<Ask size={16}/>
|
{/* <Ask size={16}/>*/}
|
||||||
<Text className={'pl-3 text-sm'}>常见问题</Text>
|
{/* <Text className={'pl-3 text-sm'}>常见问题</Text>*/}
|
||||||
</View>
|
{/* </View>*/}
|
||||||
}
|
{/* }*/}
|
||||||
align="center"
|
{/* align="center"*/}
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||||
onClick={() => {
|
{/* onClick={() => {*/}
|
||||||
navTo('/user/help/index')
|
{/* navTo('/user/help/index')*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
/>
|
{/* />*/}
|
||||||
<Cell
|
{/* <Cell*/}
|
||||||
className="nutui-cell-clickable"
|
{/* className="nutui-cell-clickable"*/}
|
||||||
title={
|
{/* title={*/}
|
||||||
<View style={{display: 'inline-flex', alignItems: 'center'}}>
|
{/* <View style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||||
<Tips size={16}/>
|
{/* <Tips size={16}/>*/}
|
||||||
<Text className={'pl-3 text-sm'}>关于我们</Text>
|
{/* <Text className={'pl-3 text-sm'}>关于我们</Text>*/}
|
||||||
</View>
|
{/* </View>*/}
|
||||||
}
|
{/* }*/}
|
||||||
align="center"
|
{/* align="center"*/}
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||||
onClick={() => {
|
{/* onClick={() => {*/}
|
||||||
navTo('/user/about/index')
|
{/* navTo('/user/about/index')*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
/>
|
{/* />*/}
|
||||||
</Cell.Group>
|
{/*</Cell.Group>*/}
|
||||||
<Cell.Group divider={true} description={
|
{/*<Cell.Group divider={true} description={*/}
|
||||||
<View style={{display: 'inline-flex', alignItems: 'center'}}>
|
{/* <View style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||||
<Text style={{marginTop: '12px'}}>账号管理</Text>
|
{/* <Text style={{marginTop: '12px'}}>账号管理</Text>*/}
|
||||||
</View>
|
{/* </View>*/}
|
||||||
}>
|
{/*}>*/}
|
||||||
<Cell
|
|
||||||
className="nutui-cell-clickable"
|
{/*</Cell.Group>*/}
|
||||||
title="个人资料"
|
|
||||||
align="center"
|
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
|
||||||
onClick={() => navTo('/user/profile/profile', true)}
|
|
||||||
/>
|
|
||||||
<Cell
|
|
||||||
className="nutui-cell-clickable"
|
|
||||||
title="返回首页"
|
|
||||||
align="center"
|
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
|
||||||
onClick={() => Taro.reLaunch({url: '/pages/index/index'})}
|
|
||||||
/>
|
|
||||||
<Cell
|
|
||||||
className="nutui-cell-clickable"
|
|
||||||
title="退出登录"
|
|
||||||
align="center"
|
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
|
||||||
onClick={onLogout}
|
|
||||||
/>
|
|
||||||
</Cell.Group>
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const UserFooter = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={'text-center py-4 w-full text-gray-300'} onClick={onLoginByPhone}>
|
<div className={'text-center py-4 w-full text-gray-300 fixed bottom-2'} onClick={onLoginByPhone}>
|
||||||
<div className={'text-xs text-gray-400 py-1'}>当前版本:{Version}</div>
|
<div className={'text-xs text-gray-400 py-1'}>当前版本:{Version}</div>
|
||||||
<div className={'text-xs text-gray-400 py-1'}>Copyright © { new Date().getFullYear() } {Copyright}</div>
|
<div className={'text-xs text-gray-400 py-1'}>Copyright © { new Date().getFullYear() } {Copyright}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
export default definePageConfig({
|
export default definePageConfig({
|
||||||
navigationBarTitleText: '我的',
|
navigationBarTitleText: '我的',
|
||||||
navigationStyle: 'custom',
|
|
||||||
navigationBarBackgroundColor: '#e9fff2'
|
navigationBarBackgroundColor: '#e9fff2'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,73 @@
|
|||||||
.header-bg{
|
.user-page {
|
||||||
background: url('https://oss.wsdns.cn/20250621/edb5d4da976b4d97ba185cb7077d2858.jpg') no-repeat top center;
|
min-height: 100vh;
|
||||||
background-size: 100%;
|
background: linear-gradient(180deg, #f2fbf6 0%, #f8fbff 38%, #f9fafb 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bg {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 12px;
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(34, 197, 94, 0.14) 0%, rgba(56, 189, 248, 0.12) 52%, rgba(245, 158, 11, 0.08) 100%),
|
||||||
|
linear-gradient(135deg, #e8f8ef 0%, #eef7ff 58%, #f9fafb 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bg::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 4px;
|
||||||
|
background: linear-gradient(90deg, #22c55e 0%, #38bdf8 55%, #f59e0b 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card-wrap {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card {
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||||
|
border-radius: 18px !important;
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.98) 0%, rgba(247, 252, 255, 0.94) 100%);
|
||||||
|
box-shadow: 0 12px 28px rgba(15, 23, 42, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card-header {
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card .nut-avatar {
|
||||||
|
border: 3px solid rgba(255, 255, 255, 0.94);
|
||||||
|
box-shadow: 0 8px 18px rgba(15, 23, 42, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card__name {
|
||||||
|
max-width: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #0f172a;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card__profile {
|
||||||
|
border: 1px solid rgba(15, 118, 110, 0.22);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #ecfdf5;
|
||||||
|
color: #0f766e;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-card__scan {
|
||||||
|
padding: 6px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #ecfeff;
|
||||||
|
color: #0f766e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grade .nut-tag {
|
||||||
|
border-radius: 999px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
import {useEffect, useState} from 'react'
|
import {useEffect} from 'react'
|
||||||
import Taro from '@tarojs/taro';
|
// import Taro from '@tarojs/taro';
|
||||||
import UserCard from "./components/UserCard";
|
import UserCard from "./components/UserCard";
|
||||||
import UserOrder from "./components/UserOrder";
|
// import UserOrder from "./components/UserOrder";
|
||||||
import UserCell from "./components/UserCell";
|
import UserCell from "./components/UserCell";
|
||||||
import UserFooter from "./components/UserFooter";
|
import UserFooter from "./components/UserFooter";
|
||||||
import {useUser} from "@/hooks/useUser";
|
import {useUser} from "@/hooks/useUser";
|
||||||
import {NavBar} from '@nutui/nutui-react-taro';
|
// import {NavBar} from '@nutui/nutui-react-taro';
|
||||||
import {Home} from '@nutui/icons-react-taro'
|
// import {Home} from '@nutui/icons-react-taro';
|
||||||
import './user.scss'
|
import './user.scss';
|
||||||
|
|
||||||
function User() {
|
function User() {
|
||||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
// const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||||
const {
|
const {
|
||||||
isAdmin
|
isAdmin
|
||||||
} = useUser();
|
} = useUser();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Taro.getSystemInfo({
|
// Taro.getSystemInfo({
|
||||||
success: (res) => {
|
// success: (res) => {
|
||||||
setStatusBarHeight(res.statusBarHeight)
|
// setStatusBarHeight(res.statusBarHeight)
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,11 +28,9 @@ function User() {
|
|||||||
*/
|
*/
|
||||||
if (isAdmin()) {
|
if (isAdmin()) {
|
||||||
return <>
|
return <>
|
||||||
<div className={'w-full'} style={{
|
<div className={'user-page w-full'}>
|
||||||
background: 'linear-gradient(to bottom, #e9fff2, #f9fafb)'
|
|
||||||
}}>
|
|
||||||
<UserCard/>
|
<UserCard/>
|
||||||
<UserOrder/>
|
{/*<UserOrder/>*/}
|
||||||
<UserCell/>
|
<UserCell/>
|
||||||
<UserFooter/>
|
<UserFooter/>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,31 +39,29 @@ function User() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NavBar
|
{/*<NavBar*/}
|
||||||
fixed={true}
|
{/* fixed={true}*/}
|
||||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
{/* style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}*/}
|
||||||
onBackClick={() => {
|
{/* onBackClick={() => {*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
left={
|
{/* left={*/}
|
||||||
<div style={{
|
{/* <div style={{*/}
|
||||||
display: 'flex',
|
{/* display: 'flex',*/}
|
||||||
alignItems: 'center',
|
{/* alignItems: 'center',*/}
|
||||||
justifyContent: 'center',
|
{/* justifyContent: 'center',*/}
|
||||||
width: '30px',
|
{/* width: '30px',*/}
|
||||||
height: '30px',
|
{/* height: '30px',*/}
|
||||||
backgroundColor: 'white',
|
{/* backgroundColor: 'white',*/}
|
||||||
textAlign: 'center',
|
{/* textAlign: 'center',*/}
|
||||||
borderRadius: '50%',
|
{/* borderRadius: '50%',*/}
|
||||||
}}>
|
{/* }}>*/}
|
||||||
<Home size={15} onClick={() => Taro.reLaunch({url: '/pages/index/index'})} style={{color: 'black', marginBottom: '1px'}} />
|
{/* <Home size={15} onClick={() => Taro.reLaunch({url: '/pages/index/index'})} style={{color: 'black', marginBottom: '1px'}} />*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
}
|
{/* }*/}
|
||||||
>
|
{/*>*/}
|
||||||
<span>我的</span>
|
{/* <span>我的</span>*/}
|
||||||
</NavBar>
|
{/*</NavBar>*/}
|
||||||
<div className={'w-full'} style={{
|
<div className={'user-page w-full'}>
|
||||||
background: 'linear-gradient(to bottom, #e9fff2, #f9fafb)'
|
|
||||||
}}>
|
|
||||||
<UserCard/>
|
<UserCard/>
|
||||||
{/*<UserOrder/>*/}
|
{/*<UserOrder/>*/}
|
||||||
<UserCell/>
|
<UserCell/>
|
||||||
|
|||||||
BIN
小程序系统使用说明书.docx
Normal file
BIN
小程序系统使用说明书.docx
Normal file
Binary file not shown.
BIN
系统使用说明书.docx
Normal file
BIN
系统使用说明书.docx
Normal file
Binary file not shown.
Reference in New Issue
Block a user