@ -0,0 +1,623 @@
import React , { useState , useEffect } from 'react' ;
import {
Button ,
Table ,
Space ,
Modal ,
message ,
Input ,
Select ,
Form ,
Tooltip ,
Tag ,
TablePaginationConfig ,
DatePicker ,
Row ,
Col ,
} from 'antd' ;
import {
PlusOutlined ,
DeleteOutlined ,
ExclamationCircleOutlined ,
SearchOutlined ,
EditOutlined ,
EyeOutlined ,
} from '@ant-design/icons' ;
import { TaskStatus , TaskType , TaskStatusText , TaskStatusColor , TaskTypeText } from '@/dicts/supplierTaskDict' ;
import './supplierTaskManage.less' ;
const { Option } = Select ;
const { RangePicker } = DatePicker ;
// 任务记录类型
interface TaskRecord {
id : string ;
taskName : string ;
taskCode : string ;
taskType : string ;
templateName : string ;
status : string ;
startTime : string ;
endTime : string ;
createBy : string ;
createTime : string ;
updateBy? : string ;
updateTime? : string ;
key : string ;
}
interface SearchParams {
taskName? : string ;
status? : string ;
dateRange ? : [ string , string ] ;
}
const SupplierTaskManage : React.FC = ( ) = > {
const [ selectedRowKeys , setSelectedRowKeys ] = useState < React.Key [ ] > ( [ ] ) ;
const [ loading , setLoading ] = useState < boolean > ( false ) ;
const [ form ] = Form . useForm ( ) ;
const [ modalVisible , setModalVisible ] = useState < boolean > ( false ) ;
const [ isEdit , setIsEdit ] = useState < boolean > ( false ) ;
const [ isViewMode , setIsViewMode ] = useState < boolean > ( false ) ;
const [ currentId , setCurrentId ] = useState < string > ( '' ) ;
// 查看详情数据
const [ viewData , setViewData ] = useState < TaskRecord | null > ( null ) ;
const [ taskData , setTaskData ] = useState < TaskRecord [ ] > ( [ ] ) ;
const [ pagination , setPagination ] = useState < TablePaginationConfig > ( {
current : 1 ,
pageSize : 10 ,
total : 0 ,
showSizeChanger : true ,
showQuickJumper : true ,
showTotal : ( total ) = > ` 共 ${ total } 条记录 ` ,
} ) ;
const [ searchParams , setSearchParams ] = useState < SearchParams > ( { } ) ;
// 模拟获取任务列表
const fetchTaskList = async (
current = 1 ,
pageSize = 10 ,
params : SearchParams = searchParams ,
) = > {
// 更新搜索参数状态
if ( params !== searchParams ) {
setSearchParams ( params ) ;
}
setLoading ( true ) ;
try {
// 模拟API请求
setTimeout ( ( ) = > {
// 模拟数据
const mockData : TaskRecord [ ] = Array . from ( { length : 35 } ) . map ( ( _ , index ) = > {
const id = ` ${ index + 1 } ` ;
const status = Object . values ( TaskStatus ) [ Math . floor ( Math . random ( ) * 3 ) ] ;
const taskType = Math . random ( ) > 0.5 ? TaskType.REGULAR : TaskType.SPECIAL ;
// 生成随机单位名称
const units = [ '中山市合创展包装材料有限公司' , '广州市科技发展有限公司' , '深圳市创新科技有限公司' , '东莞市制造业有限公司' ] ;
const unitIndex = Math . floor ( Math . random ( ) * units . length ) ;
return {
id ,
key : id ,
taskName : ` 供应商评价任务 ${ index + 1 } ` ,
taskCode : ` TASK ${ String ( index + 1 ) . padStart ( 4 , '0' ) } ` ,
taskType ,
templateName : ` ${ TaskTypeText [ taskType ] } 模板 ${ Math . floor ( Math . random ( ) * 5 ) + 1 } ` ,
status ,
startTime : '2023-01-01' ,
endTime : '2023-12-31' ,
createBy : units [ unitIndex ] ,
createTime : '2023-01-01 12:00:00' ,
} ;
} ) ;
// 根据搜索条件过滤
let filteredData = [ . . . mockData ] ;
if ( params . taskName ) {
filteredData = filteredData . filter ( item = >
item . taskName . includes ( params . taskName || '' )
) ;
}
if ( params . status ) {
filteredData = filteredData . filter ( item = >
item . status === params . status
) ;
}
// 分页
const startIndex = ( current - 1 ) * pageSize ;
const endIndex = startIndex + pageSize ;
const paginatedData = filteredData . slice ( startIndex , endIndex ) ;
setTaskData ( paginatedData ) ;
setPagination ( {
. . . pagination ,
current ,
pageSize ,
total : filteredData.length ,
} ) ;
setLoading ( false ) ;
} , 500 ) ;
} catch ( error ) {
console . error ( '获取任务列表失败:' , error ) ;
message . error ( '获取任务列表失败' ) ;
setLoading ( false ) ;
}
} ;
// 首次加载获取数据
useEffect ( ( ) = > {
fetchTaskList ( pagination . current , pagination . pageSize , { } ) ;
} , [ ] ) ;
// 处理查看
const handleView = ( record : TaskRecord ) = > {
setCurrentId ( record . id ) ;
setIsViewMode ( true ) ;
setViewData ( record ) ;
setModalVisible ( true ) ;
} ;
// 处理编辑
const handleEdit = ( record : TaskRecord ) = > {
setIsEdit ( true ) ;
setIsViewMode ( false ) ;
setCurrentId ( record . id ) ;
setViewData ( record ) ;
setModalVisible ( true ) ;
} ;
// 处理删除
const showDeleteConfirm = ( record : TaskRecord ) = > {
Modal . confirm ( {
title : '确认删除' ,
icon : < ExclamationCircleOutlined / > ,
content : ` 确定要删除任务: ${ record . taskName } ? ` ,
okText : '确定' ,
okType : 'danger' ,
cancelText : '取消' ,
maskClosable : false ,
onOk : async ( ) = > {
try {
// 模拟删除请求
setTimeout ( ( ) = > {
message . success ( '删除成功' ) ;
fetchTaskList ( pagination . current , pagination . pageSize , searchParams ) ;
} , 500 ) ;
} catch ( error ) {
console . error ( '删除任务失败:' , error ) ;
message . error ( '删除任务失败' ) ;
}
} ,
} ) ;
} ;
// 处理发布/取消
const handlePublishStatus = ( record : TaskRecord ) = > {
const isInProgress = record . status === TaskStatus . PROCESSING ;
const actionText = isInProgress ? '取消' : '开始' ;
Modal . confirm ( {
title : ` 确认 ${ actionText } ` ,
icon : < ExclamationCircleOutlined / > ,
content : ` 确定要 ${ actionText } 任务: ${ record . taskName } ? ` ,
okText : '确定' ,
cancelText : '取消' ,
maskClosable : false ,
onOk : async ( ) = > {
try {
// 模拟请求
setTimeout ( ( ) = > {
message . success ( ` ${ actionText } 成功 ` ) ;
fetchTaskList ( pagination . current , pagination . pageSize , searchParams ) ;
} , 500 ) ;
} catch ( error ) {
console . error ( ` ${ actionText } 失败: ` , error ) ;
message . error ( ` ${ actionText } 失败 ` ) ;
}
} ,
} ) ;
} ;
// 获取状态标签
const getStatusTag = ( status : string ) = > {
const color = TaskStatusColor [ status as keyof typeof TaskStatusColor ] || 'default' ;
const text = TaskStatusText [ status as keyof typeof TaskStatusText ] || '未知状态' ;
return < Tag color = { color } > { text } < / Tag > ;
} ;
// 处理表格分页变化
const handleTableChange = ( newPagination : TablePaginationConfig ) = > {
fetchTaskList ( newPagination . current , newPagination . pageSize , searchParams ) ;
} ;
const columns = [
{
title : '序号' ,
render : ( _ : any , __ : TaskRecord , index : number ) = >
( pagination . current ! - 1 ) * pagination . pageSize ! + index + 1 ,
width : 80 ,
} ,
{
title : '评价主题' ,
dataIndex : 'taskName' ,
key : 'taskName' ,
width : 200 ,
ellipsis : {
showTitle : false ,
} ,
render : ( taskName : string ) = > (
< Tooltip placement = "topLeft" title = { taskName } >
{ taskName }
< / Tooltip >
) ,
} ,
{
title : '发起单位' ,
dataIndex : 'createBy' ,
key : 'createBy' ,
width : 150 ,
} ,
{
title : '评价开始时间' ,
dataIndex : 'startTime' ,
key : 'startTime' ,
width : 120 ,
} ,
{
title : '评价结束时间' ,
dataIndex : 'endTime' ,
key : 'endTime' ,
width : 120 ,
} ,
{
title : '评价状态' ,
dataIndex : 'status' ,
key : 'status' ,
width : 100 ,
render : ( status : string ) = > getStatusTag ( status ) ,
} ,
{
title : '操作' ,
key : 'action' ,
width : 180 ,
align : 'center' as const ,
render : ( _ : unknown , record : TaskRecord ) = > (
< Space size = "middle" >
< Button type = "link" onClick = { ( ) = > handleView ( record ) } >
查 看
< / Button >
< Button type = "link" onClick = { ( ) = > handleEdit ( record ) } >
修 改
< / Button >
< Button type = "link" onClick = { ( ) = > showDeleteConfirm ( record ) } >
删 除
< / Button >
< / Space >
) ,
} ,
] ;
const onSelectChange = ( newSelectedRowKeys : React.Key [ ] ) = > {
setSelectedRowKeys ( newSelectedRowKeys ) ;
} ;
const rowSelection = {
selectedRowKeys ,
onChange : onSelectChange ,
} ;
const hasSelected = selectedRowKeys . length > 0 ;
// 处理添加
const handleAdd = ( ) = > {
setIsEdit ( false ) ;
setIsViewMode ( false ) ;
setCurrentId ( '' ) ;
setViewData ( null ) ;
setModalVisible ( true ) ;
} ;
// 处理批量删除
const handleBatchDelete = ( ) = > {
Modal . confirm ( {
title : '确认批量删除' ,
icon : < ExclamationCircleOutlined / > ,
content : '确定要删除选中的任务吗?此操作不可恢复。' ,
okText : '删除' ,
okType : 'danger' ,
cancelText : '取消' ,
maskClosable : false ,
onOk : async ( ) = > {
setLoading ( true ) ;
try {
// 模拟批量删除
setTimeout ( ( ) = > {
setSelectedRowKeys ( [ ] ) ;
message . success ( '批量删除成功' ) ;
fetchTaskList ( pagination . current , pagination . pageSize , searchParams ) ;
setLoading ( false ) ;
} , 1000 ) ;
} catch ( error ) {
console . error ( '批量删除失败:' , error ) ;
message . error ( '批量删除失败' ) ;
setLoading ( false ) ;
}
} ,
} ) ;
} ;
// 处理搜索
const handleSearch = ( values : any ) = > {
const { dateRange , . . . rest } = values ;
const params : SearchParams = { . . . rest } ;
if ( dateRange && dateRange . length === 2 ) {
params . dateRange = [ dateRange [ 0 ] . format ( 'YYYY-MM-DD' ) , dateRange [ 1 ] . format ( 'YYYY-MM-DD' ) ] ;
}
fetchTaskList ( 1 , pagination . pageSize , params ) ;
} ;
// 处理模态框取消
const handleModalCancel = ( ) = > {
setModalVisible ( false ) ;
setIsViewMode ( false ) ;
setViewData ( null ) ;
} ;
// 渲染任务详情
const renderTaskDetail = ( ) = > {
if ( ! viewData ) return null ;
return (
< div className = "task-detail" >
< Row gutter = { [ 16 , 16 ] } >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 任 务 名 称 : < / span >
< span className = "content" > { viewData . taskName } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 任 务 编 号 : < / span >
< span className = "content" > { viewData . taskCode } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 任 务 类 型 : < / span >
< span className = "content" >
{ TaskTypeText [ viewData . taskType as keyof typeof TaskTypeText ] || '未知类型' }
< / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 使 用 模 板 : < / span >
< span className = "content" > { viewData . templateName } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 状 态 : < / span >
< span className = "content" > { getStatusTag ( viewData . status ) } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 开 始 时 间 : < / span >
< span className = "content" > { viewData . startTime } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 结 束 时 间 : < / span >
< span className = "content" > { viewData . endTime } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 创 建 人 : < / span >
< span className = "content" > { viewData . createBy } < / span >
< / div >
< / Col >
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 创 建 时 间 : < / span >
< span className = "content" > { viewData . createTime } < / span >
< / div >
< / Col >
{ viewData . updateBy && (
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 更 新 人 : < / span >
< span className = "content" > { viewData . updateBy } < / span >
< / div >
< / Col >
) }
{ viewData . updateTime && (
< Col span = { 12 } >
< div className = "detail-item" >
< span className = "label" > 更 新 时 间 : < / span >
< span className = "content" > { viewData . updateTime } < / span >
< / div >
< / Col >
) }
< / Row >
< / div >
) ;
} ;
// 渲染任务表单
const renderTaskForm = ( ) = > {
return (
< Form
labelCol = { { span : 6 } }
wrapperCol = { { span : 16 } }
initialValues = { viewData || { } }
>
< Form.Item
label = "任务名称"
name = "taskName"
rules = { [ { required : true , message : '请输入任务名称' } ] }
>
< Input placeholder = "请输入任务名称" / >
< / Form.Item >
< Form.Item
label = "任务编号"
name = "taskCode"
rules = { [ { required : true , message : '请输入任务编号' } ] }
>
< Input placeholder = "请输入任务编号" disabled = { isEdit } / >
< / Form.Item >
< Form.Item
label = "任务类型"
name = "taskType"
rules = { [ { required : true , message : '请选择任务类型' } ] }
>
< Select placeholder = "请选择任务类型" >
< Option value = { TaskType . REGULAR } > { TaskTypeText [ TaskType . REGULAR ] } < / Option >
< Option value = { TaskType . SPECIAL } > { TaskTypeText [ TaskType . SPECIAL ] } < / Option >
< / Select >
< / Form.Item >
< Form.Item
label = "使用模板"
name = "templateName"
rules = { [ { required : true , message : '请选择使用模板' } ] }
>
< Select placeholder = "请选择使用模板" >
< Option value = "常规评价模板1" > 常 规 评 价 模 板 1 < / Option >
< Option value = "常规评价模板2" > 常 规 评 价 模 板 2 < / Option >
< Option value = "专项评价模板1" > 专 项 评 价 模 板 1 < / Option >
< Option value = "专项评价模板2" > 专 项 评 价 模 板 2 < / Option >
< / Select >
< / Form.Item >
< Form.Item
label = "时间范围"
rules = { [ { required : true , message : '请选择时间范围' } ] }
>
< RangePicker / >
< / Form.Item >
< Form.Item wrapperCol = { { offset : 6 , span : 16 } } >
< Button type = "primary" htmlType = "submit" >
保 存
< / Button >
< Button style = { { marginLeft : 8 } } onClick = { handleModalCancel } >
取 消
< / Button >
< / Form.Item >
< / Form >
) ;
} ;
return (
< div className = "supplier-task-manage-container common-container" >
< div className = "filter-action-row" >
< Form
form = { form }
name = "search"
onFinish = { handleSearch }
layout = "inline"
className = "filter-form"
>
< Form.Item name = "taskName" label = "评价主题" >
< Input placeholder = "请输入评价主题" allowClear / >
< / Form.Item >
< Form.Item name = "status" label = "评价状态" >
< Select placeholder = "请选择状态" allowClear >
< Option value = { TaskStatus . DRAFT } > 未 开 始 < / Option >
< Option value = { TaskStatus . PROCESSING } > 进 行 中 < / Option >
< Option value = { TaskStatus . COMPLETED } > 已 结 束 < / Option >
< / Select >
< / Form.Item >
< Form.Item name = "dateRange" label = "评价时间" >
< RangePicker / >
< / Form.Item >
< / Form >
< / div >
< div className = "button-row" >
< div className = "left-buttons" >
< Button type = "primary" htmlType = "submit" icon = { < SearchOutlined / > } onClick = { ( ) = > form . submit ( ) } >
搜 索
< / Button >
< Button
danger
icon = { < DeleteOutlined / > }
onClick = { ( ) = > {
form . resetFields ( ) ;
fetchTaskList ( 1 , pagination . pageSize , { } ) ;
} }
>
重 置
< / Button >
< / div >
< div className = "right-buttons" >
< Button type = "primary" ghost icon = { < PlusOutlined / > } onClick = { handleAdd } >
新 增
< / Button >
< Button
danger
icon = { < DeleteOutlined / > }
onClick = { handleBatchDelete }
disabled = { ! hasSelected }
loading = { loading }
>
批 量 删 除
< / Button >
< / div >
< / div >
< div className = "content-area" >
< Table
rowSelection = { rowSelection }
columns = { columns }
dataSource = { taskData }
pagination = { pagination }
loading = { loading }
onChange = { handleTableChange }
scroll = { { x : 1500 } }
/ >
< / div >
{ /* 新增/编辑/查看模态框 */ }
< Modal
title = { isViewMode
? "查看任务详情"
: isEdit
? "编辑任务"
: "新增任务" }
visible = { modalVisible }
onCancel = { handleModalCancel }
width = { 800 }
maskClosable = { false }
destroyOnClose
footer = {
isViewMode
? [
< Button key = "close" onClick = { handleModalCancel } >
关 闭
< / Button > ,
]
: null
}
>
{ isViewMode ? renderTaskDetail ( ) : renderTaskForm ( ) }
< / Modal >
< / div >
) ;
} ;
export default SupplierTaskManage ;