dev_1.2
tangjie 2026-07-27 10:54:22 +08:00
parent 45d7838757
commit f7ab71d7b8
5 changed files with 297 additions and 102 deletions

View File

@ -0,0 +1,84 @@
{
"openapi": "3.0.1",
"info": {
"title": "新增签字任务",
"version": "1.0.0"
},
"paths": {
"/safetyEval/institution/eval-sign-task/save": {
"post": {
"summary": "新增签字任务",
"tags": ["机构端-签字任务"],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/EvalSignTaskSaveCmd" }
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/SingleResponseEvalSignTaskCO" }
}
}
}
}
}
}
},
"components": {
"schemas": {
"EvalSignTaskSaveCmd": {
"type": "object",
"properties": {
"projectId": { "type": "string", "description": "项目ID" },
"nodeCode": {
"type": "string",
"description": "所属节点编码NODE_01风险分析 NODE_02业务合同 NODE_03项目组成立 NODE_04现场踏勘 NODE_05报告编制 NODE_06内部审核 NODE_07技术审核 NODE_08过程控制"
},
"bizRefId": { "type": "string", "description": "业务关联ID" },
"signerPersonnelId": { "type": "string", "description": "签字人员ID" },
"taskTitle": { "type": "string", "description": "任务标题" },
"taskStatusCode": { "type": "integer", "description": "任务状态编码1待签 2已签 3已作废" },
"issueTime": { "type": "string", "description": "下发时间" },
"signerUrl": { "type": "string", "description": "签字图片" },
"remarks": { "type": "string", "description": "备注" }
},
"required": ["projectId"]
},
"SingleResponseEvalSignTaskCO": {
"type": "object",
"properties": {
"success": { "type": "boolean", "description": "是否成功" },
"code": { "type": "string", "description": "响应码" },
"message": { "type": "string", "description": "响应消息" },
"errMessage": { "type": "string", "description": "错误响应消息" },
"data": { "$ref": "#/components/schemas/EvalSignTaskCO" }
}
},
"EvalSignTaskCO": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "签字任务ID" },
"orgId": { "type": "string", "description": "机构ID" },
"projectId": { "type": "string", "description": "项目ID" },
"nodeCode": { "type": "string", "description": "所属节点编码" },
"bizRefId": { "type": "string", "description": "业务关联ID" },
"signerPersonnelId": { "type": "string", "description": "签字人员ID" },
"taskTitle": { "type": "string", "description": "任务标题" },
"taskStatusCode": { "type": "integer", "description": "任务状态编码1待签 2已签 3已作废" },
"taskStatusName": { "type": "string", "description": "任务状态名称" },
"issueTime": { "type": "string", "description": "下发时间" },
"signerUrl": { "type": "string", "description": "签字图片" },
"remarks": { "type": "string", "description": "备注" },
"createName": { "type": "string", "description": "创建人" },
"createTime": { "type": "string", "description": "创建时间" },
"updateTime": { "type": "string", "description": "更新时间" }
}
}
}
}
}

View File

@ -0,0 +1,49 @@
// POST /safetyEval/institution/eval-sign-task/save
// See ./spec.json
export interface EvalSignTaskSaveCmd {
/** 项目ID */
projectId: string;
/** 所属节点编码NODE_01风险分析 NODE_02业务合同 NODE_03项目组成立 NODE_04现场踏勘 NODE_05报告编制 NODE_06内部审核 NODE_07技术审核 NODE_08过程控制 */
nodeCode?: string;
/** 业务关联ID */
bizRefId?: string;
/** 签字人员ID */
signerPersonnelId?: string;
/** 任务标题 */
taskTitle?: string;
/** 任务状态编码1待签 2已签 3已作废 */
taskStatusCode?: 1 | 2 | 3;
/** 下发时间 */
issueTime?: string;
/** 签字图片 */
signerUrl?: string;
/** 备注 */
remarks?: string;
}
export interface EvalSignTaskCO {
id: string;
orgId: string;
projectId: string;
nodeCode: string;
bizRefId: string;
signerPersonnelId: string;
taskTitle: string;
taskStatusCode: 1 | 2 | 3;
taskStatusName: string;
issueTime: string;
signerUrl: string;
remarks: string;
createName: string;
createTime: string;
updateTime: string;
}
export interface SingleResponseEvalSignTaskCO {
success: boolean;
code: string;
message: string;
errMessage: string;
data: EvalSignTaskCO;
}

View File

@ -13,8 +13,8 @@ module.exports = {
//API_HOST: "https://gbs-gateway.qhdsafety.com", //API_HOST: "https://gbs-gateway.qhdsafety.com",
//API_HOST: "http://192.168.0.152", //API_HOST: "http://192.168.0.152",
API_HOST: "http://192.168.0.150", //太浅 //API_HOST: "http://192.168.0.150", //太浅
// API_HOST: "http://192.168.0.152", API_HOST: "http://192.168.0.152",
//API_HOST: "http://192.168.0.103", //huwei //API_HOST: "http://192.168.0.103", //huwei
}, },
production: { production: {

View File

@ -130,6 +130,11 @@ export const evalRiskAnalysisPeopleSave = declareRequest(
"Post > @/safetyEval/institution/eval-risk-analysis/participant/save", "Post > @/safetyEval/institution/eval-risk-analysis/participant/save",
); );
export const evalSignTaskSave = declareRequest(
"evalSignTaskSaveLoading",
"Post > @/safetyEval/institution/eval-sign-task/save",
);
export const evalProjectMemberPage = declareRequest( export const evalProjectMemberPage = declareRequest(
"memberLoading", "memberLoading",
"Get > /safetyEval/institution/eval-project-member/page", "Get > /safetyEval/institution/eval-project-member/page",

View File

@ -41,17 +41,20 @@ const RiskAnalysisContent = (props) => {
evalRiskAnalysisGet, evalRiskAnalysisGet,
evalRiskAnalysisSave, evalRiskAnalysisSave,
evalRiskAnalysisPeopleSave, evalRiskAnalysisPeopleSave,
evalSignTaskSave,
} = props; } = props;
const { const {
riskAnalysisLoading, riskAnalysisLoading,
evalProjectDetailLoading, evalProjectDetailLoading,
riskAnalysisSaveLoading, riskAnalysisSaveLoading,
evalSignTaskSaveLoading,
evalProjectDetailData, evalProjectDetailData,
} = safetyEvalBusiness || {}; } = safetyEvalBusiness || {};
// 查询风险分析数据回显 // 查询风险分析数据回显
const [participantModalOpen, setParticipantModalOpen] = useState(false); const [participantModalOpen, setParticipantModalOpen] = useState(false);
const [selectedParticipantIds, setSelectedParticipantIds] = useState([]); const [selectedParticipantIds, setSelectedParticipantIds] = useState([]);
const [signingIndex, setSigningIndex] = useState(null);
const addParticipantRef = useRef(null); const addParticipantRef = useRef(null);
const fetchData = async () => { const fetchData = async () => {
@ -108,11 +111,37 @@ const RiskAnalysisContent = (props) => {
); );
if (result.success) { if (result.success) {
message.success(statusCode === 2 ? "风险分析已完成" : "已暂存"); message.success(statusCode === 2 ? "风险分析已完成" : "已暂存");
props.getDetail() props.getDetail();
} }
} }
}; };
// 发起APP签字
const handleSignApp = async (fieldName) => {
const participant = form.getFieldValue(["participants", fieldName]);
if (!participant?.personnelId) {
message.warning("该人员信息不完整,请先保存后再发起签字");
return;
}
setSigningIndex(fieldName);
try {
const res = await evalSignTaskSave({
projectId,
nodeCode: "RISK_ANALYSIS",
bizRefId: form.getFieldValue("id") || undefined,
signerPersonnelId: participant.personnelId,
taskTitle: "风险分析签字",
taskStatusCode: 1,
});
if (res?.success) {
message.success("已发起APP签字");
form.setFieldValue(["participants", fieldName, "signStatusCode"], 1);
}
} finally {
setSigningIndex(null);
}
};
return ( return (
<Spin spinning={evalProjectDetailLoading || riskAnalysisLoading}> <Spin spinning={evalProjectDetailLoading || riskAnalysisLoading}>
<div> <div>
@ -301,82 +330,108 @@ const RiskAnalysisContent = (props) => {
{(fields, { add, remove }) => { {(fields, { add, remove }) => {
addParticipantRef.current = add; addParticipantRef.current = add;
return ( return (
<> <>
<Table <Table
dataSource={fields} dataSource={fields}
columns={[ columns={[
{ {
title: "姓名", title: "姓名",
dataIndex: "name", dataIndex: "name",
render: (_, field) => { render: (_, field) => {
const { key, ...fieldProps } = field; const { key, ...fieldProps } = field;
return ( return (
<Form.Item <Form.Item
{...fieldProps} {...fieldProps}
name={[field.name, "personnelName"]} name={[field.name, "personnelName"]}
noStyle noStyle
> >
<Input <Input
placeholder="姓名" placeholder="姓名"
disabled disabled
maxLength={20} maxLength={20}
allowClear allowClear
/> />
</Form.Item> </Form.Item>
); );
},
}, },
}, {
{ title: "部门/岗位",
title: "部门/岗位", dataIndex: "deptName",
dataIndex: "deptName", render: (_, field) => {
render: (_, field) => { const { key, ...fieldProps } = field;
const { key, ...fieldProps } = field; return (
return ( <Form.Item
<Form.Item {...fieldProps}
{...fieldProps} name={[field.name, "deptName"]}
name={[field.name, "deptName"]} noStyle
noStyle >
> <Input
<Input placeholder="部门/岗位"
placeholder="部门/岗位" disabled
disabled maxLength={20}
maxLength={20} allowClear
allowClear />
/> </Form.Item>
</Form.Item> );
); },
}, },
}, {
{ title: "分析意见",
title: "分析意见", dataIndex: "opinion",
dataIndex: "opinion", render: (_, field) => {
render: (_, field) => { const { key, ...fieldProps } = field;
const { key, ...fieldProps } = field; return (
return ( <Form.Item
<Form.Item {...fieldProps}
{...fieldProps} name={[field.name, "opinion"]}
name={[field.name, "opinion"]} noStyle
noStyle >
> <Input
<Input placeholder="填写分析意见"
placeholder="填写分析意见" maxLength={30}
maxLength={30} allowClear
allowClear />
/> </Form.Item>
</Form.Item> );
); },
}, },
}, {
{ title: "签字状态",
title: "签字状态", render: (_, field) => {
render: (_, field) => ( const value = form.getFieldValue([
<Button size="small">发起APP签字</Button> "participants",
), field.name,
}, "signStatusCode",
{ ]);
title: "操作", let text = "发起APP签字";
render: (_, field) =>
fields.length > 1 ? ( if (value === 1) {
text = "待APP签字";
}
if (value === 2) {
text = "已手写签字";
}
return (
<Button
size="small"
loading={
evalSignTaskSaveLoading &&
signingIndex === field.name
}
disabled={value === 1 || value === 2}
onClick={() => handleSignApp(field.name)}
>
{text}
</Button>
);
},
},
{
title: "操作",
render: (_, field) => (
<Button <Button
type="link" type="link"
danger danger
@ -385,26 +440,26 @@ const RiskAnalysisContent = (props) => {
> >
删除 删除
</Button> </Button>
) : null, ),
}, },
]} ]}
rowKey={(_, index) => index} rowKey={(_, index) => index}
pagination={false} pagination={false}
/> />
<Button <Button
type="dashed" type="dashed"
size="small" size="small"
style={{ marginTop: 8 }} style={{ marginTop: 8 }}
onClick={() => { onClick={() => {
setSelectedParticipantIds([]); setSelectedParticipantIds([]);
setParticipantModalOpen(true); setParticipantModalOpen(true);
}} }}
> >
添加参与人员 添加参与人员
</Button> </Button>
</> </>
); );
}} }}
</Form.List> </Form.List>
</Card> </Card>
@ -413,14 +468,16 @@ const RiskAnalysisContent = (props) => {
open={participantModalOpen} open={participantModalOpen}
onCancel={() => setParticipantModalOpen(false)} onCancel={() => setParticipantModalOpen(false)}
onOk={() => { onOk={() => {
const selected = (evalProjectDetailData?.participants || []).filter( const selected = (
(p) => selectedParticipantIds.includes(p.id), evalProjectDetailData?.participants || []
); ).filter((p) => selectedParticipantIds.includes(p.id));
selected.forEach((p) => { selected.forEach((p) => {
addParticipantRef.current?.({ addParticipantRef.current?.({
personnelId: p.id,
personnelName: p.name, personnelName: p.name,
deptName: p.deptName, deptName: p.deptName,
opinion: "", opinion: "",
projectId,
}); });
}); });
setParticipantModalOpen(false); setParticipantModalOpen(false);
@ -428,9 +485,9 @@ const RiskAnalysisContent = (props) => {
> >
<Table <Table
dataSource={(() => { dataSource={(() => {
const existing = (form.getFieldValue("participants") || []).map( const existing = (
(p) => p.personnelName, form.getFieldValue("participants") || []
); ).map((p) => p.personnelName);
return (evalProjectDetailData?.participants || []).filter( return (evalProjectDetailData?.participants || []).filter(
(p) => !existing.includes(p.name), (p) => !existing.includes(p.name),
); );