tsg-web/src/views/rcgl/jdkh/khrwgl/PfDetail.js

709 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React,{useState,useEffect,useRef,useContext,useMemo} from 'react'
import { Table, Radio,Switch,Button,Form,message, InputNumber,DatePicker,Upload,Row,Col,Image,Modal,Input} from "antd"
import { EditOutlined,DeleteOutlined,EyeOutlined } from '@ant-design/icons';
import { httpget2, httppost2 } from '../../../../utils/request'
import { handleData } from "../../../../utils/tools"
import apiurl from '../../../../service/apiurl'
import PfViewModal from "./pfViewModal"
import { formItemLayout, btnItemLayout } from '../../../../components/crud/FormLayoutProps';
import moment from 'moment'
const { Dragger } = Upload;
export default function PfDetail({ record, Item, refresh, onCancel,tabs }) {
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
const EditableContext = React.createContext(null);
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef(null);
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef.current.focus();
}
}, [editing]);
const toggleEdit = () => {
if(Item.view) return
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({
...record,
...values,
});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form form={form}>
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
>
<InputNumber min={0} max={record?.standardScore} ref={inputRef} onPressEnter={save} onBlur={save} />
</Form.Item>
</Form>
) : (
<div
className="editable-cell-value-wrap"
style={{
paddingRight: 24,
}}
onClick={toggleEdit}
>
{children}
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
// 总分
const [tableData, setTableData] = useState([])
const score = useMemo(() => tableData?.reduce((total, cur) => total + (cur?.assessScore ?? 0), 0), [tableData]);
const columns = [
{
title: "考核类目",
dataIndex: "name",
key:"name",
width: 150,
align: "center",
onCell: (row) => ({ rowSpan: row.rowSpan || 0 })
},
{
title: '指标名称',
key: 'indicatorName',
dataIndex: 'indicatorName',
width: 200,
align: "center",
},
{
title: '标准分数',
key: 'standardScore',
dataIndex: 'standardScore',
width: 70,
align: "center",
},
{
title: `考核得分(${score ?? ''})`,
key: 'assessScore',
dataIndex: 'assessScore',
width: 80,
align: "center",
editable: true,
},
{
title: '是否需要整改',
key: 'isNeedRectify1',
dataIndex: 'isNeedRectify1',
width: 150,
align: "center",
render: (text, row) => {
const checked = compareScore(row)
return (
<>
<Switch
checkedChildren="是"
unCheckedChildren="否"
checked={checked}
/>
{(checked && !Item.view) ? <EditOutlined
title='编辑'
style={{ marginLeft: 10, cursor: 'pointer' }}
onClick={() => { zgCallback(row) }}
/> : (checked && Item.view) ?
<EyeOutlined
title='查看'
style={{ marginLeft: 10, cursor: 'pointer' }}
onClick={() => { zgView(row) }}
/> : null
}
</>
)
}
},
]
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const newcolumns = columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
const handleSave = (row) => {
const newData = [...tableData];
const index = newData.findIndex((item) => row.id === item.id);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setTableData(newData);
tableDataRef.current = newData
};
const tableDataRef = useRef(null)
const getZbTableData = async (id, type) => {
const url = type == 1 ? apiurl.rcgl.jdkh.khmbgl.info :
apiurl.rcgl.jdkh.khrwgl.pfDetail
try {
const res = await httpget2(url + `/${id}`)
if (res.code == 200) {
res.data.forEach(item => {
if (item.rowSpan) delete item.rowSpan;
})
const result = handleData(res.data, "name")
setTableData(result)
tableDataRef.current = result;
}
} catch (error) {
console.log(error);
}
}
// 分数进行比较
const compareScore = (row) => {
let isBelowStandard = false;
if (Item.tabs != 2) {
isBelowStandard = row.standardScore > row.assessScore ? true : false;
return isBelowStandard;
} else {
for (let i = 0; row[`assessScore${i}`] !== undefined; i++) {
if (row[`assessScore${i}`] < row.standardScore) {
isBelowStandard = true;
break;
}
}
}
return isBelowStandard
}
// 处理清单任务查看详情
const handleTableData = (obj) => {
let rrlts = {};
const arr = Object.values(obj).map(item => {
item.map((it, index) => {
it['teamUserName' + index] = it.teamUserName;
it['assessScore' + index] = it.assessScore;
it['problemDesc' + index] = it.problemDesc;
it['rectifyRequirement' + index] = it.rectifyRequirement;
it['rectifyLastDate' + index] = it.rectifyLastDate;
it['files' + index] = it.files;
it["count"] = index +1;
rrlts = { ...rrlts, ...it }
})
return rrlts
})
return arr
}
const handleTableData2 = (obj) => {
const names = Object.values(obj)?.[0]?.map(o=>o.teamUserName)
const obj2 = {}
for(let key in obj){
const arr = []
names?.map((name)=>{
obj?.[key]?.map((item)=>{
if(name===item.teamUserName){
arr.push(item)
}
})
})
obj2[key] = arr
}
return obj2
}
// 获取清单查看数据
const [qdColumns, setQdColumns] = useState(newcolumns)
const [qdWidth, setQdWidth] = useState()
const getQdViewData = async (id) => {
try {
const res = await httpget2(apiurl.rcgl.jdkh.khrwgl.qdView + `/${id}`)
if (res.code == 200) {
const linshi = handleTableData2(res.data)//将接口里用户的顺序统一
const result = handleTableData(linshi);
const insertCols = [];
result.forEach((item, index, arr) => {
const total = arr?.reduce((total, cur) => total + (cur["assessScore" + index] || 0), 0)
if (item["teamUserName" + index]) {
insertCols.push( {
title: item['teamUserName' + index] + `(${total})`,
key: "assessScore" + index,
dataIndex: "assessScore" + index,
width: 80,
align: "center",
})
}
})
// 综合得分
const zfScore = result?.reduce((total,cur) => total + (cur?.indicatorScore || 0),0 )
insertCols.push({
title: "综合得分" + `(${zfScore})`,
key: "indicatorScore",
dataIndex: "indicatorScore",
width: 100,
align: "center",
render: (v, r) => (
<div style={{display:"flex",columnGap:10,justifyContent:"center"}}>
<span>{record?.scoreWay ==1 ? "取最低": record?.scoreWay ==2 ? "平均" : ''}</span>
<span>{v}</span>
</div>
)
})
columns.splice(3, 1, ...insertCols)
const width = columns?.reduce((total, cur) => total + (cur?.width || 0), 0);
setQdWidth(width)
setQdColumns(columns)
result.forEach(item => {
if (item.rowSpan) delete item.rowSpan;
})
const newData = handleData(result, "name")
setTableData(newData)
}
} catch (error) {
console.log(error);
}
}
// 重置评分
const resetPf = () => {
const newData = [...tableData];
newData.forEach(item => {
item.assessScore = ''
})
setTableData(newData)
tableDataRef.current = newData
}
// 保存评分
const savepf = async () => {
const params = {
taskId: record.id,
score,
ratings: tableData.map(item => ({
indicatorId: item.indicatorId,
standardScore: item.standardScore,
assessScore: item.assessScore,
teamId: Item.id,
isNeedRectify: item.isNeedRectify || 0,
problemDesc: item.problemDesc,
rectifyRequirement: item.rectifyRequirement,
rectifyLastDate: item.rectifyLastDate,
files: item.files,
fileList:undefined,
rectifyStatus:0
}))
}
try {
const res =await httppost2(apiurl.rcgl.jdkh.khrwgl.savePf, params)
if (res.code == 200) {
message.success("保存成功")
refresh()
} else {
message.error("保存失败")
}
} catch (error) {
console.log(error);
}
}
// 确认完成
const confirm = async () => {
const params = {
taskId: record.id,
score,
ratings: tableData.map(item => ({
indicatorId: item.indicatorId,
standardScore: item.standardScore,
assessScore: item.assessScore,
teamId: Item.id,
isNeedRectify: item.isNeedRectify || 0,
problemDesc: item.problemDesc,
rectifyRequirement: item.rectifyRequirement,
rectifyLastDate: item.rectifyLastDate,
files: item.files,
fileList:undefined,
rectifyStatus:0
}))
}
if(tableData.length>0){
let flag = true //fasle有位评分的
params.ratings?.map((item)=>{
if(item.assessScore==null){
flag = false
}
})
if(!flag){
message.error('请输入全部考核评分')
return
}
}
try {
const res = await httppost2(apiurl.rcgl.jdkh.khrwgl.confirmpf, params)
if (res.code == 200) {
message.success("评分完成")
refresh()
onCancel()
}
} catch (error) {
console.log(error);
}
}
// 查看评分详情
const [zgViewOpen, setzgViewOpen] = useState(false)
const zgView = (record) => {
setzgViewOpen(true)
setZgItem(record)
}
const [clickItem, setClickItem] = useState()
// 点击某一行的回调
const handleRowClick = (record) => {
setClickItem(record)
}
const handleRadioChange = (e) => {
if (e.target.value == 1) {
if (tabs == 2) {
getQdViewData(Item?.id)
} else {
getZbTableData(Item?.id,2)
}
} else {
// debugger
const newData = tabs == 2 ? tableData.filter(item => item.standardScore > item.indicatorScore) :
tableData.filter(item => item.standardScore > item.assessScore)
newData.forEach(item => {
if (item.rowSpan) delete item.rowSpan;
})
const res = handleData(newData, "name")
setTableData(res);
}
}
// 整改
const [zgOpen, setZgOpen] = useState(false)
const [form1] = Form.useForm();
const [loading, setLoading] = useState(false)
const [imgloading, setImgLoading] = useState(false)
const [imgfileList, setImgFileList] = useState([]) //上传文件列表
const [zgItem, setZgItem] = useState("")
const zgCallback = (e) => {
setZgOpen(true)
setZgItem(e)
console.log("ee",e);
}
const imgbeforeUpload = (file) => {
const isJpgOrPng =
file.type === 'image/jpeg' ||
file.type === 'image/jpg' ||
file.type === 'image/png';
if (!isJpgOrPng) {
message.error('请上传图片格式的文件!');
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.error('图片大小需小于5M!');
}
return isJpgOrPng && isLt2M ? true : Upload.LIST_IGNORE;
};
const imgdeleteFile = (fileId) => {
let filterFile = imgfileList.filter(item => item.response?.data?.fileId !== fileId);
setImgFileList(filterFile)
}
const imgfileChange = (info) => {
console.log("info",info);
if (info.file.status === "done") {
setImgLoading(false);
}
if (info.file.status === "uploading") {
setImgLoading(true);
}
if (info.file.status === "error") {
message.error("文件上传失败")
setImgLoading(false);
}
setImgFileList(info.fileList)
}
// 整改数据
const onfinish = (values) => {
let files = imgfileList.map(item => ({ fileId: item.response?.data?.fileId }))
values.files = files;
values.isNeedRectify = 1;
values.fileList = imgfileList.map(item => item.response.data);
const newData = tableData.map(item => {
if (item.id == zgItem.id) {
return {...item, ...values}
} else {
return item
}
})
setTableData(newData)
setZgOpen(false)
setZgItem("")
form1.resetFields();
}
// 获取指标表格数据
useEffect(() => {
// if (Item.type != "start") {
// if (tabs == 2) {
// getQdViewData(Item?.id)
// } else {
// getZbTableData(Item?.id,2)
// }
// } else {
// getZbTableData(record?.templateId,1)
// }
if (tabs == 2) {
getQdViewData(Item?.id)
} else {
getZbTableData(Item?.id,2)
}
}, [record, Item])
useEffect(() => {
const file = zgItem?.fileList ? zgItem.fileList : zgItem.files
if (file) {
const imgFile = file?.map(o => ({
name: o.fileName,
response: {
data: {
filePath: o.filePath,
fileId:o.fileId
}
},
}))
setImgFileList(imgFile)
} else {
setImgFileList([])
}
form1.setFieldsValue({...zgItem})
}, [zgItem])
return (
<div>
<Radio.Group style={{marginBottom:10}} defaultValue={1} onChange={(e) => handleRadioChange(e)}>
<Radio value={1}>显示全部</Radio>
<Radio value={2}>仅显示扣分项目</Radio>
</Radio.Group>
<Table
components={components}
rowKey="id"
columns={Item?.tabs != 2 ?newcolumns :qdColumns }
dataSource={tableData}
scroll={{x:Item?.tabs != 2 ? 500: qdWidth, y: "calc( 100vh - 400px )"}}
pagination={false}
onRow={(record, rowIndex) => {
return {
onClick: () => handleRowClick(record),
onDoubleClick:(record, rowIndex) => setClickItem()
};
}}
/>
{clickItem ? <div style={{backgroundColor:"#f2f2f2",marginTop:20,padding:10}}>
{clickItem?.indicatorRatings?.map(item => (
<div key={item.id}>
<div>{item?.ratingDesc}</div>
</div>
))}
</div> : null}
{!Item?.view ?
<div className='btns' style={{display:"flex",marginTop:40,justifyContent:"space-between"}}>
<Button type="primary" onClick={resetPf}>重置评分</Button>
<div style={{display:"flex",columnGap:10}}>
<Button type="primary" onClick={onCancel}>取消</Button>
<Button onClick={savepf}>保存</Button>
<Button type="primary" onClick={confirm}>确认完成</Button>
</div>
</div>
:
<div className='btns' style={{display:"flex",marginTop:40,justifyContent:"flex-end"}}>
<Button onClick={onCancel} type='primary'>关闭</Button>
</div>
}
{/* 整改 */}
<Modal
open={zgOpen}
width={800}
footer={null}
onCancel={() => { setZgOpen(false);form1.resetFields(); }}
title="整改详情"
destroyOnClose={true}
>
<Form
form={form1}
{...formItemLayout}
onFinish={onfinish}
// initialValues={zgItem}
>
<Row>
<Col span={24}>
<Form.Item
label="问题描述"
name="problemDesc"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
rules={[
{
required: true,
},
]}
>
<Input.TextArea style={{width:'100%',minHeight:'100px'}} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="整改要求"
name="rectifyRequirement"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<Input.TextArea style={{width:'100%',minHeight:'100px'}} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item
label="整改期限"
name="rectifyLastDate"
getValueFromEvent={(e,dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
>
<DatePicker format={'YYYY-MM-DD'} style={{width:'100%'}} allowClear />
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="现场图片"
name="fieldId"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<Dragger
name='file'
action="/gunshiApp/tsg/assessTeamRating/file/upload/singleSimple"
onChange={imgfileChange}
beforeUpload={imgbeforeUpload}
onDrop={(info) => { console.log(info); }}
fileList={imgfileList}
disabled={imgloading}
>
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
<p className="ant-upload-hint">
支持扩展名.jpg .png
</p>
</Dragger>
<Row gutter={[16]}>
{
loading ? <span>文件正在上传中请等待</span> :
imgfileList.length > 0 && imgfileList.map(file => {
return (
<Col span={12}>
<div className={'file-item'} >
<div className='file-description'>
<Image width={60} src={url +file.response?.data?.filePath} alt='' />
<span>{file.name}</span>
</div>
<div
className={'delete-icon'}
onClick={() => imgdeleteFile(file.response?.data?.fileId)}
>
<DeleteOutlined
/>
</div>
</div>
</Col>
)
})
}
</Row>
</Form.Item>
</Col>
</Row>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</Form>
</Modal>
{/* 评分详情中整改的详情查看 */}
<Modal
open={zgViewOpen}
width={800}
footer={null}
onCancel={() => { setzgViewOpen(false); ;setZgItem('');}}
title="查看"
destroyOnClose
wrapClassName='zgview-modal'
>
<PfViewModal zgItem={zgItem} record={Item} onCancel={() => {setzgViewOpen(false); ;setZgItem('');}} />
</Modal>
</div>
)
}