dev-tmp1
tangjie 2026-08-20 11:23:54 +08:00
parent 998911c179
commit 2a737ef53f
4 changed files with 69 additions and 15 deletions

View File

@ -76,6 +76,11 @@ export const evalProjectDetail = declareRequest(
'evalProjectDetailData: {} | res.data || {}', 'evalProjectDetailData: {} | res.data || {}',
); );
export const evalProjectUpdate = declareRequest(
"evalProjectUpdateLoading",
"Post > @/safetyEval/institution/eval-project/update",
);
export const evalProjectDelete = declareRequest( export const evalProjectDelete = declareRequest(
"evalProjectDeleteLoading", "evalProjectDeleteLoading",
"Post > @/safetyEval/institution/eval-project/delete", "Post > @/safetyEval/institution/eval-project/delete",

View File

@ -40,10 +40,13 @@ const EvalProjectCreate = (props) => {
const [detailLoading, setDetailLoading] = useState(false); const [detailLoading, setDetailLoading] = useState(false);
const projectId = router.query?.id; const projectId = router.query?.id;
const isView = projectId; // 编辑模式:仅可编辑项目参与人员,其余字段禁用
const isEditParticipant = !!projectId && router.query?.edit === "participant";
const isView = !!projectId && !isEditParticipant;
const { const {
evalProjectSaveLoading, evalProjectSaveLoading,
evalProjectUpdateLoading,
evalProjectDetailLoading, evalProjectDetailLoading,
customerPage: customerList, customerPage: customerList,
} = props.safetyEvalBusiness; } = props.safetyEvalBusiness;
@ -112,12 +115,14 @@ const EvalProjectCreate = (props) => {
: item.capacity, : item.capacity,
})), })),
}; };
if (isView) { if (projectId) {
params.id = projectId; params.id = projectId;
} }
const res = await props.evalProjectSave(params); const res = isEditParticipant
? await props.evalProjectUpdate(params)
: await props.evalProjectSave(params);
if (res?.success) { if (res?.success) {
message.success(isView ? "修改成功" : "创建成功"); message.success(isEditParticipant ? "编辑成功" : "创建成功");
props.history.goBack(); props.history.goBack();
} }
}); });
@ -130,7 +135,13 @@ const EvalProjectCreate = (props) => {
return ( return (
<PageLayout <PageLayout
title={isView ? "查看安全评价项目" : "新建安全评价项目"} title={
isView
? "查看安全评价项目"
: isEditParticipant
? "编辑项目参与人员"
: "新建安全评价项目"
}
history={props.history} history={props.history}
previous previous
footer={ footer={
@ -140,16 +151,25 @@ const EvalProjectCreate = (props) => {
<Button <Button
type="primary" type="primary"
onClick={handleSubmit} onClick={handleSubmit}
loading={detailLoading || evalProjectSaveLoading} loading={
detailLoading ||
evalProjectSaveLoading ||
evalProjectUpdateLoading
}
> >
提交并返回项目列表 {isEditParticipant ? "保存并返回项目列表" : "提交并返回项目列表"}
</Button> </Button>
</Flex> </Flex>
) )
} }
loading={detailLoading} loading={detailLoading}
> >
<Form form={form} layout="vertical" disabled={isView} scrollToFirstError> <Form
form={form}
layout="vertical"
disabled={!!projectId}
scrollToFirstError
>
<Card title="项目基本信息" style={{ marginBottom: 24 }}> <Card title="项目基本信息" style={{ marginBottom: 24 }}>
<Row gutter={24}> <Row gutter={24}>
<Col span={12}> <Col span={12}>
@ -389,6 +409,7 @@ const EvalProjectCreate = (props) => {
<Input <Input
placeholder="点击选择参与人员" placeholder="点击选择参与人员"
readOnly readOnly
disabled={isView}
value={ value={
selectedParticipants.length selectedParticipants.length
? `已选 ${selectedParticipants.length}` ? `已选 ${selectedParticipants.length}`
@ -403,6 +424,7 @@ const EvalProjectCreate = (props) => {
<Tag <Tag
key={item.id} key={item.id}
closable={!isView} closable={!isView}
disabled={isView}
onClose={() => onClose={() =>
setSelectedParticipants((prev) => setSelectedParticipants((prev) =>
prev.filter((r) => r.id !== item.id), prev.filter((r) => r.id !== item.id),

View File

@ -16,6 +16,7 @@ import {
} from "@ant-design/icons"; } from "@ant-design/icons";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import SearchForm from "~/components/SearchForm"; import SearchForm from "~/components/SearchForm";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper"; import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd"; import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
@ -114,10 +115,10 @@ const EvalProject = (props) => {
}, },
{ {
title: "操作", title: "操作",
width: 160, width: 200,
fixed: "right", fixed: "right",
render: (_, record) => ( render: (_, record) => (
<Space> <TableAction>
<Button <Button
type="link" type="link"
size="small" size="small"
@ -125,16 +126,24 @@ const EvalProject = (props) => {
> >
查看 查看
</Button> </Button>
<Button
type="link"
size="small"
onClick={() =>
props.history.push(`Create?id=${record.id}&edit=participant`)
}
>
编辑
</Button>
<Button <Button
type="link" type="link"
size="small" size="small"
danger danger
onClick={() => handleDelete(record)} onClick={() => handleDelete(record)}
> >
删除 删除
</Button> </Button>
</Space> </TableAction>
), ),
}, },
]; ];

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Form, Button, Flex, Typography, Steps, Tag, Card, Table, message, Popover, Image, Checkbox } from "antd"; import { Form, Button, Flex, Typography, Steps, Tag, Card, Table, message, Popover, Image, Checkbox } from "antd";
import { CheckCircleFilled, DownloadOutlined, QuestionOutlined } from "@ant-design/icons"; import { CheckCircleFilled, DownloadOutlined, QuestionOutlined, PictureOutlined } from "@ant-design/icons";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib"; import { tools } from "@cqsjjb/jjb-common-lib";
@ -73,6 +73,24 @@ const NoticePanel = ({ readOnly }) => (
</div> </div>
); );
/** 打卡时间后追加人脸照片图标faceUrl 逗号分隔第1张为签到、第2张为签退 */
const renderTimeWithFace = (time, record, idx) => {
const url = record?.faceUrl?.split(",")[idx];
if (!url) return time || "-";
return (
<span>
{time}
<Popover
content={<Image src={url} width={240} />}
title="人脸照片"
trigger="hover"
>
<PictureOutlined style={{ marginLeft: 6, color: "#1677ff", cursor: "pointer" }} />
</Popover>
</span>
);
};
const InspectionPanel = ({ dataSource = [], evalProjectDetailData = {}, readOnly }) => { const InspectionPanel = ({ dataSource = [], evalProjectDetailData = {}, readOnly }) => {
const calcDuration = (signIn, signOut) => { const calcDuration = (signIn, signOut) => {
if (!signIn || !signOut) return '-'; if (!signIn || !signOut) return '-';
@ -103,8 +121,8 @@ const InspectionPanel = ({ dataSource = [], evalProjectDetailData = {}, readOnly
{ title: "项目角色", dataIndex: "role", render: (v) => Array.isArray(v) ? v.map(item => ROLE_DEFINITIONS_MAP[item]).join('、') : v, ellipsis: true }, { title: "项目角色", dataIndex: "role", render: (v) => Array.isArray(v) ? v.map(item => ROLE_DEFINITIONS_MAP[item]).join('、') : v, ellipsis: true },
{ title: "人脸识别", dataIndex: "faceState", render: (v) => <Tag color={v === 1 ? "success" : "error"}>{v === 1 ? "通过" : "未通过"}</Tag> }, { title: "人脸识别", dataIndex: "faceState", render: (v) => <Tag color={v === 1 ? "success" : "error"}>{v === 1 ? "通过" : "未通过"}</Tag> },
{ title: "GPS定位", dataIndex: "gpsState", render: (v) => <Tag color={v === 1 ? "success" : "error"}>{v === 1 ? "正常" : "异常"}</Tag> }, { title: "GPS定位", dataIndex: "gpsState", render: (v) => <Tag color={v === 1 ? "success" : "error"}>{v === 1 ? "正常" : "异常"}</Tag> },
{ title: "签到时间", dataIndex: "singInTime" }, { title: "签到时间", dataIndex: "singInTime" , render: (time, record)=>{return renderTimeWithFace(time, record, 0);}},
{ title: "签退时间", dataIndex: "signOutTime" }, { title: "签退时间", dataIndex: "signOutTime" , render: (time, record)=>{return renderTimeWithFace(time, record, 1);}},
{ title: "在场时长", render: (_, r) => calcDuration(r.singInTime, r.signOutTime) }, { title: "在场时长", render: (_, r) => calcDuration(r.singInTime, r.signOutTime) },
{ {
title: "现场照片", dataIndex: "sceneUrl", render: (v) => { title: "现场照片", dataIndex: "sceneUrl", render: (v) => {