提交代码
This commit is contained in:
202
src/hjm/bx/BestSellers.tsx
Normal file
202
src/hjm/bx/BestSellers.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
import React from "react";
|
||||
import {Image, Space, Tag, Button} from '@nutui/nutui-react-taro'
|
||||
import {Truck, User, Shield, Location} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||
|
||||
interface BestSellersProps {
|
||||
data: HjmCar[]
|
||||
onRefresh?: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 车辆列表组件
|
||||
*/
|
||||
const BestSellers: React.FC<BestSellersProps> = ({data, onRefresh}) => {
|
||||
|
||||
// 获取保险状态显示
|
||||
const getInsuranceStatusDisplay = (status?: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return {text: '未投保', color: '#ff4d4f', bgColor: '#fff2f0'}
|
||||
case 1:
|
||||
return {text: '已投保', color: '#52c41a', bgColor: '#f6ffed'}
|
||||
case 2:
|
||||
return {text: '即将到期', color: '#faad14', bgColor: '#fffbe6'}
|
||||
default:
|
||||
return {text: '未知', color: '#8c8c8c', bgColor: '#f5f5f5'}
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到车辆详情
|
||||
const navigateToDetail = (item: HjmCar) => {
|
||||
Taro.navigateTo({
|
||||
url: `/hjm/query?id=${item.id}`
|
||||
})
|
||||
}
|
||||
|
||||
// 快速报险
|
||||
const quickInsurance = (item: HjmCar, event: any) => {
|
||||
event.stopPropagation()
|
||||
Taro.navigateTo({
|
||||
url: `/hjm/bx/bx-add?carId=${item.id}&carCode=${item.code}`
|
||||
})
|
||||
}
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{padding: '0 16px', marginBottom: '16px'}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '12px'
|
||||
}}>
|
||||
{data.map((item, index) => {
|
||||
const insuranceStatus = getInsuranceStatusDisplay(item.insuranceStatus)
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '12px',
|
||||
padding: '16px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
|
||||
border: '1px solid #f0f0f0'
|
||||
}}
|
||||
onClick={() => navigateToDetail(item)}
|
||||
>
|
||||
<div style={{display: 'flex', gap: '12px'}}>
|
||||
{/* 车辆图片 */}
|
||||
<div style={{flexShrink: 0}}>
|
||||
<Image
|
||||
src={item.image || 'https://via.placeholder.com/80x80?text=车辆'}
|
||||
mode="aspectFill"
|
||||
radius="8px"
|
||||
width="80"
|
||||
height="80"
|
||||
style={{
|
||||
border: '1px solid #f0f0f0'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 车辆信息 */}
|
||||
<div style={{flex: 1, minWidth: 0}}>
|
||||
<Space direction="vertical" size={8}>
|
||||
{/* 车辆编号 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<Truck size={16} color="#1890ff"/>
|
||||
<span style={{
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
color: '#262626'
|
||||
}}>
|
||||
{item.code || '未知编号'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* 快递公司 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<Location size={14} color="#8c8c8c"/>
|
||||
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||
快递公司:
|
||||
</span>
|
||||
<span style={{fontSize: '13px', color: '#595959'}}>
|
||||
{item.parentOrganization || '未知'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* 保险状态 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<Shield size={14} color="#8c8c8c"/>
|
||||
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||
保险状态:
|
||||
</span>
|
||||
<Tag
|
||||
color={insuranceStatus.color}
|
||||
style={{
|
||||
backgroundColor: insuranceStatus.bgColor,
|
||||
border: `1px solid ${insuranceStatus.color}`,
|
||||
fontSize: '12px'
|
||||
}}
|
||||
>
|
||||
{insuranceStatus.text}
|
||||
</Tag>
|
||||
</div>
|
||||
|
||||
{/* 操作员 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<User size={14} color="#8c8c8c"/>
|
||||
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||
操作员:
|
||||
</span>
|
||||
<span style={{fontSize: '13px', color: '#595959'}}>
|
||||
{item.driver || '未绑定'}
|
||||
</span>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div style={{
|
||||
marginTop: '12px',
|
||||
paddingTop: '12px',
|
||||
borderTop: '1px solid #f0f0f0',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
onClick={(e) => quickInsurance(item, e)}
|
||||
style={{
|
||||
borderRadius: '16px',
|
||||
fontSize: '12px'
|
||||
}}
|
||||
>
|
||||
一键报险
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="default"
|
||||
size="small"
|
||||
onClick={() => navigateToDetail(item)}
|
||||
style={{
|
||||
borderRadius: '16px',
|
||||
fontSize: '12px'
|
||||
}}
|
||||
>
|
||||
查看详情
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BestSellers
|
||||
3
src/hjm/bx/bx-add.config.ts
Normal file
3
src/hjm/bx/bx-add.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '一键报险'
|
||||
})
|
||||
549
src/hjm/bx/bx-add.tsx
Normal file
549
src/hjm/bx/bx-add.tsx
Normal file
@@ -0,0 +1,549 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {
|
||||
Button,
|
||||
TextArea,
|
||||
Cell,
|
||||
Loading,
|
||||
Space
|
||||
} from '@nutui/nutui-react-taro'
|
||||
import {Truck} from '@nutui/icons-react-taro'
|
||||
import {addHjmBxLog} from "@/api/hjm/hjmBxLog";
|
||||
import {pageHjmCar} from "@/api/hjm/hjmCar";
|
||||
import {HjmBxLog} from "@/api/hjm/hjmBxLog/model";
|
||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||
import {listCmsWebsiteField} from "@/api/cms/cmsWebsiteField";
|
||||
import {CmsWebsiteField} from "@/api/cms/cmsWebsiteField/model";
|
||||
import {TenantId} from "@/utils/config";
|
||||
|
||||
// 图片数据接口
|
||||
interface UploadedImageData {
|
||||
url: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键报险 - 添加报险记录页面
|
||||
*/
|
||||
function BxAdd() {
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [bxFiled, setBxFiled] = useState<CmsWebsiteField>()
|
||||
const [bxFiled2, setBxFiled2] = useState<CmsWebsiteField>()
|
||||
const [carInfo, setCarInfo] = useState<HjmCar | null>(null)
|
||||
const [fileList, setFileList] = useState<any[]>([]) // 图片文件列表
|
||||
const [lastSubmitTime, setLastSubmitTime] = useState<number>(0) // 最后提交时间
|
||||
const [formData, setFormData] = useState<HjmBxLog>({
|
||||
carId: undefined,
|
||||
accidentType: undefined,
|
||||
image: undefined,
|
||||
comments: '',
|
||||
status: 0 // 0: 待审核, 1: 已通过, 2: 已驳回
|
||||
})
|
||||
|
||||
// 事故类型选项
|
||||
const accidentTypes = [
|
||||
{text: '轻微刮擦', value: '轻微刮擦'},
|
||||
{text: '碰撞事故', value: '碰撞事故'},
|
||||
{text: '追尾事故', value: '追尾事故'},
|
||||
{text: '侧翻事故', value: '侧翻事故'},
|
||||
{text: '其他事故', value: '其他事故'}
|
||||
]
|
||||
|
||||
const [accidentType, setAccidentType] = useState<string>('')
|
||||
const [accidentDescription, setAccidentDescription] = useState<string>('')
|
||||
|
||||
// 初始化页面数据
|
||||
const initPageData = async () => {
|
||||
try {
|
||||
listCmsWebsiteField({}).then(data => {
|
||||
const bxPhone = data.find(item => item.name === 'bxPhone');
|
||||
const bxPhone2 = data.find(item => item.name === 'bxPhone2');
|
||||
if (bxPhone) {
|
||||
setBxFiled(bxPhone);
|
||||
}
|
||||
if (bxPhone2) {
|
||||
setBxFiled2(bxPhone2);
|
||||
}
|
||||
})
|
||||
pageHjmCar({driverId: Taro.getStorageSync('UserId')}).then(res => {
|
||||
const car = res?.list[0];
|
||||
if (car) {
|
||||
setCarInfo(car)
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
carId: car.id
|
||||
}))
|
||||
} else {
|
||||
Taro.showToast({
|
||||
title: '获取车辆信息失败',
|
||||
icon: 'none'
|
||||
})
|
||||
setTimeout(() => {
|
||||
Taro.navigateBack()
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取车辆信息失败:', error)
|
||||
Taro.showToast({
|
||||
title: '获取车辆信息失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 选择并上传图片
|
||||
const handleChooseImage = () => {
|
||||
if (fileList.length >= 5) {
|
||||
Taro.showToast({
|
||||
title: '最多只能上传5张图片',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Taro.chooseImage({
|
||||
count: 5 - fileList.length, // 剩余可选择的数量
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
console.log('选择图片成功:', res)
|
||||
|
||||
// 逐个上传选中的图片
|
||||
res.tempFilePaths.forEach((filePath, index) => {
|
||||
uploadSingleImage(filePath, index)
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('选择图片失败:', err)
|
||||
Taro.showToast({
|
||||
title: '选择图片失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 上传单张图片
|
||||
const uploadSingleImage = (filePath: string, index: number) => {
|
||||
|
||||
Taro.uploadFile({
|
||||
url: 'https://server.gxwebsoft.com/api/oss/upload',
|
||||
filePath: filePath,
|
||||
name: 'file',
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId
|
||||
},
|
||||
success: (res) => {
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
console.log('上传成功', data)
|
||||
if (data.code === 0) {
|
||||
// 更新文件列表
|
||||
const newFile = {
|
||||
name: `图片${Date.now()}_${index}`,
|
||||
url: data.data.url,
|
||||
status: 'success',
|
||||
message: '上传成功',
|
||||
type: 'image',
|
||||
uid: `${Date.now()}_${index}`,
|
||||
}
|
||||
|
||||
setFileList(prev => {
|
||||
const newList = [...prev, newFile]
|
||||
// 同时更新表单数据 - 使用JSON格式存储
|
||||
const imageData: UploadedImageData[] = newList.map(f => ({
|
||||
url: f.url
|
||||
}))
|
||||
setFormData(prevForm => ({
|
||||
...prevForm,
|
||||
image: JSON.stringify(imageData)
|
||||
}))
|
||||
return newList
|
||||
})
|
||||
|
||||
Taro.showToast({
|
||||
title: '上传成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
Taro.showToast({
|
||||
title: data.message || '上传失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解析响应失败:', error)
|
||||
Taro.showToast({
|
||||
title: '上传失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('上传请求失败', err);
|
||||
Taro.showToast({
|
||||
title: '上传失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 处理文件删除
|
||||
const handleFileRemove = (file: any) => {
|
||||
console.log('删除文件:', file)
|
||||
const newFileList = fileList.filter(f => f.uid !== file.uid)
|
||||
setFileList(newFileList)
|
||||
|
||||
// 更新表单数据 - 使用JSON格式存储
|
||||
if (newFileList.length === 0) {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
image: undefined
|
||||
}))
|
||||
} else {
|
||||
const imageData: UploadedImageData[] = newFileList.map(f => ({
|
||||
url: f.url
|
||||
}))
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
image: JSON.stringify(imageData)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
// 防止重复提交 - 检查loading状态
|
||||
if (loading) {
|
||||
Taro.showToast({
|
||||
title: '正在提交中,请稍候...',
|
||||
icon: 'loading'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 防止快速连续点击 - 2秒内不允许重复提交
|
||||
const now = Date.now()
|
||||
if (now - lastSubmitTime < 2000) {
|
||||
Taro.showToast({
|
||||
title: '请勿频繁提交',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
setLastSubmitTime(now)
|
||||
|
||||
// 表单验证
|
||||
if (!formData.carId) {
|
||||
Taro.showToast({
|
||||
title: '请选择车辆',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!accidentType) {
|
||||
Taro.showToast({
|
||||
title: '请选择事故类型',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.image || fileList.length === 0) {
|
||||
Taro.showToast({
|
||||
title: '请上传现场照片',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
// 构建提交数据
|
||||
const submitData: HjmBxLog = {
|
||||
...formData,
|
||||
accidentType: accidentType,
|
||||
comments: `${accidentDescription || '无'}`
|
||||
}
|
||||
|
||||
console.log('提交的图片数据:', formData.image)
|
||||
console.log('完整提交数据:', submitData)
|
||||
|
||||
// 解析JSON格式的图片数据示例
|
||||
if (formData.image) {
|
||||
try {
|
||||
const parsedImages: UploadedImageData[] = JSON.parse(formData.image)
|
||||
console.log('解析后的图片数据:', parsedImages)
|
||||
console.log('图片数量:', parsedImages.length)
|
||||
parsedImages.forEach((img, index) => {
|
||||
console.log(`图片${index + 1}:`, {
|
||||
url: img.url
|
||||
})
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('解析图片数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
await addHjmBxLog(submitData)
|
||||
|
||||
Taro.showToast({
|
||||
title: '报险提交成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
formData.image = ''
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error)
|
||||
Taro.showToast({
|
||||
title: '提交失败',
|
||||
icon: 'error'
|
||||
})
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
initPageData().then(r => {
|
||||
console.log(r,'rr')
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (loading && !carInfo) {
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '100vh'
|
||||
}}>
|
||||
<Loading type="spinner">加载中...</Loading>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
backgroundColor: '#f5f5f5',
|
||||
minHeight: '100vh',
|
||||
paddingBottom: '80px'
|
||||
}}>
|
||||
<div style={{
|
||||
backgroundColor: '#fff',
|
||||
margin: '16px',
|
||||
borderRadius: '12px',
|
||||
padding: '16px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
|
||||
}}>
|
||||
{bxFiled && (<div>{bxFiled.comments}:{bxFiled.value}</div>)}
|
||||
{bxFiled2 && (<div>{bxFiled2.comments}:{bxFiled2.value}</div>)}
|
||||
</div>
|
||||
{/* 车辆信息卡片 */}
|
||||
{carInfo && (
|
||||
<div style={{
|
||||
backgroundColor: '#fff',
|
||||
margin: '16px',
|
||||
borderRadius: '12px',
|
||||
padding: '16px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
marginBottom: '12px'
|
||||
}}>
|
||||
<Truck size={18} color="#1890ff"/>
|
||||
<span style={{fontSize: '16px', fontWeight: 'bold'}}>车辆信息</span>
|
||||
</div>
|
||||
|
||||
<Space direction="vertical">
|
||||
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||
<span style={{color: '#8c8c8c'}}>车辆编号:</span>
|
||||
<span style={{fontWeight: 'bold'}}>{carInfo.code}</span>
|
||||
</div>
|
||||
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||
<span style={{color: '#8c8c8c'}}>快递公司:</span>
|
||||
<span>{carInfo.parentOrganization}</span>
|
||||
</div>
|
||||
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||
<span style={{color: '#8c8c8c'}}>操作员:</span>
|
||||
<span>{carInfo.driver || '未绑定'}</span>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
{/* 现场照片 */}
|
||||
<div style={{
|
||||
backgroundColor: '#fff',
|
||||
margin: '0 16px 16px',
|
||||
borderRadius: '12px',
|
||||
padding: '16px'
|
||||
}}>
|
||||
<div style={{marginBottom: '12px'}}>
|
||||
<span style={{fontSize: '16px', fontWeight: 'bold'}}>现场照片</span>
|
||||
<span style={{color: '#ff4d4f', fontSize: '12px', marginLeft: '8px'}}>*必填(最多5张)</span>
|
||||
{fileList.length > 0 && (
|
||||
<span style={{color: '#52c41a', fontSize: '12px', marginLeft: '8px'}}>
|
||||
已上传{fileList.length}张
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
gap: '12px'
|
||||
}}>
|
||||
{/* 显示已上传的图片 */}
|
||||
{fileList.map((file) => (
|
||||
<div key={file.uid} style={{
|
||||
position: 'relative',
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
borderRadius: '8px',
|
||||
overflow: 'hidden',
|
||||
border: '1px solid #d9d9d9'
|
||||
}}>
|
||||
<img
|
||||
src={file.url}
|
||||
alt={file.name}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover'
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
type="default"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-8px',
|
||||
right: '-8px',
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
borderRadius: '12px',
|
||||
fontSize: '12px',
|
||||
minWidth: '24px',
|
||||
padding: 0
|
||||
}}
|
||||
onClick={() => handleFileRemove(file)}
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* 添加图片按钮 */}
|
||||
{fileList.length < 5 && (
|
||||
<Button
|
||||
size="small"
|
||||
onClick={handleChooseImage}
|
||||
style={{
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
borderRadius: '8px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
border: '2px dashed #d9d9d9',
|
||||
backgroundColor: '#fafafa'
|
||||
}}
|
||||
>
|
||||
<span style={{fontSize: '24px', color: '#d9d9d9'}}>+</span>
|
||||
<span style={{fontSize: '12px', marginTop: '4px', color: '#666'}}>
|
||||
添加图片
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 事故信息表单 */}
|
||||
<div style={{
|
||||
backgroundColor: '#fff',
|
||||
margin: '16px 16px 16px',
|
||||
borderRadius: '12px',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<div style={{
|
||||
padding: '16px',
|
||||
borderBottom: '1px solid #f0f0f0'
|
||||
}}>
|
||||
<span style={{fontSize: '16px', fontWeight: 'bold'}}>事故信息</span>
|
||||
</div>
|
||||
<Cell.Group>
|
||||
<Cell
|
||||
title="事故类型"
|
||||
description={accidentType || '请选择事故类型'}
|
||||
onClick={() => {
|
||||
Taro.showActionSheet({
|
||||
itemList: accidentTypes.map(item => item.text),
|
||||
success: (res) => {
|
||||
setAccidentType(accidentTypes[res.tapIndex].value)
|
||||
}
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Cell.Group>
|
||||
</div>
|
||||
|
||||
{/* 事故描述 */}
|
||||
<div style={{
|
||||
backgroundColor: '#fff',
|
||||
margin: '0 16px 16px',
|
||||
borderRadius: '12px',
|
||||
padding: '16px'
|
||||
}}>
|
||||
<div style={{marginBottom: '12px'}}>
|
||||
<span style={{fontSize: '16px', fontWeight: 'bold'}}>事故描述</span>
|
||||
<span style={{color: '#8c8c8c', fontSize: '12px', marginLeft: '8px'}}>(选填)</span>
|
||||
</div>
|
||||
<TextArea
|
||||
placeholder={'请详细描述事故经过、损失情况等...'}
|
||||
value={accidentDescription}
|
||||
onChange={setAccidentDescription}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 提交按钮 */}
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: '#fff',
|
||||
padding: '16px',
|
||||
borderTop: '1px solid #f0f0f0'
|
||||
}}>
|
||||
<Button
|
||||
type="primary"
|
||||
block
|
||||
loading={loading}
|
||||
disabled={loading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{loading ? '提交中...' : '提交报险申请'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default BxAdd
|
||||
3
src/hjm/bx/bx.config.ts
Normal file
3
src/hjm/bx/bx.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '报险记录'
|
||||
})
|
||||
292
src/hjm/bx/bx.tsx
Normal file
292
src/hjm/bx/bx.tsx
Normal file
@@ -0,0 +1,292 @@
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {
|
||||
Loading,
|
||||
Empty,
|
||||
Button,
|
||||
Input,
|
||||
Tag,
|
||||
Image,
|
||||
Space
|
||||
} from '@nutui/nutui-react-taro'
|
||||
import {Search, Calendar, Truck, File} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {pageHjmBxLog} from "@/api/hjm/hjmBxLog";
|
||||
import {HjmBxLog} from "@/api/hjm/hjmBxLog/model";
|
||||
|
||||
|
||||
/**
|
||||
* 报险记录列表页面
|
||||
*/
|
||||
const Bx: React.FC = () => {
|
||||
const [list, setList] = useState<HjmBxLog[]>([])
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [keywords, setKeywords] = useState<string>('')
|
||||
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||
console.log(refreshing)
|
||||
// 获取状态显示
|
||||
const getStatusDisplay = (status?: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return {text: '待审核', color: '#faad14', bgColor: '#fffbe6'}
|
||||
case 1:
|
||||
return {text: '已通过', color: '#52c41a', bgColor: '#f6ffed'}
|
||||
case 2:
|
||||
return {text: '已驳回', color: '#ff4d4f', bgColor: '#fff2f0'}
|
||||
default:
|
||||
return {text: '未知', color: '#8c8c8c', bgColor: '#f5f5f5'}
|
||||
}
|
||||
}
|
||||
|
||||
const reload = async (showLoading = true) => {
|
||||
try {
|
||||
if (showLoading) setLoading(true)
|
||||
setRefreshing(true)
|
||||
|
||||
const res = await pageHjmBxLog({
|
||||
keywords: keywords.trim(),
|
||||
userId: Taro.getStorageSync('UserId')
|
||||
})
|
||||
|
||||
setList(res?.list.map(d => {
|
||||
console.log(d,'ddd')
|
||||
d.image = JSON.parse(d.image);
|
||||
console.log(d)
|
||||
return d;
|
||||
}) || [])
|
||||
} catch (error) {
|
||||
console.error('获取报险记录失败:', error)
|
||||
Taro.showToast({
|
||||
title: '获取报险记录失败',
|
||||
icon: 'error'
|
||||
})
|
||||
} finally {
|
||||
setLoading(false)
|
||||
setRefreshing(false)
|
||||
}
|
||||
}
|
||||
|
||||
const onSearch = () => {
|
||||
reload()
|
||||
}
|
||||
|
||||
const onKeywordsChange = (value: string) => {
|
||||
setKeywords(value)
|
||||
}
|
||||
|
||||
const onAddInsurance = () => {
|
||||
Taro.navigateTo({
|
||||
url: '/hjm/bx/bx-add'
|
||||
})
|
||||
}
|
||||
|
||||
const viewDetail = (item: HjmBxLog) => {
|
||||
Taro.navigateTo({
|
||||
url: `/hjm/bx/bx-detail?id=${item.id}`
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload().then()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 搜索栏 */}
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
top: '20px',
|
||||
left: 0,
|
||||
right: 0,
|
||||
display: "none",
|
||||
zIndex: 20,
|
||||
padding: '0 16px',
|
||||
backgroundColor: '#f5f5f5'
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
padding: '8px 12px',
|
||||
borderRadius: '20px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
<Search size={16} color="#999"/>
|
||||
<Input
|
||||
placeholder="搜索报险记录"
|
||||
value={keywords}
|
||||
onChange={onKeywordsChange}
|
||||
onConfirm={onSearch}
|
||||
style={{
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
flex: 1,
|
||||
marginLeft: '8px'
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
onClick={onSearch}
|
||||
loading={loading}
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 报险记录列表 */}
|
||||
<div style={{
|
||||
marginTop: '10px',
|
||||
paddingBottom: '80px'
|
||||
}}>
|
||||
{loading && list.length === 0 ? (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '200px'
|
||||
}}>
|
||||
<Loading type="spinner">加载中...</Loading>
|
||||
</div>
|
||||
) : list.length === 0 ? (
|
||||
<Empty description="暂无报险记录">
|
||||
<Button type="primary" onClick={onAddInsurance}>
|
||||
立即报险
|
||||
</Button>
|
||||
</Empty>
|
||||
) : (
|
||||
<div style={{padding: '0 16px'}}>
|
||||
{list.map((item, index) => {
|
||||
const statusDisplay = getStatusDisplay(item.status)
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '12px',
|
||||
padding: '16px',
|
||||
marginBottom: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
|
||||
border: '1px solid #f0f0f0'
|
||||
}}
|
||||
onClick={() => viewDetail(item)}
|
||||
>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
marginBottom: '12px'
|
||||
}}>
|
||||
<div style={{flex: 1}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
marginBottom: '8px'
|
||||
}}>
|
||||
<File size={16} color="#1890ff"/>
|
||||
<span style={{
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
color: '#262626'
|
||||
}}>
|
||||
报险记录 #{item.id}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Space direction="vertical">
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<Truck size={14} color="#8c8c8c"/>
|
||||
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||
车辆编号:{item.carNo}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px'
|
||||
}}>
|
||||
<Calendar size={14} color="#8c8c8c"/>
|
||||
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||
提交时间:{item.createTime}
|
||||
</span>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Tag
|
||||
color={statusDisplay.color}
|
||||
style={{
|
||||
backgroundColor: statusDisplay.bgColor,
|
||||
border: `1px solid ${statusDisplay.color}`,
|
||||
fontSize: '12px'
|
||||
}}
|
||||
>
|
||||
{statusDisplay.text}
|
||||
</Tag>
|
||||
</div>
|
||||
|
||||
{/* 事故照片预览 */}
|
||||
{item.image && (
|
||||
<div style={{marginBottom: '12px'}} className={'flex gap-2'}>
|
||||
{item.image.map((image) => (
|
||||
<Image
|
||||
src={image.url}
|
||||
width="60"
|
||||
height="60"
|
||||
radius="6px"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 备注信息 */}
|
||||
{item.comments && (
|
||||
<div style={{
|
||||
backgroundColor: '#f8f9fa',
|
||||
padding: '8px 12px',
|
||||
borderRadius: '6px',
|
||||
fontSize: '13px',
|
||||
color: '#595959',
|
||||
lineHeight: '1.4'
|
||||
}}>
|
||||
{item.comments.length > 50
|
||||
? `${item.comments.substring(0, 50)}...`
|
||||
: item.comments
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 浮动添加按钮 */}
|
||||
{/*<div style={{*/}
|
||||
{/* position: 'fixed',*/}
|
||||
{/* bottom: '20px',*/}
|
||||
{/* right: '20px',*/}
|
||||
{/* zIndex: 30*/}
|
||||
{/*}}>*/}
|
||||
{/* <Button*/}
|
||||
{/* type="primary"*/}
|
||||
{/* size="large"*/}
|
||||
{/* onClick={onAddInsurance}*/}
|
||||
{/* >*/}
|
||||
{/* 一键报险*/}
|
||||
{/* </Button>*/}
|
||||
{/*</div>*/}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bx
|
||||
Reference in New Issue
Block a user