feat(credit): 重构订单管理页面并优化公司模块功能

- 新增 company/add 和 company/edit 页面路由配置
- 移除 Banner.tsx 中的调试日志
- 从 find.tsx 中移除未使用的 total 状态变量
- 更新 credit/order/index.config.ts 页面标题为订单管理并添加自定义导航栏样式
- 从 credit/company/index.tsx 中移除内联添加客户的对话框相关代码
- 将添加客户按钮跳转到独立的 /credit/company/add 页面
- 为公司列表项添加编辑功能点击事件,可跳转至 /credit/company/edit?id=xx
- 优化信用订单页面结构,替换为新的订单管理界面
- 实现订单搜索、筛选、日期范围选择等功能
- 添加订单统计信息展示(总数、本金、利息)
- 实现模拟数据加载和分页功能
This commit is contained in:
2026-03-05 12:50:57 +08:00
parent 31098f889b
commit f4a1fab4cb
11 changed files with 1035 additions and 762 deletions

View File

@@ -122,7 +122,9 @@ export default {
"pages": [ "pages": [
"order/index", "order/index",
"order/add", "order/add",
"company/index" "company/index",
"company/add",
"company/edit"
] ]
} }
], ],

View File

@@ -0,0 +1,6 @@
export default definePageConfig({
navigationBarTitleText: '添加客户',
navigationBarTextStyle: 'black',
navigationBarBackgroundColor: '#ffffff',
navigationStyle: 'custom'
})

262
src/credit/company/add.tsx Normal file
View File

@@ -0,0 +1,262 @@
import { useMemo, useState } from 'react'
import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import { Address, Button, Cell, CellGroup, ConfigProvider, Input } from '@nutui/nutui-react-taro'
import { Close } from '@nutui/icons-react-taro'
import RegionData from '@/api/json/regions-data.json'
import { addCreditCompany, pageCreditCompany } from '@/api/credit/creditCompany'
import type { CreditCompany } from '@/api/credit/creditCompany/model'
import FixedButton from '@/components/FixedButton'
const shortRegion = (label?: string) => {
const v = String(label || '').trim()
if (!v) return ''
return v
.replace(/壮族自治区|回族自治区|维吾尔自治区|自治区/g, '')
.replace(/省|市/g, '')
}
export default function CreditCompanyAddPage() {
const statusBarHeight = useMemo(() => {
try {
const info = Taro.getSystemInfoSync()
return Number(info?.statusBarHeight || 0)
} catch (_e) {
return 0
}
}, [])
const [name, setName] = useState('')
const [code, setCode] = useState('')
const [industry, setIndustry] = useState('')
const [contact, setContact] = useState('')
const [phones, setPhones] = useState<string[]>([''])
const [province, setProvince] = useState('广西壮族自治区')
const [city, setCity] = useState('南宁市')
const [detailAddress, setDetailAddress] = useState('')
const [projectName, setProjectName] = useState('')
const [regionVisible, setRegionVisible] = useState(false)
const [submitting, setSubmitting] = useState(false)
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 updatePhone = (idx: number, v: string) => {
setPhones(prev => prev.map((p, i) => (i === idx ? v : p)))
}
const addPhone = () => {
setPhones(prev => prev.concat(''))
}
const removePhone = (idx: number) => {
setPhones(prev => prev.filter((_, i) => i !== idx))
}
const submit = async () => {
if (submitting) return
const companyName = name.trim()
if (!companyName) {
Taro.showToast({ title: '请输入客户名称', icon: 'none' })
return
}
const firstPhone = String(phones?.[0] || '').trim()
if (!firstPhone) {
Taro.showToast({ title: '请输入客户联系方式', icon: 'none' })
return
}
setSubmitting(true)
try {
// 先查重:公司名称/统一代码
const keywords = (code.trim() || companyName).trim()
const existsRes = await pageCreditCompany({ page: 1, limit: 1, keywords } as any)
const exists = ((existsRes?.list || []) as CreditCompany[]).some(c => c?.deleted !== 1)
if (exists) {
await Taro.showModal({
title: '提示',
content: '该公司信息已存在,请联系管理员核实',
showCancel: false
})
return
}
const moreTel = phones
.slice(1)
.map(p => String(p || '').trim())
.filter(Boolean)
.join(',')
const payload: CreditCompany = {
name: companyName,
matchName: companyName,
code: code.trim() || undefined,
tel: firstPhone,
moreTel: moreTel || undefined,
province,
city,
address: detailAddress.trim() || undefined,
nationalStandardIndustryCategories: industry.trim() || undefined,
comments: [
contact.trim() ? `联系人:${contact.trim()}` : '',
projectName.trim() ? `项目:${projectName.trim()}` : ''
]
.filter(Boolean)
.join('') || undefined
}
await addCreditCompany(payload)
Taro.showToast({ title: '添加成功', icon: 'success' })
setTimeout(() => {
Taro.navigateBack()
}, 500)
} catch (e) {
console.error('添加客户失败:', e)
Taro.showToast({ title: '添加失败,请重试', icon: 'none' })
} finally {
setSubmitting(false)
}
}
return (
<View className="bg-pink-50 min-h-screen">
<ConfigProvider>
<View
className="fixed z-50 top-0 left-0 right-0 bg-pink-50"
style={{ paddingTop: `${statusBarHeight}px` }}
>
<View className="px-4 h-10 flex items-center justify-between text-sm text-gray-900">
<Text className="font-medium">12:00</Text>
<View className="flex items-center gap-2 text-xs text-gray-600">
<Text></Text>
<Text>Wi-Fi</Text>
<Text></Text>
</View>
</View>
<View className="px-4 pb-2 flex items-center justify-between">
<Text
className="text-sm text-gray-700"
onClick={() => Taro.navigateBack()}
>
</Text>
<Text className="text-base font-semibold text-gray-900"></Text>
<View className="flex items-center gap-3">
<View className="w-7 h-7 rounded-full border border-gray-300 flex items-center justify-center text-gray-700">
<Text>...</Text>
</View>
<View className="w-7 h-7 rounded-full border border-gray-300" />
</View>
</View>
</View>
<View style={{ paddingTop: `${statusBarHeight + 80}px` }} className="max-w-md mx-auto">
<View className="px-3 pt-2 pb-2 text-sm text-gray-500">
<Text></Text>
</View>
<CellGroup>
<Cell title="客户名称*">
<Input value={name} onChange={setName} placeholder="请输入" />
</Cell>
<Cell title="统一代码">
<Input value={code} onChange={setCode} placeholder="请输入" />
</Cell>
<Cell title="所属行业">
<Input value={industry} onChange={setIndustry} placeholder="请输入" />
</Cell>
<Cell title="客户联系人">
<Input value={contact} onChange={setContact} placeholder="请输入" />
</Cell>
<Cell title="客户联系方式*">
<View className="w-full">
{phones.map((p, idx) => (
<View key={idx} className={idx === 0 ? '' : 'mt-2'}>
<View className="flex items-center gap-2">
<View className="flex-1">
<Input value={p} onChange={(v) => updatePhone(idx, v)} placeholder="请输入" />
</View>
{idx > 0 && (
<Button
size="small"
fill="outline"
type="danger"
icon={<Close />}
onClick={() => removePhone(idx)}
>
</Button>
)}
</View>
</View>
))}
<View className="mt-2">
<Text className="text-red-500" onClick={addPhone}>
+
</Text>
</View>
</View>
</Cell>
<Cell
title="所在省份"
description={shortRegion(province) || '请选择'}
onClick={() => setRegionVisible(true)}
/>
<Cell
title="所在地级市"
description={shortRegion(city) || '请选择'}
onClick={() => setRegionVisible(true)}
/>
<Cell title="详细地址">
<Input value={detailAddress} onChange={setDetailAddress} placeholder="请输入" />
</Cell>
<Cell title="项目名称">
<Input value={projectName} onChange={setProjectName} placeholder="请输入" />
</Cell>
</CellGroup>
</View>
<Address
visible={regionVisible}
options={cityOptions as any}
title="选择省市"
onChange={(value: any[]) => {
const arr = (value || []).filter(Boolean)
if (arr[0]) setProvince(arr[0])
if (arr[1]) setCity(arr[1])
setRegionVisible(false)
}}
onClose={() => setRegionVisible(false)}
/>
<FixedButton
text={submitting ? '提交中...' : '确定'}
background="#ef4444"
disabled={submitting}
onClick={submit}
/>
</ConfigProvider>
</View>
)
}

View File

@@ -0,0 +1,7 @@
export default definePageConfig({
navigationBarTitleText: '修改客户信息',
navigationBarTextStyle: 'black',
navigationBarBackgroundColor: '#ffffff',
navigationStyle: 'custom'
})

364
src/credit/company/edit.tsx Normal file
View File

@@ -0,0 +1,364 @@
import { useCallback, useMemo, useState } from 'react'
import Taro, { useDidShow, useRouter } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import { Cell, CellGroup, ConfigProvider, Popup, Tag, TextArea } from '@nutui/nutui-react-taro'
import { getCreditCompany } 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 FixedButton from '@/components/FixedButton'
type CustomerStatus = '保护期内' | '已签约' | '已完成' | '保护期外'
const STATUS_OPTIONS: CustomerStatus[] = ['保护期内', '已签约', '已完成', '保护期外']
const PENDING_EDIT_STORAGE_KEY = 'credit_company_pending_edit_map'
const safeParseJSON = <T,>(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 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 | null) => {
if (!c) return []
const arr = [...splitPhones(c.tel), ...splitPhones(c.moreTel)]
return Array.from(new Set(arr))
}
const getCompanyIndustry = (c?: CreditCompany | null) => {
if (!c) return ''
return String(
c.nationalStandardIndustryCategories6 ||
c.nationalStandardIndustryCategories2 ||
c.nationalStandardIndustryCategories ||
c.institutionType ||
''
).trim()
}
type PendingEdit = {
status: CustomerStatus
remark: string
submittedAt: string
}
const loadPendingMap = (): Record<string, PendingEdit> => {
try {
const raw = Taro.getStorageSync(PENDING_EDIT_STORAGE_KEY)
return safeParseJSON<Record<string, PendingEdit>>(raw) || {}
} catch (_e) {
return {}
}
}
const savePendingMap = (map: Record<string, PendingEdit>) => {
try {
Taro.setStorageSync(PENDING_EDIT_STORAGE_KEY, map)
} catch (_e) {
// ignore
}
}
export default function CreditCompanyEditPage() {
const router = useRouter()
const companyId = Number(router?.params?.id)
const statusBarHeight = useMemo(() => {
try {
const info = Taro.getSystemInfoSync()
return Number(info?.statusBarHeight || 0)
} catch (_e) {
return 0
}
}, [])
const [loading, setLoading] = useState(false)
const [company, setCompany] = useState<CreditCompany | null>(null)
const [staffList, setStaffList] = useState<User[]>([])
const [statusPickerVisible, setStatusPickerVisible] = useState(false)
const [customerStatus, setCustomerStatus] = useState<CustomerStatus>('保护期内')
const [remark, setRemark] = useState('')
const [pending, setPending] = useState(false)
const [pendingAt, setPendingAt] = useState<string | undefined>(undefined)
const [submitting, setSubmitting] = useState(false)
const ensureStaffLoaded = useCallback(async () => {
if (staffList.length) return
try {
const res = await listUsers({ isStaff: true } as any)
setStaffList((res || []) as User[])
} catch (_e) {
// ignore (只影响“跟进人”展示)
}
}, [staffList.length])
const staffNameMap = useMemo(() => {
const map = new Map<number, string>()
for (const u of staffList) {
if (!u?.userId) continue
map.set(u.userId, String(u.realName || u.nickname || u.username || `员工${u.userId}`))
}
return map
}, [staffList])
const followRealName = useMemo(() => {
if (!company?.userId) return ''
return staffNameMap.get(Number(company.userId)) || ''
}, [company?.userId, staffNameMap])
const assignDate = useMemo(() => {
// 兼容:接口未提供“分配日期”字段时,用 updateTime/createTime 兜底展示
return String(company?.updateTime || company?.createTime || '')
}, [company?.createTime, company?.updateTime])
const pendingKey = useMemo(() => (Number.isFinite(companyId) && companyId > 0 ? String(companyId) : ''), [companyId])
const loadCompany = useCallback(async () => {
if (!Number.isFinite(companyId) || companyId <= 0) {
Taro.showToast({ title: '参数错误', icon: 'none' })
return
}
setLoading(true)
try {
const data = await getCreditCompany(companyId)
setCompany(data)
// 从本地 pending map 恢复“待审核”状态与内容(纯前端模拟)
const map = loadPendingMap()
const pendingEdit = pendingKey ? map[pendingKey] : undefined
if (pendingEdit) {
setCustomerStatus(pendingEdit.status)
setRemark(pendingEdit.remark)
setPending(true)
setPendingAt(pendingEdit.submittedAt)
} else {
setCustomerStatus('保护期内')
setRemark('')
setPending(false)
setPendingAt(undefined)
}
} catch (e) {
console.error('加载客户信息失败:', e)
Taro.showToast({ title: '加载失败', icon: 'none' })
} finally {
setLoading(false)
}
}, [companyId, pendingKey])
useDidShow(() => {
loadCompany().then()
ensureStaffLoaded().then()
})
const submitOrWithdraw = async () => {
if (submitting) return
if (!pendingKey) return
// 撤回修改
if (pending) {
setSubmitting(true)
try {
const map = loadPendingMap()
delete map[pendingKey]
savePendingMap(map)
setPending(false)
setPendingAt(undefined)
Taro.showToast({ title: '已撤回,可重新修改', icon: 'success' })
} finally {
setSubmitting(false)
}
return
}
// 提交修改(仅备注 + 状态),进入待审核(纯前端模拟)
const r = remark.trim()
if (!r) {
Taro.showToast({ title: '请填写备注信息', icon: 'none' })
return
}
setSubmitting(true)
try {
const map = loadPendingMap()
const now = new Date().toISOString()
map[pendingKey] = { status: customerStatus, remark: r, submittedAt: now }
savePendingMap(map)
setPending(true)
setPendingAt(now)
Taro.showToast({ title: '提交成功,等待审核', icon: 'success' })
} finally {
setSubmitting(false)
}
}
const phones = useMemo(() => getCompanyPhones(company), [company])
const industry = useMemo(() => getCompanyIndustry(company), [company])
const companyName = String(company?.matchName || company?.name || '')
return (
<View className="bg-pink-50 min-h-screen">
<ConfigProvider>
<View className="fixed z-50 top-0 left-0 right-0 bg-pink-50" style={{ paddingTop: `${statusBarHeight}px` }}>
<View className="px-4 h-10 flex items-center justify-between text-sm text-gray-900">
<Text className="font-medium">12:00</Text>
<View className="flex items-center gap-2 text-xs text-gray-600">
<Text></Text>
<Text>Wi-Fi</Text>
<Text></Text>
</View>
</View>
<View className="px-4 pb-2 flex items-center justify-between">
<Text className="text-sm text-gray-700" onClick={() => Taro.navigateBack()}>
</Text>
<Text className="text-base font-semibold text-gray-900"></Text>
<View className="flex items-center gap-3">
<View className="w-7 h-7 rounded-full border border-gray-300 flex items-center justify-center text-gray-700">
<Text>...</Text>
</View>
<View className="w-7 h-7 rounded-full border border-gray-300" />
</View>
</View>
</View>
<View style={{ paddingTop: `${statusBarHeight + 80}px` }} className="max-w-md mx-auto px-3">
{loading ? (
<View className="py-12 text-center text-gray-500">
<Text>...</Text>
</View>
) : (
<>
<CellGroup>
<Cell title="客户名称" description={companyName || '-'} />
<Cell title="统一代码" description={String(company?.code || '-')} />
<Cell
title="所属行业"
description={
<Text className="text-red-500">
{industry || '-'}
</Text>
}
/>
<Cell title="客户联系人" description={String((company as any)?.contactName || '-')} />
<Cell
title="客户联系方式"
description={
phones.length ? (
<View className="flex flex-col">
{phones.map(p => (
<Text key={p} className="text-gray-600">
{p}
</Text>
))}
</View>
) : (
'-'
)
}
/>
<Cell title="地址" description={String(company?.address || '-')} />
<Cell
title="跟进人"
description={
<Text className="text-blue-600">
{followRealName || '未分配'}
</Text>
}
/>
<Cell title="分配日期" description={assignDate || '-'} />
<Cell
title="客户状态"
description={
<View className="flex items-center gap-2">
<Text className={customerStatus === '保护期内' ? 'text-green-600' : 'text-gray-700'}>
{customerStatus}
</Text>
{pending && <Tag type="warning"></Tag>}
</View>
}
onClick={() => {
if (pending) return
setStatusPickerVisible(true)
}}
/>
</CellGroup>
<View className="mt-3 px-1">
<View className="text-sm text-gray-700 mb-2"></View>
<TextArea
placeholder="请输入客户最新信息情况,管理员审核通过后,客户信息才可变更!"
value={remark}
onChange={(v) => setRemark(v)}
rows={4}
maxLength={500}
showCount
autoHeight
disabled={pending}
/>
{pending && (
<View className="mt-2 text-xs text-gray-500">
{pendingAt ? `${pendingAt}` : ''}
</View>
)}
</View>
</>
)}
</View>
<Popup
visible={statusPickerVisible}
position="bottom"
style={{ height: '45vh' }}
onClose={() => setStatusPickerVisible(false)}
>
<View className="p-4">
<View className="flex items-center justify-between mb-3">
<Text className="text-base font-medium"></Text>
<Text className="text-sm text-gray-500" onClick={() => setStatusPickerVisible(false)}>
</Text>
</View>
<CellGroup>
{STATUS_OPTIONS.map(s => (
<Cell
key={s}
title={<Text className={s === customerStatus ? 'text-blue-600' : ''}>{s}</Text>}
onClick={() => {
setCustomerStatus(s)
setStatusPickerVisible(false)
}}
/>
))}
</CellGroup>
</View>
</Popup>
<FixedButton
text={submitting ? '处理中...' : pending ? '撤回修改' : '确定修改'}
background="#ef4444"
disabled={loading || submitting}
onClick={submitOrWithdraw}
/>
</ConfigProvider>
</View>
)
}

View File

@@ -8,10 +8,8 @@ import {
CellGroup, CellGroup,
Checkbox, Checkbox,
ConfigProvider, ConfigProvider,
Dialog,
Empty, Empty,
InfiniteLoading, InfiniteLoading,
Input,
Loading, Loading,
Popup, Popup,
PullToRefresh, PullToRefresh,
@@ -21,7 +19,7 @@ import {
import { Copy, Phone } from '@nutui/icons-react-taro' import { Copy, Phone } from '@nutui/icons-react-taro'
import RegionData from '@/api/json/regions-data.json' import RegionData from '@/api/json/regions-data.json'
import { addCreditCompany, pageCreditCompany, updateCreditCompany } from '@/api/credit/creditCompany' import { pageCreditCompany, updateCreditCompany } from '@/api/credit/creditCompany'
import type { CreditCompany } from '@/api/credit/creditCompany/model' import type { CreditCompany } from '@/api/credit/creditCompany/model'
import { listUsers } from '@/api/system/user' import { listUsers } from '@/api/system/user'
import type { User } from '@/api/system/user/model' import type { User } from '@/api/system/user/model'
@@ -101,17 +99,6 @@ export default function CreditCompanyPage() {
const [staffSelectedId, setStaffSelectedId] = useState<number | undefined>(undefined) const [staffSelectedId, setStaffSelectedId] = useState<number | undefined>(undefined)
const [assigning, setAssigning] = useState(false) const [assigning, setAssigning] = useState(false)
const [addDialogVisible, setAddDialogVisible] = useState(false)
const [addStep, setAddStep] = useState<'search' | 'form'>('search')
const [addChecking, setAddChecking] = useState(false)
const [addSubmitting, setAddSubmitting] = useState(false)
const [addName, setAddName] = useState('')
const [addCode, setAddCode] = useState('')
const [addPhone, setAddPhone] = useState('')
const [addCityVisible, setAddCityVisible] = useState(false)
const [addCityText, setAddCityText] = useState('')
const [addIndustry, setAddIndustry] = useState('')
const [followMap, setFollowMap] = useState<Record<string, FollowStatus>>(() => { const [followMap, setFollowMap] = useState<Record<string, FollowStatus>>(() => {
const raw = Taro.getStorageSync(FOLLOW_MAP_STORAGE_KEY) const raw = Taro.getStorageSync(FOLLOW_MAP_STORAGE_KEY)
return safeParseJSON<Record<string, FollowStatus>>(raw) || {} return safeParseJSON<Record<string, FollowStatus>>(raw) || {}
@@ -350,83 +337,7 @@ export default function CreditCompanyPage() {
} }
const openAddCustomer = () => { const openAddCustomer = () => {
setAddStep('search') Taro.navigateTo({ url: '/credit/company/add' })
setAddName('')
setAddCode('')
setAddPhone('')
setAddCityText('')
setAddIndustry('')
setAddDialogVisible(true)
}
const checkCompanyExists = async () => {
if (addChecking) return
const name = addName.trim()
const code = addCode.trim()
const keywords = (name || code).trim()
if (!keywords) {
Taro.showToast({ title: '请输入公司名称或统一代码', icon: 'none' })
return
}
setAddChecking(true)
try {
const res = await pageCreditCompany({ page: 1, limit: 1, keywords } as any)
const exists = ((res?.list || []) as CreditCompany[]).some(c => c?.deleted !== 1)
if (exists) {
await Taro.showModal({
title: '提示',
content: '该公司信息已存在,请联系管理员核实',
showCancel: false
})
return
}
// 未存在:进入录入表单
setAddStep('form')
} catch (e) {
console.error('查询公司失败:', e)
Taro.showToast({ title: '查询失败,请重试', icon: 'none' })
} finally {
setAddChecking(false)
}
}
const submitAddCustomer = async () => {
if (addSubmitting) return
const name = addName.trim()
const code = addCode.trim()
const phone = addPhone.trim()
if (!name) {
Taro.showToast({ title: '请输入公司名称', icon: 'none' })
return
}
setAddSubmitting(true)
try {
const regionParts = addCityText.split(' ').map(s => s.trim()).filter(Boolean)
const province = regionParts.length >= 2 ? regionParts[0] : undefined
const city = regionParts.length >= 2 ? regionParts[1] : (regionParts[0] || undefined)
const payload: CreditCompany = {
name,
matchName: name,
code: code || undefined,
tel: phone || undefined,
province,
city,
nationalStandardIndustryCategories: addIndustry || undefined
}
await addCreditCompany(payload)
Taro.showToast({ title: '添加成功', icon: 'success' })
setAddDialogVisible(false)
await reload(true)
} catch (e) {
console.error('添加客户失败:', e)
Taro.showToast({ title: '添加失败,请重试', icon: 'none' })
} finally {
setAddSubmitting(false)
}
} }
const ensureStaffLoaded = async () => { const ensureStaffLoaded = async () => {
@@ -564,10 +475,21 @@ export default function CreditCompanyPage() {
const primaryPhone = phones[0] const primaryPhone = phones[0]
return ( return (
<CellGroup key={c.id || idx} className="mb-3"> <CellGroup key={c.id || idx} className="mb-3">
<Cell> <Cell
onClick={() => {
if (selectMode) return
if (!c?.id) return
Taro.navigateTo({ url: `/credit/company/edit?id=${c.id}` })
}}
>
<View className="flex gap-3 items-start w-full"> <View className="flex gap-3 items-start w-full">
{selectMode && ( {selectMode && (
<View className="pt-1"> <View
className="pt-1"
onClick={(e) => {
e.stopPropagation()
}}
>
<Checkbox <Checkbox
checked={selected} checked={selected}
onChange={(checked) => toggleSelectId(id, checked)} onChange={(checked) => toggleSelectId(id, checked)}
@@ -641,11 +563,11 @@ export default function CreditCompanyPage() {
<View className="h-20 w-full" /> <View className="h-20 w-full" />
<View className="fixed z-50 bottom-0 left-0 right-0 bg-white border-t border-gray-200 px-3 py-3 safe-area-bottom"> <View className="fixed z-50 bottom-0 left-0 right-0 bg-white border-t border-gray-200 px-3 py-3 safe-area-bottom">
<View className="flex justify-between items-center gap-3"> <View className="flex items-center gap-3">
<Button <Button
type="primary" type="primary"
style={{ background: '#ef4444' }} style={{ background: '#ef4444' }}
block className="flex-1"
onClick={openAddCustomer} onClick={openAddCustomer}
> >
@@ -654,7 +576,7 @@ export default function CreditCompanyPage() {
type="primary" type="primary"
style={{ background: canAssign ? '#3b82f6' : '#94a3b8' }} style={{ background: canAssign ? '#3b82f6' : '#94a3b8' }}
disabled={!canAssign || assigning} disabled={!canAssign || assigning}
block className="flex-1"
onClick={openAssign} onClick={openAssign}
> >
{selectMode ? '分配所选' : '分配客户'} {selectMode ? '分配所选' : '分配客户'}
@@ -812,67 +734,6 @@ export default function CreditCompanyPage() {
</View> </View>
</Popup> </Popup>
<Dialog
title={addStep === 'search' ? '添加客户(查重)' : '添加客户'}
visible={addDialogVisible}
confirmText={
addStep === 'search'
? (addChecking ? '查询中...' : '查询')
: (addSubmitting ? '提交中...' : '提交')
}
cancelText="取消"
onCancel={() => {
if (addChecking || addSubmitting) return
setAddDialogVisible(false)
}}
onConfirm={() => {
if (addStep === 'search') return checkCompanyExists()
return submitAddCustomer()
}}
>
<View className="text-sm text-gray-700">
<View className="text-xs text-gray-500 mb-2">
</View>
<CellGroup>
<Cell title="公司名称">
<Input value={addName} onChange={setAddName} placeholder="请输入公司名称" />
</Cell>
<Cell title="统一代码">
<Input value={addCode} onChange={setAddCode} placeholder="请输入统一代码(可选)" />
</Cell>
{addStep === 'form' && (
<>
<Cell title="电话">
<Input value={addPhone} onChange={setAddPhone} placeholder="请输入联系电话(可选)" />
</Cell>
<Cell
title="地区"
description={addCityText || '选择到城市'}
onClick={() => setAddCityVisible(true)}
/>
<Cell title="行业">
<Input value={addIndustry} onChange={setAddIndustry} placeholder="请输入行业(可选)" />
</Cell>
</>
)}
</CellGroup>
<Address
visible={addCityVisible}
options={cityOptions as any}
title="选择地区(到城市)"
onChange={(value: any[]) => {
const txt = value.filter(Boolean).slice(0, 2).join(' ')
setAddCityText(txt)
setAddCityVisible(false)
}}
onClose={() => setAddCityVisible(false)}
/>
</View>
</Dialog>
</ConfigProvider> </ConfigProvider>
</View> </View>
) )

View File

@@ -1,5 +1,6 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '需求列表', navigationBarTitleText: '订单管理',
navigationBarTextStyle: 'black', navigationBarTextStyle: 'black',
navigationBarBackgroundColor: '#ffffff' navigationBarBackgroundColor: '#ffffff',
navigationStyle: 'custom'
}) })

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,6 @@ const Find = () => {
const [storeList, setStoreList] = useState<ShopStoreView[]>([]) const [storeList, setStoreList] = useState<ShopStoreView[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [hasMore, setHasMore] = useState(true) const [hasMore, setHasMore] = useState(true)
const [total, setTotal] = useState(0)
const [userLngLat, setUserLngLat] = useState<LngLat | null>(null) const [userLngLat, setUserLngLat] = useState<LngLat | null>(null)
const pageRef = useRef(1) const pageRef = useRef(1)
@@ -86,7 +85,6 @@ const Find = () => {
latestListRef.current = [] latestListRef.current = []
setStoreList([]) setStoreList([])
setHasMore(true) setHasMore(true)
setTotal(0)
} }
try { try {
@@ -112,7 +110,6 @@ const Find = () => {
setStoreList(nextList) setStoreList(nextList)
const count = typeof res?.count === 'number' ? res.count : nextList.length const count = typeof res?.count === 'number' ? res.count : nextList.length
setTotal(count)
setHasMore(nextList.length < count) setHasMore(nextList.length < count)
if (resList.length > 0) { if (resList.length > 0) {

View File

@@ -16,6 +16,7 @@ const MyPage = () => {
} }
const bannerHeight = toCssSize(ad?.height) const bannerHeight = toCssSize(ad?.height)
console.log(bannerHeight)
const reload = async () => { const reload = async () => {
const flash = await getCmsAdByCode('flash') const flash = await getCmsAdByCode('flash')

View File

@@ -19,7 +19,7 @@ function User() {
} }
// TabBar 页在小程序里通常不会销毁;从“注册/申请”页返回时需要触发子组件重新初始化/拉取最新状态。 // TabBar 页在小程序里通常不会销毁;从“注册/申请”页返回时需要触发子组件重新初始化/拉取最新状态。
const [dealerViewKey, setDealerViewKey] = useState(0) const [dealerViewKey, setDealerViewKey] = useState(0)
console.log(dealerViewKey)
// 下拉刷新处理 // 下拉刷新处理
const handleRefresh = async () => { const handleRefresh = async () => {
if (userCardRef.current?.handleRefresh) { if (userCardRef.current?.handleRefresh) {