tangjie 2026-08-05 15:30:43 +08:00
parent cb9137eab3
commit 6605938618
4 changed files with 101 additions and 55 deletions

View File

@ -10,9 +10,9 @@ module.exports = {
javaGitBranch: "dev", javaGitBranch: "dev",
// 本地联调 safetyEval-servicecontext-path: /safetyEval默认端口 8095 // 本地联调 safetyEval-servicecontext-path: /safetyEval默认端口 8095
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
// API_HOST: "https://gbs-gateway.qhdsafety.com", API_HOST: "https://gbs-gateway.qhdsafety.com",
API_HOST: "http://192.168.0.134", // API_HOST: "http://192.168.0.134",
//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

View File

@ -16,14 +16,7 @@ function includesSeniorTitle(titleName = "") {
return titleName === "SENIOR"; return titleName === "SENIOR";
} }
function includesMidTitle(titleName = "") {
return titleName === "MIDDLE" || titleName === "SENIOR";
}
function isRegisterEngineer(record = {}) {
const flag = record.registerEngineerFlag;
return flag === 1 || flag === true || flag === "1";
}
export function verifyFilingPrerequisites(detail = {}) { export function verifyFilingPrerequisites(detail = {}) {
const items = []; const items = [];
@ -47,21 +40,17 @@ export function verifyFilingPrerequisites(detail = {}) {
const personnel = detail.personnelList || []; const personnel = detail.personnelList || [];
const total = personnel.length; const total = personnel.length;
const regEngineerCount = personnel.filter(isRegisterEngineer).length;
const midTitleCount = personnel.filter((p) => const businessScopeCount = Array.isArray(detail.businessScope) ? detail.businessScope.length : 0;
includesMidTitle(p.titleName), const minPersonnel = 25 + Math.max(businessScopeCount - 1, 0) * 5;
).length;
const seniorTitleCount = personnel.filter((p) =>
includesSeniorTitle(p.titleName),
).length;
items.push({ items.push({
key: "personnelStructure", key: "personnelStructure",
label: "人员数量与结构", label: "人员数量与结构",
desc: "专职技术人员≥25人", desc: `专职技术人员≥${minPersonnel}`,
passed: passed:
SKIP_PERSONNEL_VERIFY || SKIP_PERSONNEL_VERIFY ||
total >= 25 , total >= minPersonnel,
}); });
const twoYearsAgo = new Date(); const twoYearsAgo = new Date();
@ -79,7 +68,7 @@ export function verifyFilingPrerequisites(detail = {}) {
}) })
.map((p) => p.userName || p.personName || ""); .map((p) => p.userName || p.personName || "");
const personnelExpPassed = total >= 25 && ratio(withExperience, total) >= 1; const personnelExpPassed = ratio(withExperience, total) >= 1;
items.push({ items.push({
key: "personnelExp", key: "personnelExp",
label: "人员资历", label: "人员资历",

View File

@ -18,7 +18,11 @@ import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm"; import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper"; import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { PROGRESS_STATUS_MAP, NODE_LABELS } from "~/enumerate/constant"; import {
PROGRESS_STATUS_MAP,
NODE_LABELS,
EVAL_TYPE_MAP,
} from "~/enumerate/constant";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { tools } from "@cqsjjb/jjb-common-lib"; import { tools } from "@cqsjjb/jjb-common-lib";
import "./index.less"; import "./index.less";
@ -87,17 +91,24 @@ const ProjectProgress = (props) => {
}; };
const renderProgressDots = (nodes) => { const renderProgressDots = (nodes) => {
if (!nodes || nodes.length === 0) return <span className="pp-progress-empty">暂无进度</span>; if (!nodes || nodes.length === 0)
return <span className="pp-progress-empty">暂无进度</span>;
const total = nodes.length; const total = nodes.length;
const done = nodes.filter((n) => n.state === 1).length; const done = nodes.filter((n) => n.state === 1).length;
return ( return (
<div> <div>
<div className="pp-progress-dots"> <div className="pp-progress-dots">
{nodes.map((node, idx) => { {nodes.map((node, idx) => {
const dotClass = node.state === 1 ? "pp-progress-dot-done" : "pp-progress-dot-wait"; const dotClass =
node.state === 1
? "pp-progress-dot-done"
: "pp-progress-dot-wait";
const name = NODE_LABELS[node.type] || node.type; const name = NODE_LABELS[node.type] || node.type;
return ( return (
<Tooltip key={node.type || idx} title={`${name}: ${node.state === 1 ? "已完成" : "未完成"}`}> <Tooltip
key={node.type || idx}
title={`${name}: ${node.state === 1 ? "已完成" : "未完成"}`}
>
<span className={`pp-progress-dot ${dotClass}`} /> <span className={`pp-progress-dot ${dotClass}`} />
</Tooltip> </Tooltip>
); );
@ -122,8 +133,20 @@ const ProjectProgress = (props) => {
</div> </div>
), ),
}, },
{ title: "评价类别", dataIndex: "evalTypeName", width: 110 }, {
{ title: "负责人", dataIndex: "projectLeaderName", width: 100, ellipsis: true }, title: "评价类别",
dataIndex: "evalTypeCode",
width: 110,
render: (_, record) => {
return EVAL_TYPE_MAP[record.evalTypeCode];
},
},
{
title: "负责人",
dataIndex: "projectLeaderName",
width: 100,
ellipsis: true,
},
{ {
title: "项目进度", title: "项目进度",
width: 240, width: 240,
@ -142,8 +165,15 @@ const ProjectProgress = (props) => {
: `超期${Math.abs(record.remainingDays)}`; : `超期${Math.abs(record.remainingDays)}`;
return ( return (
<div> <div>
<div>{cfg ? <Tag color={cfg.color}>{cfg.text}-{daysText}</Tag> : <Tag>{code}</Tag>}</div> <div>
{cfg ? (
<Tag color={cfg.color}>
{cfg.text}-{daysText}
</Tag>
) : (
<Tag>{code}</Tag>
)}
</div>
</div> </div>
); );
}, },
@ -162,14 +192,15 @@ const ProjectProgress = (props) => {
return ( return (
<PageLayout title="项目进度管理"> <PageLayout title="项目进度管理">
<Row gutter={16} className="pp-stat-row"> <Row gutter={16} className="pp-stat-row">
<Col span={6}> <Col span={6}>
<Card size="small"> <Card size="small">
<Statistic <Statistic
title="项目总数" title="项目总数"
value={statData.totalCount ?? "-"} value={statData.totalCount ?? "-"}
suffix={<span className="pp-stat-suffix">当前机构名下评价项目</span>} suffix={
<span className="pp-stat-suffix">当前机构名下评价项目</span>
}
/> />
</Card> </Card>
</Col> </Col>
@ -179,7 +210,9 @@ const ProjectProgress = (props) => {
title="正常项目" title="正常项目"
value={statData.normalCount ?? "-"} value={statData.normalCount ?? "-"}
valueStyle={{ color: "#52c41a" }} valueStyle={{ color: "#52c41a" }}
suffix={<span className="pp-stat-suffix">距项目结束日期超过3天</span>} suffix={
<span className="pp-stat-suffix">距项目结束日期超过3天</span>
}
/> />
</Card> </Card>
</Col> </Col>
@ -189,7 +222,9 @@ const ProjectProgress = (props) => {
title="项目临期" title="项目临期"
value={statData.nearExpiryCount ?? "-"} value={statData.nearExpiryCount ?? "-"}
valueStyle={{ color: "#faad14" }} valueStyle={{ color: "#faad14" }}
suffix={<span className="pp-stat-suffix">项目结束前3天自动提醒</span>} suffix={
<span className="pp-stat-suffix">项目结束前3天自动提醒</span>
}
/> />
</Card> </Card>
</Col> </Col>
@ -199,14 +234,14 @@ const ProjectProgress = (props) => {
title="项目延期" title="项目延期"
value={statData.delayedCount ?? "-"} value={statData.delayedCount ?? "-"}
valueStyle={{ color: "#ff4d4f" }} valueStyle={{ color: "#ff4d4f" }}
suffix={<span className="pp-stat-suffix">已超过项目结束日期</span>} suffix={
<span className="pp-stat-suffix">已超过项目结束日期</span>
}
/> />
</Card> </Card>
</Col> </Col>
</Row> </Row>
<SearchForm <SearchForm
form={searchForm} form={searchForm}
loading={false} loading={false}
@ -236,8 +271,6 @@ const ProjectProgress = (props) => {
onReset={handleReset} onReset={handleReset}
/> />
<Table <Table
rowKey="id" rowKey="id"
columns={columns} columns={columns}
@ -265,27 +298,54 @@ const ProjectProgress = (props) => {
> >
{currentRecord && ( {currentRecord && (
<> <>
<Descriptions column={2} bordered size="small" className="pp-detail-desc"> <Descriptions
<Descriptions.Item label="项目编号">{currentRecord.projectNo}</Descriptions.Item> column={2}
<Descriptions.Item label="项目名称">{currentRecord.projectName}</Descriptions.Item> bordered
<Descriptions.Item label="客户名称">{currentRecord.customerName}</Descriptions.Item> size="small"
<Descriptions.Item label="客户负责人">{currentRecord.customerContactName}</Descriptions.Item> className="pp-detail-desc"
<Descriptions.Item label="评价类型">{currentRecord.evalTypeName}</Descriptions.Item> >
<Descriptions.Item label="项目负责人">{currentRecord.projectLeaderName}</Descriptions.Item> <Descriptions.Item label="项目编号">
<Descriptions.Item label="项目结束日期">{currentRecord.planEndDate}</Descriptions.Item> {currentRecord.projectNo}
</Descriptions.Item>
<Descriptions.Item label="项目名称">
{currentRecord.projectName}
</Descriptions.Item>
<Descriptions.Item label="客户名称">
{currentRecord.customerName}
</Descriptions.Item>
<Descriptions.Item label="客户负责人">
{currentRecord.customerContactName}
</Descriptions.Item>
<Descriptions.Item label="评价类型">
{currentRecord.evalTypeName}
</Descriptions.Item>
<Descriptions.Item label="项目负责人">
{currentRecord.projectLeaderName}
</Descriptions.Item>
<Descriptions.Item label="项目结束日期">
{currentRecord.planEndDate}
</Descriptions.Item>
<Descriptions.Item label="剩余天数"> <Descriptions.Item label="剩余天数">
<span <span
className={`pp-remaining-days ${ className={`pp-remaining-days ${
currentRecord.remainingDays < 0 ? "pp-remaining-danger" : currentRecord.remainingDays < 0
currentRecord.remainingDays <= 3 ? "pp-remaining-warn" : ? "pp-remaining-danger"
"pp-remaining-normal" : currentRecord.remainingDays <= 3
? "pp-remaining-warn"
: "pp-remaining-normal"
}`} }`}
> >
{currentRecord.remainingDays >= 0 ? `${currentRecord.remainingDays}` : `已超期${Math.abs(currentRecord.remainingDays)}`} {currentRecord.remainingDays >= 0
? `${currentRecord.remainingDays}`
: `已超期${Math.abs(currentRecord.remainingDays)}`}
</span> </span>
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="项目状态" span={2}> <Descriptions.Item label="项目状态" span={2}>
<Tag color={PROGRESS_STATUS_MAP[currentRecord.progressStatusCode]?.color}> <Tag
color={
PROGRESS_STATUS_MAP[currentRecord.progressStatusCode]?.color
}
>
{currentRecord.progressStatusName} {currentRecord.progressStatusName}
</Tag> </Tag>
</Descriptions.Item> </Descriptions.Item>

View File

@ -19,6 +19,7 @@ import {
import dayjs from "dayjs"; import dayjs from "dayjs";
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 {EVAL_TYPE_OPTIONS} from '~/enumerate/constant';
import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions"; import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
import { tools } from "@cqsjjb/jjb-common-lib"; import { tools } from "@cqsjjb/jjb-common-lib";
import AttachmentUpload from "~/components/AttachmentUpload"; import AttachmentUpload from "~/components/AttachmentUpload";
@ -26,11 +27,7 @@ import AttachmentUpload from "~/components/AttachmentUpload";
const { router } = tools; const { router } = tools;
const { TextArea } = Input; const { TextArea } = Input;
const EVAL_TYPE_OPTIONS = [
{ label: "安全预评价", value: "PRE" },
{ label: "安全验收评价", value: "ACCEPT" },
{ label: "安全现状评价", value: "STATUS" },
];
const RiskAnalysisContent = ({ readOnly, ...props }) => { const RiskAnalysisContent = ({ readOnly, ...props }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();