12.28 智能招标采购室-第二版

This commit is contained in:
jl-zhoujl2
2022-12-28 17:29:12 +08:00
parent e30573e862
commit 576ac70ce4
8 changed files with 522 additions and 513 deletions

View File

@ -11,6 +11,7 @@ const messageMap = {
403: '您的用户角色信息异常,请重新登录',
90401: '您的登录已超时,请重新登录',
404: '系统错误,请联系管理员',
405: '您的用户无权限访问'
};
const RequestTimeoutPage: React.FC<{}> = () => {

View File

@ -1,10 +1,9 @@
import { Col, Progress, Row, Table } from 'antd';
import { debounce } from 'lodash';
import { Col, Row } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import '../style.less'
import { onCell, onHeaderCell, OverviewItem, proviceEnum, ScreenLabel, ScreenTitle, ScrollTable } from '../Home';
import { authCheck, onCell, onHeaderCell, OverviewItem, ScreenLabel, ScreenTitle, ScrollTable } from '../Home';
import Circle3199 from '@/assets/monitor/circle-3199.png';
import { getDecryptDataAPI, getNoOpenAssessListAPI, getNoOpenListAPI, getNoOpenNumberAPI, getThreeDayNoEndAPI } from '../service';
import { getDecryptDataAPI, getNoOpenAssessListAPI, getNoOpenListAPI, getNoOpenNumberAPI, getThreeDayNoEndAPI, getThreeDaysUnSendAnnoCountAPI, getThreeDaysUnSendAnnoListAPI } from '../service';
const columns: any[] = [
{
@ -119,104 +118,6 @@ const columnsSecond: any[] = [
},
},
];
const dataSource = [
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "10:30",
vital: "1",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "10:30",
vital: "1",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "10:30",
vital: "1",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "10:30",
vital: "1",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
{
provinceDictId: "0012",
projectName: "天津设备采购",
number: "320万",
time: "9:30",
vital: "0",
people: "曹鹏",
},
]
const MonitorException: React.FC<{}> = () => {
//超过1小时未开标数量
@ -224,11 +125,17 @@ const MonitorException: React.FC<{}> = () => {
//开启评审后3日未结束评标-列表
const [threeDayNoEndData, setThreeDayNoEndData] = useState<any[]>([]);
//超过1小时未开标数量-列表
const [noOpenListData, setNoOpenListData] = useState<any[]>([]);
const [noOpenListData, setNoOpenListData] = useState<any>();
//开标后超过6小时未开启评审室-列表
const [noOpenAssessListData, setNoOpenAssessListData] = useState<any>();
//异常监控-解密异常、mac地址相同及相关项目列表
const [decryptData, setDecryptData] = useState<any>();
//评审室关闭3日内未发布公示数
const [threeDaysUnSendAnnoCount, setThreeDaysUnSendAnnoCount] = useState<string>("");
//评审室关闭3日内未发布公示列表
const [threeDaysUnSendAnnoList, setThreeDaysUnSendAnnoList] = useState<any[]>([]);
//权限校验
const auth = useRef<boolean>(authCheck());
//超过1小时未开标数量
const getNoOpenNumber = () => {
getNoOpenNumberAPI().then(res => {
@ -269,23 +176,45 @@ const MonitorException: React.FC<{}> = () => {
}
})
}
//异常监控-评审室关闭3日内未发布公示数
const getThreeDaysUnSendAnnoCount = () => {
getThreeDaysUnSendAnnoCountAPI().then(res => {
if (res?.code == 200) {
setThreeDaysUnSendAnnoCount(res?.data);
}
})
}
//异常监控-评审室关闭3日内未发布公示列表
const getThreeDaysUnSendAnnoList = () => {
getThreeDaysUnSendAnnoListAPI().then(res => {
if (res?.code == 200) {
setThreeDaysUnSendAnnoList(res?.data);
}
})
}
useEffect(() => {
if (auth.current) {
getNoOpenNumber();
getThreeDayNoEnd();
getNoOpenList();
getNoOpenAssessList();
getDecryptData();
getThreeDaysUnSendAnnoCount();
getThreeDaysUnSendAnnoList();
}
}, [])
return (
<ScreenTitle title="异常监控">
<div className="top-main">
<div className="monitor-top-space-flex">
<OverviewItem icon={Circle3199} title="一小时内未开标" number={noOpenNumberData} unit="" />
<OverviewItem icon={Circle3199} title="电子谈判总数" number={73185} unit="" />
<OverviewItem icon={Circle3199} title="MAC地址相同" number={decryptData?.macSameCount} unit="" />
<OverviewItem icon={Circle3199} title="开标后6小时未开启评审" number={noOpenAssessListData?.length} unit="" />
<OverviewItem icon={Circle3199} title="开启评审后3日未结束评标" number={threeDayNoEndData?.length} unit="" />
<OverviewItem icon={Circle3199} title="评标结束3日未公示" number={62520} unit="" />
<OverviewItem icon={Circle3199} title="一小时内未开标" number={noOpenNumberData} unit="" />
<OverviewItem icon={Circle3199} title="解密异常" number={decryptData?.decryptExceptionCount} unit="" />
<OverviewItem icon={Circle3199} title="MAC地址相同" number={decryptData?.macSameCount} unit="" />
<OverviewItem icon={Circle3199} title="开标后6小时未开启评审" number={noOpenAssessListData?.length} unit="" />
<OverviewItem icon={Circle3199} title="开启评审后3日未结束评标" number={threeDayNoEndData?.length} unit="" />
<OverviewItem icon={Circle3199} title="评标结束3日未公示" number={threeDaysUnSendAnnoCount} unit="" />
<OverviewItem icon={Circle3199} title="重新评标次数" number={62520} unit="次" />
</div>
</div>
@ -294,7 +223,7 @@ const MonitorException: React.FC<{}> = () => {
<div className="monitor-left-main">
<ScreenLabel title="1小时未开标项目列表" extra={<span>more</span>} />
<div className="monitor-exception-card">
<ScrollTable dataSource={noOpenListData} columns={columns} ynum={266} />
<ScrollTable dataSource={noOpenListData?.records} columns={columns} ynum={266} />
</div>
<ScreenLabel title="开标后六小时未开启评审" extra={<span>more</span>} />
<div className="monitor-exception-card">
@ -322,7 +251,7 @@ const MonitorException: React.FC<{}> = () => {
</div>
<ScreenLabel title="评标结束后3日内未发布公示" extra={<span>more</span>} />
<div className="monitor-exception-card">
<ScrollTable dataSource={dataSource} columns={columns} ynum={266} />
<ScrollTable dataSource={threeDaysUnSendAnnoList} columns={columnsSecond} ynum={266} />
</div>
</div>
</Col>

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,10 @@
import { Col, Progress, Row, Table } from 'antd';
import { debounce } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Col, Row } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import '../style.less'
import { GraphChart, onCell, onHeaderCell, OverviewItem, ProgressItem, proviceEnum, ScreenLabel, ScreenTitle, ScrollTable, StageCard, StatisticTable } from '../Home';
import Circle3197 from '@/assets/monitor/circle-3197.png';
import Circle3198 from '@/assets/monitor/circle-3198.png';
import { authCheck, onCell, onHeaderCell, OverviewItem, ProgressItem, proviceEnum, ScreenLabel, ScreenTitle, ScrollTable, StageCard } from '../Home';
import Circle3199 from '@/assets/monitor/circle-3199.png';
import Circle3200 from '@/assets/monitor/circle-3200.png';
import { getDecryptSuccessRateTodayAPI, getTodayInfoAPI } from '../service';
import { isNotEmpty } from '@/utils/CommonUtils';
const columns: any[] = [
{
@ -183,6 +180,8 @@ const OpenToday: React.FC<{}> = () => {
const [todayInfoData, setTodayInfoData] = useState<any>();
//今日开标-解密成功率
const [decryptSuccessRateTodayData, setDecryptSuccessRateTodayData] = useState<any>();
//权限校验
const auth = useRef<boolean>(authCheck());
//今日开标-评标阶段,评标及时率
const getTodayInfo = () => {
getTodayInfoAPI().then(res => {
@ -200,8 +199,10 @@ const OpenToday: React.FC<{}> = () => {
})
}
useEffect(() => {
if (auth.current) {
getTodayInfo();
getDecryptSuccessRateToday();
}
}, [])
return (
<ScreenTitle title="今日开标">
@ -222,16 +223,16 @@ const OpenToday: React.FC<{}> = () => {
<OverviewItem icon={Circle3199} title="完成率" number={90} unit="%" />
</div>
<div className="monitor-top-space-flex ">
<ProgressItem progress={30} title="解密成功率" leftTitle='解密成功' rightTitle='解密失败' leftNumber={decryptSuccessRateTodayData?.successNum} rightNumber={decryptSuccessRateTodayData?.failNum} />
<ProgressItem progress={isNotEmpty(decryptSuccessRateTodayData?.successRate) ? Number(decryptSuccessRateTodayData?.successRate) : 0} title="解密成功率" leftTitle='解密成功' rightTitle='解密失败' leftNumber={isNotEmpty(decryptSuccessRateTodayData?.successNum) ? Number(decryptSuccessRateTodayData?.successNum) : 0} rightNumber={isNotEmpty(decryptSuccessRateTodayData?.failNum) ? Number(decryptSuccessRateTodayData?.failNum) : 0} />
<ProgressItem progress={70} title="开标及时率" leftTitle='2小时未开标' rightTitle='5小时未开标' leftNumber={1223} rightNumber={1223} />
<ProgressItem progress={90} title="评标及时率" leftTitle='6小时未评标' rightTitle='10小时未评标' leftNumber={1223} rightNumber={1223} />
<ProgressItem progress={90} title="评标及时率" leftTitle='6小时未评标' rightTitle='10小时未评标' leftNumber={todayInfoData?.sixTimelyRate} rightNumber={todayInfoData?.tenTimelyRate} />
</div>
</Col>
<Col span={7}>
<div className='monitor-tender-card'>
<ScreenLabel title="评标阶段" />
<div className='monitor-tender-card'>
<StageCard percentage={90} total={120} firstTitle="开启评审" firstNumber={`32个`} secondTitle="专家签到" secondNumber={`45/60`} thirdTitle="评审汇总" thirdNumber={`12`} />
<StageCard percentage={isNotEmpty(todayInfoData?.timelyRate) ? Number(todayInfoData?.timelyRate) : 0} total={isNotEmpty(todayInfoData?.sectionNumber) ? todayInfoData?.sectionNumber : 0} firstTitle="开启评审" firstNumber={`${isNotEmpty(todayInfoData?.openAssessNumber) ? todayInfoData?.openAssessNumber : 0}`} secondTitle="专家签到" secondNumber={`${isNotEmpty(todayInfoData?.signExpertNumber) ? todayInfoData?.signExpertNumber : 0}/${isNotEmpty(todayInfoData?.totalExpertNumber) ? todayInfoData?.totalExpertNumber : 0}`} thirdTitle="评审汇总" thirdNumber={`${isNotEmpty(todayInfoData?.resultNumber) ? todayInfoData?.resultNumber : 0}`} />
</div>
</div>
</Col>

View File

@ -1,11 +1,10 @@
import { Col, Progress, Row, Table } from 'antd';
import { debounce } from 'lodash';
import { Col, Progress, Row } from 'antd';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import '../style.less'
import { GraphChart, MetricItems, onCell, onHeaderCell, OverviewItem, proviceEnum, ScreenLabel, ScreenTitle, ScrollTable, SelectItem, StatisticTable } from '../Home';
import { authCheck, GraphChart, MetricItems, onCell, onHeaderCell, ScreenLabel, ScreenTitle, SelectItem, StatisticTable } from '../Home';
import Frame10116 from '@/assets/monitor/Frame-10116.png';
import Frame10121 from '@/assets/monitor/Frame-10121.png';
import { getActiveSupplierRankAPI, getProvinceActiveSupplierInfoAPI, getSupplierInfoAPI, getSupplierCountAPI } from '../service';
import { getActiveSupplierRankAPI, getProvinceActiveSupplierInfoAPI, getSupplierInfoAPI } from '../service';
const columns: any[] = [
{
@ -39,7 +38,7 @@ const columns: any[] = [
width: '25%',
onCell,
onHeaderCell,
render: (_: any, record: any, index: any) => <Progress percent={Number(record.progress)} strokeColor="#1B7EF2" trailColor="#124a8d" showInfo={false} />
render: (_: any, record: any, index: any) => <Progress percent={Number((record.tenderCount / record.maxTenderCount * 100).toFixed())} strokeColor="#1B7EF2" trailColor="#124a8d" showInfo={false} />
},
{
title: '中选次数',
@ -182,12 +181,14 @@ const dataSource = [
const Supplier: React.FC<{}> = () => {
//上面六个指标
const [supplierInfoData, setSupplierInfoData] = useState<any>();
//rackDataRef
const rankDataRef = useRef<any>();
//全国活跃供应商排名
const [activeSupplierRankData, setActiveSupplierRankData] = useState<any[]>([]);
//供应商概况-省份活跃供应商
const [provinceActiveSupplierInfoData, setProvinceActiveSupplierInfoData] = useState<any>();
//活跃供应商
const [supplierCount, setSupplierCount] = useState<any[]>([]);
//权限校验
const auth = useRef<boolean>(authCheck());
const transverseBarChart = useMemo(() => {
return true && <GraphChart type="transverseBar" chartData={[]} />
}, [])
@ -209,7 +210,9 @@ const Supplier: React.FC<{}> = () => {
const getActiveSupplierRank = () => {
getActiveSupplierRankAPI().then(res => {
if (res?.code == 200) {
setActiveSupplierRankData(res?.data);
const data = JSON.parse(res?.data)
rankDataRef.current = data;
onSelectChange("procurement_mode");
}
})
}
@ -221,19 +224,26 @@ const Supplier: React.FC<{}> = () => {
}
})
}
//供应商概况-参与供应商
const getSupplierCount = () => {
getSupplierCountAPI({ type: "year" }).then(res => {
if (res?.code == 200) {
setSupplierCount(res?.data);
//onSelectChange select变更事件
const onSelectChange = (value: string | number) => {
if (rankDataRef.current) {
const data = rankDataRef.current[value];
if (data.length > 0) {
const max = data[0].tenderCount;
for (let i = 0, length = data.length; i < length; i++) {
data[i]["maxTenderCount"] = max;
}
setActiveSupplierRankData(data)
}
}
})
}
useEffect(() => {
if (auth.current) {
getSupplierInfo();
getActiveSupplierRank();
getProvinceActiveSupplierInfo();
getSupplierCount();
}
}, [])
return (
<ScreenTitle title="供应商概况">
@ -252,10 +262,10 @@ const Supplier: React.FC<{}> = () => {
<div className="monitor-left-main">
<ScreenLabel title="全国活跃供应商排名" />
<div className="monitor-supplier-card">
<span className='monitor-supplier-select-label'></span>&nbsp;&nbsp;&nbsp;<SelectItem options={[{ label: "公开招标", value: "0" }, { label: "公开比选", value: "1" }, { label: "公开招募", value: "2" }, { label: "竞争性谈判", value: "3" }, { label: "单一来源", value: "4" }, { label: "公开询价", value: "5" }, { label: "邀请招标", value: "6" }]} onSelectChange={(value) => { console.log(value) }} />
<span className='monitor-supplier-select-label'></span>&nbsp;&nbsp;&nbsp;<SelectItem options={[{ label: "全部", value: "procurement_mode" }, { label: "公开招标", value: "公开招标" }, { label: "公开比选", value: "公开比选" }, { label: "公开招募", value: "公开招募" }, { label: "竞争性谈判", value: "竞争性谈判" }, { label: "单一来源", value: "单一来源" }, { label: "公开询价", value: "公开询价" }, { label: "邀请招标", value: "邀请招标" }]} onSelectChange={onSelectChange} />
</div>
<div className="monitor-tender-card">
<StatisticTable dataSource={dataSource} columns={columns} ynum={720} />
<StatisticTable dataSource={activeSupplierRankData} columns={columns} ynum={670} />
</div>
</div>
</Col>

File diff suppressed because one or more lines are too long

View File

@ -51,6 +51,35 @@ export async function getActiveSupplierAPI() {
});
}
/**
* 首页-参与供应商数
*/
export async function getSupplierCountAPI(params: any) {
return request('/api/biz-service-ebtp-statistics/v1/tenderMonitor/supplierCount', {
method: 'GET',
params: { ...params }
});
}
/**
* 首页-公告公示数量
*/
export async function getAnnoCountAPI(params: any) {
return request('/api/biz-service-ebtp-statistics/indexMonitor/annoCount', {
method: 'GET',
params: { ...params }
});
}
/**
* 首页-评审专家数量
*/
export async function getExpertNumberAPI(params: any) {
return request(`/api/biz-service-ebtp-statistics/api/evaluation/monitor/expertNumber/${params}`, {
method: 'GET',
});
}
/**
* 异常监控-超过1小时未开标数量
*/
@ -100,6 +129,24 @@ export async function getDecryptDataAPI() {
});
}
/**
* 异常监控-评审室关闭3日内未发布公示数
*/
export async function getThreeDaysUnSendAnnoCountAPI() {
return request('/api/biz-service-ebtp-statistics/exceptionMonitor/threeDaysUnSendAnnoCount', {
method: 'GET',
});
}
/**
* 异常监控-评审室关闭3日内未发布公示列表
*/
export async function getThreeDaysUnSendAnnoListAPI() {
return request('/api/biz-service-ebtp-statistics/exceptionMonitor/threeDaysUnSendAnnoList', {
method: 'GET',
});
}
/**
* 今日开标-评标阶段,评标及时率
*/
@ -146,11 +193,18 @@ export async function getProvinceActiveSupplierInfoAPI() {
}
/**
* 供应商概况-参与供应商
* 招标代理机构概况-相关统计数据
*/
export async function getSupplierCountAPI(params: any) {
return request('/api/biz-service-ebtp-statistics/v1/tenderMonitor/supplierCount', {
export async function getTenderAgentDataAPI() {
return request('/api/biz-service-ebtp-statistics/tenderAgent/getTenderAgentData', {
method: 'GET',
});
}
/**
* 招标代理机构概况-代理分布省分
*/
export async function getProvinceByAgencyAPI(agencyId: any) {
return request(`/api/biz-service-ebtp-statistics/tenderAgent/getProvinceByAgency/${agencyId}`, {
method: 'GET',
params: { ...params }
});
}

View File

@ -84,6 +84,25 @@
margin-top: 20px;
}
.monitor-top-exchange {
height: 16px;
line-height: 16px;
color: #FFFFFF;
text-align: right;
&>span {
font-size: 14px;
color: #FFFFFF;
line-height: 16px;
cursor: pointer;
&:hover {
color: #1b7ef2;
text-decoration: underline;
}
}
}
.monitor-top-space-flex {
margin-left: 0;
margin-top: 20px;
@ -387,7 +406,54 @@
.monitor-tender-map {
margin-top: 20px;
height: 690px;
height: 650px;
}
.monitor-tender-select {
margin-top: 10px;
.monitor-tender-select-radio {
margin-right: 8px;
}
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
background: #1b7ef2;
border-color: #1b7ef2;
&:hover {
background: #1b7ef2;
border-color: #1b7ef2;
}
}
.ant-radio-button-wrapper-checked:not([class*=' ant-radio-button-wrapper-disabled']).ant-radio-button-wrapper:first-child {
border-right-color: #1b7ef2;
}
.ant-radio-button-wrapper:hover {
color: #fff;
}
.ant-radio-button-wrapper {
color: #fff;
border: 1px solid #1b7ef2;
border-left-width: 0;
border-top-width: 1.02px;
background: none;
}
.ant-radio-button-wrapper:first-child {
border-left: 1px solid #1b7ef2;
}
.ant-radio-button-wrapper:not(:first-child)::before {
background-color: #1b7ef2;
}
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before,
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover::before {
background-color: #1b7ef2;
}
}
.monitor-supplier-rank {
@ -603,6 +669,14 @@
.ant-table-tbody>tr>td {
border-bottom: 0;
}
.ant-table-placeholder {
height: var(--monitor-table-height);
}
.ant-table-body {
height: var(--monitor-table-height);
}
}
.monitor-statistic-table {
@ -694,6 +768,14 @@
.ant-table-tbody>tr>td {
border-bottom: 0;
}
.ant-table-placeholder {
height: var(--monitor-table-height);
}
.ant-table-body {
height: var(--monitor-table-height);
}
}
.monitor-stage-card {