From 4a23e2e68c35721d270242b87589b1e94d64d8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Thu, 5 Mar 2026 16:32:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(credit):=20=E6=96=B0=E5=A2=9E=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E5=92=8C=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9F=A5=E8=AF=A2=E7=BB=9F=E8=AE=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加客户管理页面,支持搜索、筛选、查看跟进状态等功能 - 新增数据查询统计页面,包含订单完成情况、回款金额等图表展示 - 在应用配置中注册新的页面路由 - 更新导航栏标题和样式配置 - 移除订单管理页面的自定义导航栏样式 - 调整首页按钮间距和用户页面背景色 --- src/app.config.ts | 2 + src/credit/customer/index.tsx | 645 ++++++++++++++++++++++++++++++- src/credit/data/index.config.ts | 2 +- src/credit/data/index.tsx | 268 ++++++++++++- src/credit/order/index.config.ts | 3 +- src/credit/order/index.tsx | 64 +-- src/pages/index/index.tsx | 2 +- src/pages/user/user.tsx | 2 +- 8 files changed, 917 insertions(+), 71 deletions(-) diff --git a/src/app.config.ts b/src/app.config.ts index 5ba6c05..916103e 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -120,6 +120,8 @@ export default { { "root": "credit", "pages": [ + "data/index", + "customer/index", "order/index", "order/add", "company/index", diff --git a/src/credit/customer/index.tsx b/src/credit/customer/index.tsx index 5579fc0..7ad9567 100644 --- a/src/credit/customer/index.tsx +++ b/src/credit/customer/index.tsx @@ -1,11 +1,654 @@ +import { useCallback, useMemo, useRef, useState } from 'react' import Taro, { useDidShow } from '@tarojs/taro' import { View, Text } from '@tarojs/components' +import { + Address, + Button, + Cell, + CellGroup, + Checkbox, + ConfigProvider, + Empty, + InfiniteLoading, + Loading, + Popup, + PullToRefresh, + SearchBar, + Tag +} from '@nutui/nutui-react-taro' +import { Copy, Phone } from '@nutui/icons-react-taro' -export default function index() { +import RegionData from '@/api/json/regions-data.json' +import { pageCreditCompany, updateCreditCompany } from '@/api/credit/creditCompany' +import type { CreditCompany } from '@/api/credit/creditCompany/model' +import { listUsers } from '@/api/system/user' +import type { User } from '@/api/system/user/model' +import { hasRole } from '@/utils/permission' + +const PAGE_SIZE = 10 + +type FollowStatus = '全部' | '未联系' | '加微前沟通' | '跟进中' | '已成交' | '无意向' + +const FOLLOW_STATUS_OPTIONS: FollowStatus[] = ['全部', '未联系', '加微前沟通', '跟进中', '已成交', '无意向'] + +const FOLLOW_MAP_STORAGE_KEY = 'credit_company_follow_status_map' + +const safeParseJSON = (v: any): T | null => { + try { + if (!v) return null + if (typeof v === 'object') return v as T + if (typeof v === 'string') return JSON.parse(v) as T + return null + } catch (_e) { + return null + } +} + +const getCompanyIdKey = (c: CreditCompany) => String(c?.id || '') + +const splitPhones = (raw?: string) => { + const text = String(raw || '').trim() + if (!text) return [] + // 常见分隔符:逗号/顿号/分号/换行/空格 + return text + .split(/[\s,,;;、\n\r]+/g) + .map(s => s.trim()) + .filter(Boolean) +} + +const getCompanyPhones = (c: CreditCompany) => { + const arr = [...splitPhones(c.tel), ...splitPhones(c.moreTel)] + return Array.from(new Set(arr)) +} + +const getCompanyIndustry = (c: CreditCompany) => { + // 兼容:不同数据源字段可能不一致,优先取更具体的大类 + return String( + c.nationalStandardIndustryCategories6 || + c.nationalStandardIndustryCategories2 || + c.nationalStandardIndustryCategories || + c.institutionType || + '' + ).trim() +} + +export default function CreditCompanyPage() { + const serverPageRef = useRef(1) + const [list, setList] = useState([]) + const [hasMore, setHasMore] = useState(true) + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + + const [searchValue, setSearchValue] = useState('') + + const [cityVisible, setCityVisible] = useState(false) + const [cityText, setCityText] = useState('全部') + + const [followVisible, setFollowVisible] = useState(false) + const [followStatus, setFollowStatus] = useState('全部') + + const [industryVisible, setIndustryVisible] = useState(false) + const [industryText, setIndustryText] = useState('全部') + + const [selectMode, setSelectMode] = useState(false) + const [selectedIds, setSelectedIds] = useState([]) + + const [staffPopupVisible, setStaffPopupVisible] = useState(false) + const [staffLoading, setStaffLoading] = useState(false) + const [staffList, setStaffList] = useState([]) + const [staffSelectedId, setStaffSelectedId] = useState(undefined) + const [assigning, setAssigning] = useState(false) + + const [followMap, setFollowMap] = useState>(() => { + const raw = Taro.getStorageSync(FOLLOW_MAP_STORAGE_KEY) + return safeParseJSON>(raw) || {} + }) + + const currentUser = useMemo(() => { + return safeParseJSON(Taro.getStorageSync('User')) || ({} as User) + }, []) + + const canAssign = useMemo(() => { + // 超级管理员:允许分配并更改客户归属(userId) + if (currentUser?.isSuperAdmin) return true + if (hasRole('superAdmin')) return true + return false + }, [currentUser?.isSuperAdmin]) + + const cityOptions = useMemo(() => { + // NutUI Address options: [{ text, value, children }] + // @ts-ignore + return (RegionData || []).map(a => ({ + value: a.label, + text: a.label, + children: (a.children || []).map(b => ({ + value: b.label, + text: b.label, + children: (b.children || []).map(c => ({ + value: c.label, + text: c.label + })) + })) + })) + }, []) + + const staffNameMap = useMemo(() => { + const map = new Map() + for (const u of staffList) { + if (!u?.userId) continue + const name = String(u.realName || u.nickname || u.username || `员工${u.userId}`) + map.set(u.userId, name) + } + return map + }, [staffList]) + + const getFollowStatus = useCallback( + (c: CreditCompany): FollowStatus => { + const k = getCompanyIdKey(c) + const stored = k ? followMap[k] : undefined + if (stored) return stored + return '未联系' + }, + [followMap] + ) + + const setFollowStatusFor = async (c: CreditCompany) => { + if (!c?.id) return + try { + const res = await Taro.showActionSheet({ + itemList: FOLLOW_STATUS_OPTIONS.filter(s => s !== '全部') + }) + const next = FOLLOW_STATUS_OPTIONS.filter(s => s !== '全部')[res.tapIndex] as FollowStatus | undefined + if (!next) return + + setFollowMap(prev => { + const k = getCompanyIdKey(c) + const merged = { ...prev, [k]: next } + Taro.setStorageSync(FOLLOW_MAP_STORAGE_KEY, merged) + return merged + }) + + // 若当前正在按状态筛选,则即时移除不匹配项,避免“改完状态但列表不变”的割裂感。 + if (followStatus !== '全部' && next !== followStatus && c.id) { + const cid = Number(c.id) + setList(prev => prev.filter(x => Number(x.id) !== cid)) + setSelectedIds(prev => prev.filter(id => id !== cid)) + } + } catch (e) { + const msg = String((e as any)?.errMsg || (e as any)?.message || e || '') + if (msg.includes('cancel')) return + } + } + + const applyFilters = useCallback( + (incoming: CreditCompany[]) => { + const city = cityText === '全部' ? '' : cityText + const industry = industryText === '全部' ? '' : industryText + const follow = followStatus === '全部' ? '' : followStatus + + return incoming.filter(c => { + if (c?.deleted === 1) return false + + if (city) { + const full = [c.province, c.city, c.region].filter(Boolean).join(' ') + if (!full.includes(city) && String(c.city || '') !== city) return false + } + + if (industry) { + const ind = getCompanyIndustry(c) + if (!ind.includes(industry)) return false + } + + if (follow) { + if (getFollowStatus(c) !== follow) return false + } + + return true + }) + }, + [cityText, followStatus, getFollowStatus, industryText] + ) + + const reload = useCallback( + async (resetPage = false) => { + if (loading) return + setLoading(true) + setError(null) + + if (resetPage) { + serverPageRef.current = 1 + setHasMore(true) + setSelectedIds([]) + setSelectMode(false) + } + + let nextList = resetPage ? [] : list + let page = serverPageRef.current + let serverHasMore = true + + // 当筛选条件较严格时,可能需要多拉几页才能拿到“至少一条匹配数据” + const MAX_PAGE_TRIES = 8 + let tries = 0 + + try { + while (tries < MAX_PAGE_TRIES) { + tries += 1 + const params: any = { + page, + limit: PAGE_SIZE, + keywords: searchValue?.trim() || undefined + } + + const res = await pageCreditCompany(params) + const incoming = (res?.list || []) as CreditCompany[] + const filtered = applyFilters(incoming) + + if (resetPage) { + nextList = filtered + resetPage = false + } else { + nextList = nextList.concat(filtered) + } + + page += 1 + + // 服务端无更多页:终止 + if (incoming.length < PAGE_SIZE) { + serverHasMore = false + break + } + + // 已拿到可展示数据:先返回,让用户继续滚动触发下一次加载 + if (filtered.length > 0) break + } + + serverPageRef.current = page + setList(nextList) + setHasMore(serverHasMore) + } catch (e) { + console.error('加载客户列表失败:', e) + setError('加载失败,请重试') + setHasMore(false) + } finally { + setLoading(false) + } + }, + [applyFilters, list, loading, searchValue] + ) + + const handleRefresh = useCallback(async () => { + await reload(true) + }, [reload]) + + const loadMore = useCallback(async () => { + if (loading || !hasMore) return + await reload(false) + }, [hasMore, loading, reload]) + + useDidShow(() => { + reload(true).then() + // 预加载员工列表,保证“跟进人(realName)”可展示 + ensureStaffLoaded().then() + }) + + const visibleIndustryOptions = useMemo(() => { + const uniq = new Set() + for (const m of list) { + const ind = getCompanyIndustry(m) + if (ind) uniq.add(ind) + } + const arr = Array.from(uniq) + arr.sort() + return ['全部'].concat(arr) + }, [list]) + + const toggleSelectId = (companyId?: number, checked?: boolean) => { + if (!companyId) return + setSelectedIds(prev => { + if (checked) return prev.includes(companyId) ? prev : prev.concat(companyId) + return prev.filter(id => id !== companyId) + }) + } + + const copyPhones = async () => { + const pool = selectMode && selectedIds.length ? list.filter(c => selectedIds.includes(Number(c.id))) : list + const phones = pool.flatMap(c => getCompanyPhones(c)) + const unique = Array.from(new Set(phones)).filter(Boolean) + if (!unique.length) { + Taro.showToast({ title: '暂无可复制的电话', icon: 'none' }) + return + } + await Taro.setClipboardData({ data: unique.join('\n') }) + Taro.showToast({ title: `已复制${unique.length}个电话`, icon: 'success' }) + } + + const callPhone = async (phone?: string) => { + const num = String(phone || '').trim() + if (!num) { + Taro.showToast({ title: '暂无电话', icon: 'none' }) + return + } + try { + await Taro.makePhoneCall({ phoneNumber: num }) + } catch (e) { + console.error('拨号失败:', e) + Taro.showToast({ title: '拨号失败', icon: 'none' }) + } + } + + const openAddCustomer = () => { + Taro.navigateTo({ url: '/credit/company/add' }) + } + + const ensureStaffLoaded = async () => { + if (staffLoading) return + if (staffList.length) return + setStaffLoading(true) + try { + const res = await listUsers({ isAdmin: true } as any) + setStaffList((res || []) as User[]) + } catch (e) { + console.error('加载员工列表失败:', e) + Taro.showToast({ title: '加载员工失败', icon: 'none' }) + } finally { + setStaffLoading(false) + } + } + + const openAssign = async () => { + if (!canAssign) { + Taro.showToast({ title: '当前角色无分配权限', icon: 'none' }) + return + } + if (!selectMode) { + setSelectMode(true) + setSelectedIds([]) + Taro.showToast({ title: '请选择要分配的客户', icon: 'none' }) + return + } + if (!selectedIds.length) { + Taro.showToast({ title: '请先勾选客户', icon: 'none' }) + return + } + await ensureStaffLoaded() + setStaffPopupVisible(true) + } + + const submitAssign = async () => { + if (!staffSelectedId) { + Taro.showToast({ title: '请选择分配对象', icon: 'none' }) + return + } + if (!selectedIds.length) { + Taro.showToast({ title: '请先勾选客户', icon: 'none' }) + return + } + + setAssigning(true) + try { + for (const id of selectedIds) { + await updateCreditCompany({ id, userId: staffSelectedId } as any) + } + Taro.showToast({ title: '分配成功', icon: 'success' }) + setStaffPopupVisible(false) + setSelectMode(false) + setSelectedIds([]) + await reload(true) + } catch (e) { + console.error('分配失败:', e) + Taro.showToast({ title: '分配失败,请重试', icon: 'none' }) + } finally { + setAssigning(false) + } + } return ( + + + reload(true)} + /> + + + + + + + + + + {!!error && ( + + {error} + + )} + + + + {list.length === 0 && !loading ? ( + + + + ) : ( + + + 加载中... + + } + loadMoreText={ + + {list.length === 0 ? '暂无数据' : '没有更多了'} + + } + > + {list.map((c, idx) => { + const id = Number(c.id) + const selected = !!id && selectedIds.includes(id) + const follow = getFollowStatus(c) + const ownerName = + // 兼容后端可能直接下发跟进人字段 + (c as any)?.realName || + (c as any)?.userRealName || + (c as any)?.followRealName || + (c.userId ? staffNameMap.get(Number(c.userId)) : undefined) + const name = c.matchName || c.name || `企业${c.id || ''}` + const industry = getCompanyIndustry(c) + const phones = getCompanyPhones(c) + const primaryPhone = phones[0] + return ( + + { + if (selectMode) return + if (!c?.id) return + Taro.navigateTo({ url: `/credit/company/detail?id=${c.id}` }) + }} + > + + {selectMode && ( + { + e.stopPropagation() + }} + > + toggleSelectId(id, checked)} + /> + + )} + + + + + + {name} + + {!!industry && ( + + {industry} + + )} + + { + e?.stopPropagation?.() + setFollowStatusFor(c) + }} + > + {follow} + + + + + + + {primaryPhone ? primaryPhone : '暂无电话'} + + + 跟进人:{ownerName || '未分配'} + + + + + + + + + {!!(c.province || c.city || c.region) && ( + + {[c.province, c.city, c.region].filter(Boolean).join(' ')} + + )} + + + + + ) + })} + + )} + + + + + + + + + + {selectMode && ( + + 已选 {selectedIds.length} 个 + + copyPhones()} + > + 复制所选电话 + + { + setSelectMode(false) + setSelectedIds([]) + }} + > + 取消 + + + + )} + + +
{ + const txt = value.filter(Boolean).slice(0, 2).join(' ') + setCityText(txt || '全部') + setCityVisible(false) + reload(true).then() + }} + onClose={() => setCityVisible(false)} + /> + + setFollowVisible(false)} + > + + + 跟进状态 + setFollowVisible(false)}> + 关闭 + + + + {FOLLOW_STATUS_OPTIONS.map(s => ( + {s}} + onClick={() => { + setFollowStatus(s) + setFollowVisible(false) + reload(true).then() + }} + /> + ))} + + + + + ) } diff --git a/src/credit/data/index.config.ts b/src/credit/data/index.config.ts index ddd1d6d..90d3ce3 100644 --- a/src/credit/data/index.config.ts +++ b/src/credit/data/index.config.ts @@ -1,5 +1,5 @@ export default definePageConfig({ - navigationBarTitleText: '数据查询', + navigationBarTitleText: '数据查询统计', navigationBarTextStyle: 'black', navigationBarBackgroundColor: '#ffffff' }) diff --git a/src/credit/data/index.tsx b/src/credit/data/index.tsx index 5579fc0..61ad4b8 100644 --- a/src/credit/data/index.tsx +++ b/src/credit/data/index.tsx @@ -1,11 +1,273 @@ +import { useEffect, useMemo, useRef, useState } from 'react' import Taro, { useDidShow } from '@tarojs/taro' import { View, Text } from '@tarojs/components' +import { ConfigProvider, DatePicker } from '@nutui/nutui-react-taro' +import { EChart } from 'echarts-taro3-react' +import dayjs from 'dayjs' -export default function index() { +type RangePreset = '近6个月' | '近12个月' +type TimeMode = '当日' | '当月' | '当年' +const formatYmd = (d?: Date | null) => { + if (!d) return '' + return dayjs(d).format('YYYY-MM-DD') +} + +const makeMonthLabels = (count: number) => { + const now = dayjs() + const arr: string[] = [] + for (let i = count - 1; i >= 0; i--) { + arr.push(`${now.subtract(i, 'month').month() + 1}月`) + } + return arr +} + +const buildLineOption = (months: string[], series: { name: string; data: number[]; color: string }[]) => { + return { + grid: { left: 36, right: 18, top: 28, bottom: 32, containLabel: false }, + tooltip: { trigger: 'axis' }, + xAxis: { + type: 'category', + data: months, + boundaryGap: false, + axisLine: { lineStyle: { color: '#e5e7eb' } }, + axisTick: { show: false }, + axisLabel: { color: '#6b7280', fontSize: 10 } + }, + yAxis: { + type: 'value', + min: 0, + max: 600000, + splitNumber: 3, + axisLine: { show: false }, + axisTick: { show: false }, + axisLabel: { + color: '#6b7280', + fontSize: 10, + formatter: (v: number) => (v >= 10000 ? `${Math.round(v / 10000)}w` : `${v}`) + }, + splitLine: { lineStyle: { color: '#f3f4f6' } } + }, + series: series.map(s => ({ + name: s.name, + type: 'line', + data: s.data, + symbol: 'circle', + symbolSize: 6, + showSymbol: true, + lineStyle: { width: 2, color: s.color }, + itemStyle: { color: s.color }, + label: { show: true, color: s.color, fontSize: 10, position: 'top' } + })) + } +} + +function Annotation({ + num, + text, + className +}: { + num: 1 | 2 | 3 | 4 + text: string + className: string +}) { return ( - - + + + + {num} + + + {text} + + + + ) +} + +export default function CreditDataPage() { + + const [rangePreset, setRangePreset] = useState('近6个月') + const months = useMemo(() => makeMonthLabels(rangePreset === '近6个月' ? 6 : 12), [rangePreset]) + + const [timeMode, setTimeMode] = useState('当月') + const [picking, setPicking] = useState<'start' | 'end'>('start') + const [datePickerVisible, setDatePickerVisible] = useState(false) + const [startDate, setStartDate] = useState(null) + const [endDate, setEndDate] = useState(null) + + const chartRef = useRef() + + const chartOption = useMemo(() => { + const len = months.length + const scale = rangePreset === '近6个月' ? 1 : 0.9 + + // 近似还原示意图:5月附近峰值,最后一个月回落。 + const mk = (base: number, peak: number) => { + const out: number[] = [] + for (let i = 0; i < len; i++) { + const t = i / Math.max(1, len - 1) + const wave = Math.sin(t * Math.PI) * peak + out.push(Math.round((base + wave) * scale)) + } + if (out.length) out[out.length - 1] = Math.round(out[out.length - 1] * 0.55) + return out + } + + const series = [ + { name: '订单完成情况', data: mk(180000, 220000), color: '#ec4899' }, + { name: '回款金额情况', data: mk(120000, 160000), color: '#22c55e' }, + { name: '提成获取情况', data: mk(90000, 120000), color: '#3b82f6' } + ] + return buildLineOption(months, series) + }, [months, rangePreset]) + + useEffect(() => { + if (chartRef.current) chartRef.current.refresh(chartOption) + }, [chartOption]) + + useDidShow(() => { + if (chartRef.current) chartRef.current.refresh(chartOption) + }) + + const pickRangePreset = async () => { + try { + const options: RangePreset[] = ['近6个月', '近12个月'] + const res = await Taro.showActionSheet({ itemList: options }) + const next = options[res.tapIndex] + if (next) setRangePreset(next) + } catch (e) { + const msg = String((e as any)?.errMsg || (e as any)?.message || e || '') + if (msg.includes('cancel')) return + console.error('选择时间范围失败:', e) + } + } + + const followSteps = useMemo(() => { + return [ + { name: '跟进第一步', count: 50 }, + { name: '跟进第二步', count: 20 }, + { name: '跟进第三步', count: 20 }, + { name: '跟进第四步', count: 20 }, + { name: '跟进第五步', count: 20 }, + { name: '跟进第六步', count: 20 } + ] + }, []) + + return ( + + + + + + 数据查询统计 + + {rangePreset} + + + + + + + + + + + + + + + 跟进统计数据 + + {(['当日', '当月', '当年'] as TimeMode[]).map(m => ( + setTimeMode(m)} + > + {m} + + ))} + + + + + { + setPicking('start') + setDatePickerVisible(true) + }} + > + {formatYmd(startDate) || '请选择开始时间'} + + { + setPicking('end') + setDatePickerVisible(true) + }} + > + {formatYmd(endDate) || '请选择结束时间'} + + + + + {followSteps.map(s => ( + + {s.name} + {s.count}个 + + ))} + + + + + + + setDatePickerVisible(false)} + onCancel={() => setDatePickerVisible(false)} + onConfirm={(_options, selectedValue) => { + const [y, m, d] = (selectedValue || []).map(v => Number(v)) + const next = new Date(y, (m || 1) - 1, d || 1, 0, 0, 0) + + if (picking === 'start') { + setStartDate(next) + if (endDate && dayjs(endDate).isBefore(next, 'day')) setEndDate(null) + } else { + setEndDate(next) + if (startDate && dayjs(next).isBefore(startDate, 'day')) setStartDate(null) + } + setDatePickerVisible(false) + }} + /> + ) } diff --git a/src/credit/order/index.config.ts b/src/credit/order/index.config.ts index 19a2888..9a59489 100644 --- a/src/credit/order/index.config.ts +++ b/src/credit/order/index.config.ts @@ -1,6 +1,5 @@ export default definePageConfig({ navigationBarTitleText: '订单管理', navigationBarTextStyle: 'black', - navigationBarBackgroundColor: '#ffffff', - navigationStyle: 'custom' + navigationBarBackgroundColor: '#ffffff' }) diff --git a/src/credit/order/index.tsx b/src/credit/order/index.tsx index f3a1f81..f8eb5d0 100644 --- a/src/credit/order/index.tsx +++ b/src/credit/order/index.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from 'react' import Taro from '@tarojs/taro' import { View, Text } from '@tarojs/components' import { Button, ConfigProvider, DatePicker, Empty, Input, Popup } from '@nutui/nutui-react-taro' -import { Search, Setting } from '@nutui/icons-react-taro' +import { Search } from '@nutui/icons-react-taro' import dayjs from 'dayjs' type PayStatus = '全部回款' | '部分回款' | '未回款' @@ -79,14 +79,6 @@ const makeMockOrders = (page: number): OrderItem[] => { } export default function CreditOrderPage() { - const statusBarHeight = useMemo(() => { - try { - const info = Taro.getSystemInfoSync() - return Number(info?.statusBarHeight || 0) - } catch (_e) { - return 0 - } - }, []) const [rawList, setRawList] = useState(() => makeMockOrders(1)) const [mockPage, setMockPage] = useState(1) @@ -193,62 +185,10 @@ export default function CreditOrderPage() { Taro.showToast({ title: '已加载更多', icon: 'none' }) } - const headerOffset = statusBarHeight + 80 - return ( - - - 12:00 - - 信号 - Wi-Fi - 电池 - - - - - Taro.navigateBack()}> - 返回 - - 订单管理 - - { - try { - const res = await Taro.showActionSheet({ itemList: ['新建订单', '刷新'] }) - if (res.tapIndex === 0) Taro.navigateTo({ url: '/credit/order/add' }) - if (res.tapIndex === 1) { - setSearchValue('') - setAmountSort('默认') - setPayFilter('全部回款') - setStartDate(null) - setEndDate(null) - setMockPage(1) - setRawList(makeMockOrders(1)) - Taro.showToast({ title: '已刷新', icon: 'none' }) - } - } catch (e) { - const msg = String((e as any)?.errMsg || (e as any)?.message || e || '') - if (msg.includes('cancel')) return - } - }} - > - ... - - Taro.showToast({ title: '设置(示意)', icon: 'none' })} - > - - - - - - - + diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 56156ef..0d3a60a 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -147,7 +147,7 @@ function Home() { {admin && ( - + navTo('/credit/company/index', true)}> 客户管理 diff --git a/src/pages/user/user.tsx b/src/pages/user/user.tsx index afeec9e..0b496bf 100644 --- a/src/pages/user/user.tsx +++ b/src/pages/user/user.tsx @@ -15,7 +15,7 @@ function User() { // 仅覆盖个人中心页顶部背景为红色(不影响全局主题) const pagePrimaryBackground = { ...themeStyles.primaryBackground, - background: '#ff0000' + background: '#cf1313' } // TabBar 页在小程序里通常不会销毁;从“注册/申请”页返回时需要触发子组件重新初始化/拉取最新状态。 const [dealerViewKey, setDealerViewKey] = useState(0)