3.10 工程代码同步master

This commit is contained in:
jl-zhoujl2
2022-03-10 14:24:13 +08:00
parent 41ab55a4ac
commit 62f6b07ee2
914 changed files with 143121 additions and 29110 deletions

View File

@ -0,0 +1,237 @@
import { message } from "antd";
import { getSessionProjectData } from '@/utils/session';
//获取url参数
export function getQueryString(name: any) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substr(1).match(reg);
return r !== null ? unescape(r[2]) : null;
}
//判断undefined ''
export const checkUnEmp = (val: any) => {
if (val != undefined && val != "") {
return true
} else {
return false
}
};
//计算一个table的最高分
export const subCountScore = (subData: any) => {
return subData?.detailList?.reduce((preValue: any, item: any) => { return preValue + parseFloat(item.highScore) }, 0)
}
//单选取最大
export function chooseOne(data: any) {
let max = 0;
if (data != undefined && data.length > 0) {
data.map((item: any) => {
parseFloat(item.standardDetailScore) > max ? max = parseFloat(item.standardDetailScore) : null;
})
}
return max;
}
//多选加和
export function chooseMany(data: any) {
let max = 0;
if (data != undefined && data.length > 0) {
max = data.reduce((preVal: any, item: any) => {
if (item.standardDetailScore != '') {
return preVal + parseFloat(item.standardDetailScore)
} else {
return preVal
}
}, 0)
}
return max;
}
//修改最大值
export function changeHighScore(method: any, list: any) {
if (method == 0) {
return chooseOne(list)
}
if (method == 1) {
return chooseMany(list)
}
if (method == 2) {
return 0
}
return 0
}
//大于0反true
export function lessThan0(val: any) {
if (val != "--" && val != "++" && !(parseInt(val) < 0)) { return true } else { return false }
}
//校验空数据-详审
export function checkEmpty(data: any, type: any, name: any) {//校验类别里的空数据
let pass = true;
let reg = /(^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d{1,2})?$)/;
if (data != undefined && data.length > 0) {
let index = 1;
for (const item of data) {
if (item.scoreItem === '') {//评分项
message.error(`${type}-${name},第${index}行,评分项不能为空!`)
return false;
}
if (item.rvwStandard === '') {//评分标准
message.error(`${type}-${name},第${index}行,评分标准不能为空!`)
return false;
}
if (item.scoreMethod == 0 || item.scoreMethod == 1) {// 单选、多选的 详细评分标准
if (item.standardList) {
for (const item2 of item.standardList) {
if (!reg.test(item2.standardDetailScore) || item2.standardName == '') {
message.error(`${type}-${name},第${index}行,详细评分标准有未填项!`)
return false;
}
}
} else {
message.error(`${type}-${name},第${index}行,详细评分标准有未填项!`)
return false;
}
} else if (item.scoreMethod == 2) {// 人工录入的 最低分
if (item.lowScore === '') {// || !lessThan0(item.lowScore)
message.error(`${type}-${name},第${index}行,最低分不能为空!`)
return false;
}
if (parseFloat(item.highScore) < parseFloat(item.lowScore)) {//最高分不小于最低分
message.error(`${type}-${name},第${index}行,最高分不能小于最低分!`)
return false;
}
} else if (item.scoreMethod == 4) {// 步长法的 每步分值
if (item.stepScore == '') {
message.error(`${type}-${name},第${index}行,每步分值不能为空!`)
return false;
}
}
if (item.highScore === '') {//最高分 || !lessThan0(item.highScore)
message.error(`${type}-${name},第${index}行,最高分不能为空!`)
return false;
}
index++;
}
} else {
const method = getSessionProjectData().bidMethodDict;
if (method === '5' || method === '6') {
pass = true;
} else {
message.error(`${type}类不能为空!`);
return false;
}
}
return pass;
}
//校验空数据-初审
export function checkEmptyFirst(data: any, type: any, name: any) {//校验类别里的空数据
let pass = true;
if (data != undefined && data.length > 0) {
let index = 1;
for (const item of data) {
if (item.scoreItem == '') {
message.error(`${type}-${name},第${index}行,审查因素不能为空!`)
return false;
}
if (item.rvwStandard == '') {
message.error(`${type}-${name},第${index}行,审查标准不能为空!`)
return false;
}
index++;
}
} else {
message.error(`${type}不能为空!`)
return false;
}
return pass;
}
//校验报价
export function checkBj(dataT: any, tanpan?: boolean) {//tanpan 是否评审流程里的报价节点
let pass = true;
let data;
if (dataT[0] == undefined) {
pass = false;
message.error(`报价类不能为空!`)
}
if (tanpan && pass) {
data = dataT[0]
} else {
data = dataT[0]?.detailList[0];
}
if (data != undefined && pass) {
if (data.scoreMethod == 3) {//自动计算
if (data.highScore === '') {//最高分 || !lessThan0(data.highScore)
pass = false;
message.error(`报价类,最高分不能为空!`)
}
if (data.effectiveType == 6) {//有效报价
if (data.includeHighPrice === '' || data.includeHighPrice === undefined) {//|| !lessThan0(data.includeHighPrice)
pass = false;
message.error(`报价类,有效报价最高价不能为空,不能小于0`)
}
if (data.includeLowPrice === '' || data.includeLowPrice === undefined) {//|| !lessThan0(data.includeLowPrice)
pass = false;
message.error(`报价类,有效报价最低价不能为空,不能小于0`)
}
}
if (data.baseType == 3) {//评标基准价 平均报价系数
if (data.avgPriceMultiplier === '') {//|| !lessThan0(data.avgPriceMultiplier)
pass = false;
message.error(`报价类,平均报价系数不能为空,不能小于0`)
}
}
if (data.priceType == 1) {//报价分
if (data.priceMultiplier === '' || data.priceMultiplierSecond === '') {//|| !lessThan0(data.priceMultiplier) || !lessThan0(data.priceMultiplierSecond)
pass = false;
message.error(`报价类,报价分,评标基准价系数不能为空,不能小于0`)
}
if (
data.lowScore === '' ||
// !lessThan0(data.lowScore) ||
data.lowScoreSecond === '' ||
// !lessThan0(data.lowScoreSecond) ||
parseFloat(data.lowScore) > parseFloat(data.highScore) ||
parseFloat(data.lowScoreSecond) > parseFloat(data.highScore)
) {
pass = false;
message.error(`报价类,报价分,最低分不能为空,不能小于0,不能大于最高分!`)
}
}
if (data.priceType == 2) {//报价分
if (
data.lowScore === '' ||
// !lessThan0(data.lowScore) ||
data.lowScoreSecond === '' ||
// !lessThan0(data.lowScoreSecond) ||
parseFloat(data.lowScore) > parseFloat(data.highScore) ||
parseFloat(data.lowScoreSecond) > parseFloat(data.highScore)
) {
pass = false;
message.error(`报价类,报价分,最低分不能为空,不能小于0,不能大于最高分!`)
}
}
if (data.priceType == 3 || data.priceType == 4 || data.priceType == 5) {//报价分
if (data.priceMultiplier === '') {//|| !lessThan0(data.priceMultiplier)
pass = false;
message.error(`报价类,报价分,评标基准价系数不能为空,不能小于0`)
}
}
} else if (data.scoreMethod == 2) {//手动计算
pass = true;
} else {
pass = false;
message.error(`请选择计算方式!`)
}
}
return pass;
}
//去重
export function unique1(arr: any) {
var hash = [];
for (var i = 0; i < arr.length; i++) {
if (hash.indexOf(arr[i]) == -1) {
hash.push(arr[i]);
}
}
return hash;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,13 +33,7 @@
.blue{
color: rgb(0, 64, 201);
}
:global {
.ant-radio{
vertical-align: top !important;
margin-top: 4px !important;
}
.ant-checkbox{
vertical-align: top !important;
margin-top: 4px !important;
}
}
// .ant-btn-dashed{
// margin:0 !important;
// }

View File

@ -0,0 +1,277 @@
import { getProMethod } from "@/utils/session";
import ProTable, { ActionType, ProColumns } from "@ant-design/pro-table";
import { Button, Modal, Spin, Tree } from "antd";
import React, { useEffect, useRef, useState } from "react";
import { unique1 } from "./commonFunc";
import { getAllFile, getGlfile, getTree, saveF } from "./service";
type FileTreeType = {
record?: any,//关联文件当前行数据\
childs: any,
roots: any,
treeData: any,
type: string,//check 查看关联应答文件; option--关联文件
id?: string,//detId 详审id firstId 初审id
rePage: () => {},//执行父组件刷新页面的方法
parentSpin: (value: any) => {},//控制父组件 spin
}
const FileTree: React.FC<FileTreeType> = (props) => {
//==============================================================state
const {
record,
type,
id,
childs,
roots,
treeData,
rePage,
parentSpin
} = props;
const checkRelationRef = useRef<ActionType>();
//根据评审室id和轮次数查应答文件格式
const [spin, setSpin] = useState<boolean>(false);//蒙层
const [glfile, setGlfile] = useState<boolean>(false);//关联应答文件
const [checkRelation, setCheckRelation] = useState<boolean>(false); //查看关联应答文件
// const [childs, childsSet] = useState<any>([]);//子节点
// const [roots, rootsSet] = useState<any>([]);//根节点
const [pIds, pIdsSet] = useState<any>([]);//根节点(保存时用)
const [checkedKeys, setCheckedKeys] = useState<any>([]);//树被选中节点
// const [treeData, setTreeData] = useState<any>([]);//应答文件树
const [choosedId, setChoosedId] = useState<any>();//关联应答文件的对应的一条数据的id
const [hide, hideSet] = useState(false);
const treeOneClass = {};// 子节点id:父节点id
treeData?.map((item: any) => {
item?.children?.map((item2: any) => {
treeOneClass[item2.key] = item2.pId
})
})
//页面文字显示
const method = getProMethod();
let showNameT: any = { tb: '应答' }//应答
if (method === 'procurement_mode_1' || method === 'procurement_mode_2') {//招标
showNameT = { tb: '投标' }
}
//查看关联应答文件表格
const columnsCheckRelation: ProColumns<any>[] = [
{ title: '序号', valueType: 'index', width: 50 },
{ title: '类别名称', dataIndex: 'name', width: 150, },
{ title: '评分项', dataIndex: 'scoreItem', width: 300, },
{ title: '关联资料', dataIndex: 'documentNames', },
];
//==============================================================func
//获取关联的文件用来选中
const getGlFile = async (detailId: any) => {
let data: any = [];
let pIdsT: any = [];
await getGlfile({ detailId: detailId }).then((res) => {
if (res.data != undefined) {
res.data.map((it: any) => {
//如果是子节点的 追加
let index = childs.findIndex((item: any) => item === it.documentId);
index != -1 ? data.push(it.documentId) : null;
if (index != -1) {
data.push(it.documentId);
pIdsT.push(treeOneClass[it.documentId]);
}
});
}
pIdsSet(pIdsT);
setCheckedKeys(data);
});
setGlfile(true);
setSpin(false);
parentSpin(false);
}
//树
const onCheck = (checkedKeys: any, e: any) => {
let pIdsT = [...pIds];//根节点
let index = pIdsT.findIndex(item => item === e.node.pId);
if (e.checked) {//选中
//pids加根节点 有就不加
if (e.node.pId != null) {//!=null为子节点
pIdsT.push(e.node.pId);
} else {
pIdsT.push(e.node.key);//添加根节点
}
} else {//取消选中
//pids删根节点
if (e.node.pId != null) {//!=null为子节点
if (index != -1) {//-1 没有
pIdsT.splice(index, 1);
}
} else {
//清空暂存的 选中的根节点 数组
pIdsT = pIdsT.filter(item => item != e.node.key)
}
}
pIdsSet(pIdsT);
setCheckedKeys(checkedKeys);
};
//关联文件 表格内操作
function relevanceFile() {
return (
<>
<Button type='text' hidden={hide} onClick={async () => {
setSpin(true);
parentSpin(true);
// await getTreeData(assessRoomId, turnSort);
await getGlFile(record.id);
setChoosedId(record.id);
}}></Button>
<Modal
visible={glfile}
title={`关联${showNameT.tb}文件`}
width={"20%"}
centered
okButtonProps={{
loading: spin
}}
onCancel={() => setGlfile(false)}
onOk={async () => {
setSpin(true);
parentSpin(true);
hideSet(true);
if (treeData.length > 0) {
let checkedKeysT = unique1([...checkedKeys, ...pIds]);
const success = await saveF({ detailId: choosedId, documentIdList: checkedKeysT });
if (success) {
rePage();
}
}
setSpin(false);
parentSpin(false);
setGlfile(false);
setCheckedKeys([]);
}}
>
<Spin spinning={spin}>
{
treeData.length != 0 ?
<Tree
checkable
autoExpandParent={true}
onCheck={onCheck}
checkedKeys={checkedKeys}
treeData={treeData}
selectable={false}
height={300}
defaultExpandAll={true}
/>
: '没有应答格式'
}
</Spin>
</Modal>
</>
)
}
//查看关联应答文件
function checkRelevanceFile() {
return (
<>
<Button style={{ marginRight: '10px' }} key="3" onClick={async () => {
// await getTreeData(assessRoomId, turnSort);
checkRelationRef.current?.reload();
setCheckRelation(true);
}}>{showNameT.tb}</Button>
<Modal
visible={checkRelation} width={'80%'} centered title={`查看关联${showNameT.tb}文件`} onCancel={() => setCheckRelation(false)}
footer={renderFooter()}
>
<ProTable
actionRef={checkRelationRef}
columns={columnsCheckRelation}//表格
options={false}
search={false}
tableAlertRender={false}
request={(params) => getAllFile({ pageNo: params.current, pageSize: params.pageSize, configId: id }).then((res) => {
let dataT: any = [...res.data.records];
let documentIds: any = [];
let documentNames: any = [];
dataT.map((item: any) => {
if (item.documentIds != null) {
documentIds = [...item.documentIds.split(',')];
documentNames = [...item.documentNames.split(',')];
for (var i = 0; i < roots.length; i++) {
for (var j = 0; j < documentIds.length; j++) {
if (documentIds[j] == roots[i]) {
documentIds.splice(j, 1);
documentNames.splice(j, 1);
j = j - 1;
}
}
}
item.documentIds = documentIds.join(',');
item.documentNames = documentNames.join(',');
}
});
const result = {
data: dataT,
total: res.data.total,
success: res.success,
pageSize: res.pageSize,
current: res.current
};
return result;
})}
pagination={{ defaultPageSize: 10, showSizeChanger: false, }}//默认显示条数
/>
</Modal>
</>
)
}
//查看关联页脚
function renderFooter() {
return (
<Button type='primary' onClick={() => setCheckRelation(false)}></Button>
)
}
//==============================================================dom
return (
<>
{type === 'option' && relevanceFile()}
{type === 'check' && checkRelevanceFile()}
</>
)
}
//获取关联文件树
export const getTreeDataOut = async (assessRoomId: any, turnSort: any) => {
let data: any = [];
let rootT: any = [];
let childT: any = [];
await getTree({ assessRoomId: assessRoomId, turnSort: turnSort }).then((res) => {
if (res.data != undefined) {
res.data.map((item: any, index: any) => {
const title1 = item.name;
const key1 = item.id;
let children1: any = [];
if (item.children != undefined) {
const children = item.children.map((item: any, index: any) => {
const title2 = item.name;
const key2 = item.id;
let children2: any = [];
if (item.children != undefined) {
const children = item.children.map((item: any, index: any) => {
const title3 = item.name;
const key3 = item.id;
childT.push(key3)
return { title: title3, key: key3, pId: key2 }
});
children2 = children;
}
childT.push(key2)
return { title: title2, key: key2, children: children2, pId: key1 }
});
children1 = children;
}
const first = { title: title1, key: key1, children: children1, pId: null }
rootT.push(key1)
data.push(first);
});
}
})
return { roots: rootT, childs: childT, treeData: data }
}
export default FileTree;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,810 @@
import React, { useEffect, useMemo, useRef, useState, } from 'react';
import { Button, Radio, Input, Modal, Form, Row, Col, Select, Collapse, message, Spin, Popconfirm } from 'antd';
import ProTable, { ProColumns } from '@ant-design/pro-table';
import { PlusOutlined, EditOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { getPage, saveData, delDet, delCate, firstTem } from './service'
import { getURLInformation } from '@/utils/CommonUtils'
import '@/assets/xsy_style.less'
import { btnAuthority } from '@/utils/authority';
import { checkEmptyFirst, checkUnEmp } from './commonFunc';
import FileTree, { getTreeDataOut } from './fileTree';
import TempleteBtns from './templeteBtns';
import Preview from './preview';
import { getParentConfig } from '@/pages/ZBiXuan/EvaluationRoom/Config/FirstLimited/service';
type FirstType = {
show: string,
}
const FirstMain: React.FC<FirstType> = (props) => {
//===========================================================================================================state
const formLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
const { show } = props
const FormItem = Form.Item;
const [form] = Form.useForm();
const [formModal] = Form.useForm();
const { Option } = Select;
const { Panel } = Collapse;
const { TextArea } = Input;
const { confirm } = Modal;
const [assessRoomId, setAssessRoomId] = useState<any>();//评标室id
const [turnSort, setTurnSort] = useState<any>();//轮次号
const [spin, setSpin] = useState<boolean>(true);//加载
const [dis, setDis] = useState<boolean>(true);//是否可以更改
//形式评审---包含商务子类
const [data1, setData1] = useState<any>([]);
//资格审查项
const [data2, setData2] = useState<any>([]);
//响应性评审
const [data3, setData3] = useState<any>([]);
//符合性审查
const [data4, setData4] = useState<any>([]);
const [category, setCategory] = useState<boolean>(false);//新增、修改类别窗口
const [isUpdateCate, isUpdateCateSet] = useState<boolean>(false);//是否修改类别
const [upData, updataSet] = useState<any>([]);//正在修改的数据
const [principleStatus, setPrincipleStatus] = useState<number>();//评判原则
const [deviatedStatus, setDeviatedStatus] = useState<any>();//偏离
const [commonId, setCommonId] = useState<any>();//初审详审公共id
const [firstId, setFirstId] = useState<any>();//初审整体data id
const [nodeId, setNodeId] = useState<any>();//包id
const [oid, oidSet] = useState<any>('')//下载excel oid
const mainDiv = useRef<HTMLDivElement>(null);
const [childs, childsSet] = useState<any>([]);//子节点
const [roots, rootsSet] = useState<any>([]);//根节点
const [treeData, setTreeData] = useState<any>([]);//应答文件树
//鼠标移入行大类别名称
const [onRowCateName, onRowCateNameSet] = useState<any>('');
//公共表格
const commonColumns: ProColumns<any>[] = [
{ title: '序号', valueType: 'index', width: 50 },
{
title: '审查因素', dataIndex: 'scoreItem', width: 300,
render: (_, record) => {
const idT = record.id != undefined ? record.id : record.tableId
return (
<Form form={form}>
<FormItem style={{ margin: 0 }} name={`scoreItem${idT}${record.key}`} rules={[{ type: 'string', message: '请输入正确内容' }, { max: 255, message: '超过内容最大长度255' }]}>
<TextArea autoSize readOnly={dis} defaultValue={record.scoreItem}
onBlur={(event) => {
record.scoreItem = event.target.value;
reTable()
}} placeholder="请输入审查因素" />
</FormItem>
</Form>
)
}
},
{
title: '审查标准', dataIndex: 'rvwStandard',
render: (_, record) => {
const idT = record.id != undefined ? record.id : record.tableId
return (
<Form form={form}>
<FormItem style={{ margin: 0 }} name={`rvwStandard${idT}${record.key}`} rules={[{ type: 'string', message: '请输入正确内容' }, { max: 2000, message: '超过内容最大长度2000' }]}>
<TextArea autoSize readOnly={dis} defaultValue={record.rvwStandard}
onBlur={(event) => {
record.rvwStandard = event.target.value;
reTable();
}} placeholder="请输入审查标准" />
</FormItem>
</Form>
)
}
},
{
title: '初审项性质', dataIndex: 'deviationStatus', width: 200,
render: (_, record) => {
return (
<Radio.Group disabled={dis} onChange={(event) => {
event.target.value === 1 && deviatedStatus === 0 && setDeviatedStatus(1)
record.deviationStatus = event.target.value;
reTable();
}} value={deviatedStatus === 1 ? record.deviationStatus : 0}>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
)
}
},
{
title: '操作', dataIndex: 'option', width: 150,
valueType: 'option',
render: (_, record, index) => {
if (!dis) {
return ([
<>
{
checkUnEmp(record.id) &&
<>
<FileTree
record={record}
type='option'
roots={roots}
childs={childs}
treeData={treeData}
rePage={() => queryFirstData()}
parentSpin={async (value) => setSpin(value)}
/>
<br />
</>
}
{index != 0 && conmmonDelConfirm(record)}
</>
]);
} else {
return <></>
}
}
},
];
//公共子类表格-删除气泡提示框
function conmmonDelConfirm(record: any) {
let id = record.id;
const idT = record.id != undefined ? record.id : record.tableId;
const confirm = async () => {
setSpin(true);
let success = false;
form.setFieldsValue({
[`scoreItem${idT}${record.key}`]: '',
[`rvwStandard${idT}${record.key}`]: '',
});
checkUnEmp(id) ? success = await delDet({ id }) : null;
if (success) {
queryFirstData();
}
if (!checkUnEmp(id)) {
let dataT: any = []
record.categoryName == '形式评审' && (dataT = [...data1])
record.categoryName == '资格审查项' && (dataT = [...data2])
record.categoryName == '响应性评审' && (dataT = [...data3])
record.categoryName == '符合性审查' && (dataT = [...data4])
dataT?.map((item: any, index: any) => {
if (item.id == record.tableId || item.tableId == record.tableId) {
dataT[index].detailList = item.detailList.filter((item2: any) => item2.key != record.key)
}
})
record.categoryName == '形式评审' && setData1(dataT)
record.categoryName == '资格审查项' && setData2(dataT)
record.categoryName == '响应性评审' && setData3(dataT)
record.categoryName == '符合性审查' && setData4(dataT)
message.success('删除成功');
}
setSpin(false);
}
return (
<Popconfirm
title={checkUnEmp(id) ? '确认删除已保存数据么?' : '确认删除未保存数据么?'}
onConfirm={confirm}
okText="确认"
cancelText="取消"
>
<Button type='text'></Button>
</Popconfirm>
)
}
//============================================================================================================组件
const rePreview = useMemo(() => {//预览页面
return <Preview data={{ data1, data2, data3, data4 }} rvwType={1} />
}, [data1, data2, data3, data4])
const btnAttr = {
hidden: btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase']),
style: { marginRight: '10px' },
disabled: dis,
}
const returnTem = useMemo(() => {//模板
let tem = null;
if (nodeId && oid) {
tem = <TempleteBtns
rvwType={1}
commonId={commonId}
nodeId={nodeId}
assessRoomId={assessRoomId}
dis={dis}
oid={oid}
purchaseMethod={1}
reviewId={firstId}
rePage={() => queryFirstData()}
parentSpin={async (value) => setSpin(value)}
processData={(data) => processingData(data)}
/>
}
return tem
}, [assessRoomId, commonId, nodeId, firstId, dis, oid]);
function detailButtons() {//业务按钮组
return (
<>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
style={{ marginRight: '10px' }}
disabled={dis}
key="saveBtn"
type="primary"
onClick={() => saveFunc()}
></Button>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
style={{ marginRight: '10px' }}
disabled={dis}
key="addCategoryBtn"
type="primary"
onClick={() => {
setCategory(true);//控制新增类别窗口
isUpdateCateSet(false);
formModal.setFieldsValue({ name: '', type: '请选择', weights: '' });
}}
></Button>
{
getURLInformation("readStatus") != null &&
<Button
{...btnAttr}
type="primary"
key="parent"
onClick={showConfirm}
>
</Button>
}
<FileTree
type='check'
id={firstId}
roots={roots}
childs={childs}
treeData={treeData}
rePage={() => queryFirstData()}
parentSpin={async (value) => setSpin(value)}
/>
{rePreview}
{returnTem}
{
getURLInformation("readStatus") != null ?
<Button style={{ marginLeft: '10px' }} onClick={() => { history.back() }}></Button>
: null
}
</>
)
}
//新增类别Modal
function addCategoryModal() {
return (
<Modal
centered
title={isUpdateCate ? '修改类别' : '新增类别'}
visible={category}
width={500}
onCancel={() => { setCategory(false); formModal.resetFields() }}
onOk={() => {
formModal.validateFields().then(() => {
if (formModal.getFieldsValue().type === '请选择') {
message.error('请选择类别');
} else {
setCategory(false);
setSpin(true);
setTimeout(() => {
typeControl(formModal.getFieldsValue());
formModal.resetFields();
//mainDiv.current.scrollTop = mainDiv.current.scrollHeight;
}, 100);
}
})
}}
>
<Form {...formLayout} form={formModal}>
<Row>
<Col span={24}><FormItem
key="addName"
name="name"
label="类别名称"
rules={[{ required: true, message: '请输入名称' }]}
>
<Input readOnly={dis} style={{ width: "80%" }} />
</FormItem></Col>
</Row>
<Row>
<Col span={24}><FormItem
name="type"
label="类型"
initialValue="请选择"
rules={[{ required: true, message: '请选择类别' }]}
>
<Select style={{ width: "80%" }}>
<Option value="形式评审" key="addCateKey1"></Option>
<Option value="资格审查项" key="addCateKey2"></Option>
<Option value="响应性评审" key="addCateKey3"></Option>
<Option value="符合性审查" key="addCateKey4"></Option>
</Select>
</FormItem></Col>
</Row>
</Form>
</Modal>
)
}
//返回单选按钮组
const returnRadios = () => {
return (
<Form style={{ marginLeft: '24px', }} form={form}>
<Row>
<Col span={8}>
<FormItem label="初审项评判原则">
<Radio.Group disabled={dis} name="radiogroup" onChange={(e) => setPrincipleStatus(e.target.value)} value={principleStatus}>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
</FormItem>
</Col>
<Col span={8}>
<FormItem label="是否可偏离">
<Radio.Group disabled={dis} onChange={(e) => {
setDeviatedStatus(e.target.value);
}} value={deviatedStatus}>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
</FormItem>
</Col>
<Col span={8}>
<FormItem
hidden={deviatedStatus != 1}
label="偏离数量"
name='deviationNumber1'
rules={[
{ required: deviatedStatus == 1, message: '请填写偏离数量' },
{ pattern: /^([1-9][0-9]{0,1}|100)$/, message: '请填写100以内正整数' },
]}>
<Input readOnly={dis} style={{ width: "30%", position: 'relative', }} />
</FormItem>
</Col>
</Row>
</Form>
)
};
//返回折叠面板
const returnPanel = () => {
return (
<Collapse defaultActiveKey={['Panel1', 'Panel2', 'Panel3', 'Panel4']}>
{
data1.length != 0 &&
<Panel header='形式评审' key='Panel1'>
{data1?.map((item: any, mapindex: any) => { return returnTable(item, mapindex) })}
</Panel>
}
{
data2.length != 0 &&
<Panel header='资格审查项' key='Panel2'>
{data2?.map((item: any, mapindex: any) => { return returnTable(item, mapindex) })}
</Panel>
}
{
data3.length != 0 &&
<Panel header='响应性评审' key='Panel3'>
{data3?.map((item: any, mapindex: any) => { return returnTable(item, mapindex) })}
</Panel>
}
{
data4.length != 0 &&
<Panel header='符合性审查' key='Panel4'>
{data4?.map((item: any, mapindex: any) => { return returnTable(item, mapindex, true) })}
</Panel>
}
</Collapse>
)
};
//返回子类表格
function returnTable(subData: any, mapindex: number, isBaojia?: boolean) {
//删除子表格
const confirm = async () => {
const categoryName = subData.categoryName;
setSpin(true);
if (subData.id != undefined) {
//走接口删除
let success = await delCate(subData.id);
if (success) {
await queryFirstData();
}
} else {
categoryName == '形式评审' && setData1(data1.filter((item: any) => item.key != subData.key));
categoryName == '资格审查项' && setData2(data2.filter((item: any) => item.key != subData.key));
categoryName == '响应性评审' && setData3(data3.filter((item: any) => item.key != subData.key));
categoryName == '符合性审查' && setData4(data4.filter((item: any) => item.key != subData.key));
message.success('删除成功');
}
setSpin(false);
}
return (
<div className='xsy-config-table' id={`${subData.name}${subData.key}`}>
<div style={{ height: '42px', lineHeight: '42px' }}>
<h3 className='scd-title' style={{ float: 'left' }}>{subData.name}</h3>
{
!dis &&
<div style={{ float: 'right' }}>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
type='dashed'
style={{ marginRight: '10px' }}
// className='xsyBtn'
onClick={() => {
setCategory(true);//控制新增、修改类别窗口
isUpdateCateSet(true);
updataSet(subData);
onRowCateNameSet(subData.categoryName);
formModal.setFieldsValue({ name: subData.name, type: subData.categoryName, weights: subData.weights });
}}
>
<EditOutlined />{`修改`}
</Button>
<Popconfirm
title="确认删除么?"
onConfirm={confirm}
okText="确认"
cancelText="取消"
>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
type='dashed'
>
<DeleteOutlined />{`删除`}
</Button>
</Popconfirm>
</div>
}
</div>
<ProTable
columns={commonColumns}
size="small"
dataSource={subData.detailList}
options={false}
search={false}
tableAlertRender={false}
pagination={false}//分页
onRow={record => {
return {
onMouseEnter: event => { onRowCateNameSet(subData.categoryName) }, // 鼠标移入行
};
}}
/>
{
!dis && subData.categoryName !== '报价' &&
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
type='dashed'
// className='xsyBtn'
style={{ width: '100%' }}
key={subData.categoryName + mapindex + 'Btn1'}
onClick={() => addOneRow(subData.categoryName, mapindex, subData.tableId, subData.id)}
>
<PlusOutlined />
</Button>
}
</div>
)
}
//继承上轮确认提示框
function showConfirm() {
confirm({
title: '即将继承上一轮初审配置(如上一轮无数据,则无法继承),是否继承?',
icon: <ExclamationCircleOutlined />,
centered: true,
okText: '继承',
onOk() {
setSpin(true);
getParentConfig({ nodeId, rvwType: 1 }).then((res) => {
res?.code == 200 ? queryFirstData() : setSpin(false);
}).catch(() => setSpin(false))
},
});
}
//===========================================================================================================FUNC
useEffect(() => {
if (show !== '2') {
queryFirstData();
firstTem().then(res => {
res?.code == 200 ? oidSet(res.data.documentCenterId) : null;
});
}
}, [show]);
//新增、修改类别
const typeControl = async (values: any) => {
const { name, type, weights } = values;
let tableId = Date.now();
let subCate = {
categoryName: type,//大类别名称
name: name,//字类名
tableId: tableId,
key: 0,
detailList: [{//初始值---新增用
key: 0,
tableId: tableId,
scoreItem: "",//评分项
categoryName: type,//大类别名称
rvwStandard: "",//评分标准
deviationStatus: 0,//是否可偏离
}]
}
let [data1T, data2T, data3T, data4T] = [[...data1], [...data2], [...data3], [...data4]];
const add = (type: any) => {
//新增
if (type == '形式评审') {
subCate['key'] = data1.length;
subCate['category'] = '0';
setData1([...data1T, subCate])
} else if (type == '资格审查项') {
subCate['key'] = data2.length;
subCate['category'] = '1';
setData2([...data2T, subCate])
} else if (type == '响应性评审') {
subCate['key'] = data3.length;
subCate['category'] = '2';
setData3([...data3T, subCate])
} else if (type == '符合性审查') {
subCate['key'] = data4.length;
subCate['category'] = '7';
setData4([...data4T, subCate])
}
}
if (isUpdateCate) {//修改
const oldCategoryName = upData.categoryName;
subCate = upData.key;
upData.name = name;
upData.categoryName = type;
upData.weights = weights == undefined ? 100 : weights;
//修改
if (oldCategoryName == '形式评审') {
if (oldCategoryName != type) {
data1T = data1T.filter((item: any) => item.key != undefined ? item.key != upData.key : item.id != upData.id);
} else {
let index = data1T.findIndex((item: any) => item.key != undefined ? item.key == upData.key : item.id == upData.id)
data1T[index] = upData;
}
setData1(data1T)
}
if (oldCategoryName == '资格审查项') {
if (oldCategoryName != type) {
data2T = data2T.filter((item: any) => item.key != undefined ? item.key != upData.key : item.id != upData.id);
} else {
let index = data2T.findIndex((item: any) => item.key != undefined ? item.key == upData.key : item.id == upData.id)
data2T[index] = upData;
}
setData2(data2T)
}
if (oldCategoryName == '响应性评审') {
if (oldCategoryName != type) {
data3T = data3T.filter((item: any) => item.key != undefined ? item.key != upData.key : item.id != upData.id);
} else {
let index = data3T.findIndex((item: any) => item.key != undefined ? item.key == upData.key : item.id == upData.id)
data3T[index] = upData;
}
setData3(data3T)
}
if (oldCategoryName == '符合性审查') {
if (oldCategoryName != type) {
data4T = data4T.filter((item: any) => item.key != undefined ? item.key != upData.key : item.id != upData.id);
} else {
let index = data4T.findIndex((item: any) => item.key != undefined ? item.key == upData.key : item.id == upData.id)
data4T[index] = upData;
}
setData4(data4T)
}
subCate = upData;
oldCategoryName != type && add(type);
} else {
add(type);
}
scrollToAnchor(subCate.name + subCate.key)
setSpin(false);
}
//表格新增一行
function addOneRow(categoryName: string, key: number, tableId: any, id: any) {
const oneRow = {//初始值---新增用
tableId: tableId ? tableId : id,
scoreItem: "",//评分项
rvwStandard: "",//评分标准
categoryName: categoryName,
deviationStatus: 0,//是否可偏离
};
const setData = (data: any) => {
let dataFirst: any[] = [];
data.map((item: any, index: any) => {//大类 含子表格数据[]
let dataSecond: any[] = [];
item.detailList.map((item2: any) => {
dataSecond.push(item2)
})
if (index == key) {
oneRow['key'] = dataSecond[dataSecond.length - 1] ? dataSecond[dataSecond.length - 1].key + 1 : 0;
dataSecond.push(oneRow)
}
item.detailList = dataSecond;
dataFirst.push(item);
})
return dataFirst;
}
if (categoryName == '形式评审') {
setData1(setData(data1))
} else if (categoryName == '资格审查项') {
setData2(setData(data2))
} else if (categoryName == '响应性评审') {
setData3(setData(data3))
} else if (categoryName == '符合性审查') {
setData4(setData(data4))
}
}
//根据name subname 定位表格、数据并重新赋值
function reTable() {
if (onRowCateName === '形式评审') {
setData1([...data1]);
} else if (onRowCateName === '资格审查项') {
setData2([...data2]);
} else if (onRowCateName === '响应性评审') {
setData3([...data3]);
} else if (onRowCateName === '符合性审查') {
setData4([...data4]);
}
}
//保存页面
async function saveFunc() {
setSpin(true);
const id = firstId;
const rvwType = "1";
let categoryList: any[] = [];
let pass = true;
let [data1t, data2t, data3t, data4t] = [[...data1], [...data2], [...data3], [...data4]]
if (data1t.length == 0 && data2t.length == 0 && data3t.length == 0 && data4t.length == 0) {
pass = false;
message.error('请新增类别');
}
pass && await form.validateFields().catch((errorInfo) => {
pass = false;
message.error(errorInfo.errorFields[0].errors);
})
if (data1t.length > 0 && pass) {
data1t.map((item: any) => {
!checkEmptyFirst(item.detailList, '形式评审', item.name) && (pass = false);
pass && deviatedStatus === 0 && (item.detailList.map((item2: any) => item2.deviationStatus = 0))
})
}
if (data2t.length > 0 && pass) {
data2t.map((item: any) => {
!checkEmptyFirst(item.detailList, '资格审查项', item.name) && (pass = false);
pass && deviatedStatus === 0 && (item.detailList.map((item2: any) => item2.deviationStatus = 0))
})
}
if (data3t.length > 0 && pass) {
data3t.map((item: any) => {
!checkEmptyFirst(item.detailList, '响应性评审', item.name) && (pass = false);
pass && deviatedStatus === 0 && (item.detailList.map((item2: any) => item2.deviationStatus = 0))
})
}
if (data4t.length > 0 && pass) {
data4t.map((item: any) => {
!checkEmptyFirst(item.detailList, '符合性审查', item.name) && (pass = false);
pass && deviatedStatus === 0 && (item.detailList.map((item2: any) => item2.deviationStatus = 0))
})
};
if (pass) {//合数据
categoryList = [...data1t, ...data2t, ...data3t, ...data4t,]
let allData = {
id,
commonId,
principleStatus,
deviatedStatus,
rvwType,
categoryList,
nodeId,
deviationNumber: form.getFieldValue('deviationNumber1'),
}
const success = await saveData(allData);
if (success) {
message.success('保存成功');
queryFirstData();
}
} else {
setSpin(false);
}
}
//获取初审数据
const queryFirstData = async () => {
let commonId: any = "";
if (getURLInformation("id") != null) {
commonId = getURLInformation("id")
}
let nodeId: any = '';
if (getURLInformation("nodeId") != null) {
nodeId = getURLInformation("nodeId")
}
setCommonId(commonId);
setNodeId(nodeId);
const rvwType = 1;
setSpin(true);
await getPage({ commonId, rvwType, nodeId }).then((res) => {
if (res.code == 200) {
processingData(res);
}
})
}
//处理数据
async function processingData(res: any) {
setData1([]);
setData2([]);
setData3([]);
setData4([]);
// let data1T: any = [];
setSpin(true);
let [data1T, data2T, data3T, data4T]: any = [[], [], [], []];
let dis: any = true;
let deviatedStatus: any, principleStatus: any, deviationNumber: any = "";
let firstId = "";
let assessRoomId: any, turnSort: any = 0;
const data = res.data;
deviatedStatus = data.deviatedStatus != null ? data.deviatedStatus : 0;
principleStatus = data.principleStatus != null ? data.principleStatus : 0;
deviationNumber = data.deviationNumber;
assessRoomId = data.assessRoomId;
turnSort = data.reviewTurnSort;
data.categoryList.map((item: any) => {
const cate = item.category
cate === '0' && data1T.push(item);
cate === '1' && data2T.push(item);
cate === '2' && data3T.push(item);
cate === '7' && data4T.push(item);
});
if (data.status == 0 || data.status == null) {
dis = false;
}
if (data.id != null) {
firstId = data.id;
}
let tree = await getTreeDataOut(assessRoomId, turnSort);
rootsSet(tree.roots);
childsSet(tree.childs);
setTreeData(tree.treeData);
setFirstId(firstId);
setAssessRoomId(assessRoomId);
setTurnSort(turnSort);
setData1(data1T); setData2(data2T); setData3(data3T); setData4(data4T);
setDeviatedStatus(deviatedStatus);
setPrincipleStatus(principleStatus);
form.setFieldsValue({
deviationNumber1: deviationNumber,
})
setDis(dis);
setSpin(false);
}
//缓慢滚动
const scrollToAnchor = (anchorName: any) => {
if (anchorName) {
let anchorElement = document.getElementById(anchorName);
if (anchorElement) {
anchorElement.scrollIntoView(
{ behavior: 'smooth' }
);
}
}
}
return (
<div className='bgCWhite'>
<Spin spinning={spin}>
<div style={{ marginTop: '16px', padding: '0px 24px', height: '32px', lineHeight: '32px' }}>
<h3 className='first-title' style={{ float: 'left' }}></h3>
<div style={{ float: 'right' }}>
{detailButtons()}{/* 业务按钮组 */}
</div>
</div>
<div style={{ clear: 'both' }} />
{returnRadios()}{/* 单选按钮组 */}
<div className='xsy-scroll-hidden' style={{ height: innerHeight - 400, overflow: 'auto', borderTop: '1px', borderTopStyle: 'solid', borderColor: 'rgb(217,217,217)' }} ref={mainDiv}>
{returnPanel()}{/* 折叠面板 */}
</div>
</Spin>
{/* 新增类别Modal */}
{addCategoryModal()}
</div>
)
}
export default FirstMain;

View File

@ -8,16 +8,13 @@
border-width: 1px;
}
}
// :global {
// .pageHeaderStyle {
// .ant-page-header {
// position: relative;
// font-size: 0px;
// padding: 0px;
// border-bottom: solid;
// border-bottom-color: rgb(208,1,0);
// border-width: 1px;
// }
// }
// }
.xsyBtn {
color:#1890ff;
margin-right: 8px;
:hover{
color:#1890ff;
}
}
// .firstTabs{
// padding: 0px 24px 0px 24px;
// }

View File

@ -0,0 +1,211 @@
import { getProMethod } from "@/utils/session";
import ProTable, { ProColumns } from "@ant-design/pro-table";
import { Button, Checkbox, Col, InputNumber, Modal, Radio, Tabs, } from "antd";
import React, { useState } from "react";
import styles from './detailedStyles.less';
type PreviewType = {
data: any,
rvwType: number,//初审1详审2
}
const Preview: React.FC<PreviewType> = (props) => {
const { TabPane } = Tabs;
const { data, rvwType } = props;
const { data1, data2, data3, data4 } = data;
//==========================================================state
const [preview, setPreview] = useState<boolean>(false);//预览显隐
//页面文字显示
const method = getProMethod();
let showNameT: any = { tbr: '供应商' }//应答
if (method === 'procurement_mode_1' || method === 'procurement_mode_2') {//招标
showNameT = { tbr: '投标人' }
}
//预览表格
const columnsPreview: ProColumns<any>[] = [
{
title: '类别名称', width: 130, dataIndex: 'name',
render: (_: any, record: any, index: number) => {
return {
children: _,
props: {
rowSpan: record.rowSpan,
}
}
}
},
{ title: '评分项', dataIndex: "scoreItem" },
{
title: showNameT.tbr + 'XXX', dataIndex: "cate", width: 400,
render: (_, record) => {
return (
<>
{
rvwType === 1 &&
<Radio.Group >
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
}
{
rvwType === 2 && record.scoreMethod == 0 &&
record?.standardList?.map((item: any, index: any) => {
return (
<Radio value={index} className={styles.radioStyle}>
<label className={styles.labelStyle} style={{ width: '400px' }}>
{item.standardDetailScore}({item.standardName})
</label>
</Radio>
)
})
}
{
rvwType === 2 && record.scoreMethod == 1 &&
record.standardList.map((item: any, index: any) => {
return (
<Col span={24}>
<Checkbox value={index} className={styles.radioStyle}>
<label className={styles.labelStyle} style={{ width: '400px' }}>
{item.standardDetailScore}({item.standardName})
</label>
</Checkbox>
</Col>
)
})
}
{
rvwType === 2 && record.scoreMethod == 3 &&
<><InputNumber min={record.lowScore} max={record.highScore} defaultValue={record.lowScore} /> </>
}
{
rvwType === 2 && record.scoreMethod == 4 &&
<><InputNumber min={record.lowScore} max={record.highScore} defaultValue={record.lowScore} step={record.lowScore} /> {record.lowScore}</>
}
</>
)
}
},
];
//==========================================================func
/**
* 合并table单元格
* @param data
* @param fieldName
*/
const createNewArr = (data: any[], fieldName: string) => {
return data.reduce((result: any[], item: any) => {
//首先将name字段作为新数组result取出
if (result.indexOf(item[fieldName]) < 0) {
result.push(item[fieldName]);
}
return result
}, []).reduce((result: any[], name: any) => {
//将name相同的数据作为新数组取出并在其内部添加新字段**rowSpan**
const children = data.filter(item => item[fieldName] === name);
result = result.concat(
children.map((item: any, index: number) => ({
...item,
rowSpan: index === 0 ? children.length : 0,//将第一行数据添加rowSpan字段
}))
)
return result;
}, [])
}
//处理数据
function makeData(data: any) {
let datat: any = [];
data?.map((item: any) => {
item?.detailList?.map((item2: any) => {
item2['name'] = item.name;
datat.push(item2)
})
})
return datat;
}
let [data1t, data2t, data3t, data4t] = [
createNewArr(makeData(data1), 'name'),
createNewArr(makeData(data2), 'name'),
createNewArr(makeData(data3), 'name'),
createNewArr(makeData(data4), 'name'),
];
//==========================================================dom
const PreViewModal = () => {
return (
<Modal
visible={preview}
title="预览"
width={"60%"}
centered
bodyStyle={{ maxHeight: "500px", overflow: 'auto' }}
onCancel={() => setPreview(false)}
footer={renderFooter()}
>
{tabs()}
</Modal>
)
}
function tabs() {//页签
return (
<Tabs>
{
data1t.length > 0 &&
<TabPane tab={data1[0].categoryName} key="1">
{table(data1t)}
</TabPane>
}
{
data2t.length > 0 &&
<TabPane tab={data2[0].categoryName} key="2">
{table(data2t)}
</TabPane>
}
{
data3t.length > 0 &&
<TabPane tab={data3[0].categoryName} key="3">
{table(data3t)}
</TabPane>
}
{
data4t.length > 0 &&
<TabPane tab={data4[0].categoryName} key="4">
{table(data4t)}
</TabPane>
}
</Tabs>
)
}
function table(data: any) {
return (
<ProTable
columns={columnsPreview}
dataSource={data}
options={false}
search={false}
pagination={false}
bordered
/>
)
}
//页脚
function renderFooter() {
return (
<Button type='primary' onClick={() => setPreview(false)}></Button>
)
}
return (
<>
<Button
key="4"
style={{ marginRight: '10px' }}
onClick={() => {
setPreview(true);
}}></Button>
<PreViewModal />
</>
)
}
export default Preview;

View File

@ -1,4 +1,5 @@
import request from '@/utils/request';
import { message } from 'antd';
//查询
@ -22,6 +23,25 @@ export async function useTem(params?: any) {
params,
});
};
//使用模板
export const useT = async (fields: any) => {
const hide = message.loading('正在配置');
try {
const success = await useTem({ ...fields }).then(res => { return res.success });
hide();
if (success) {
message.success('配置成功');
return true;
} else {
message.error('配置失败');
return false;
}
} catch (error) {
hide();
message.error('配置失败请重试!');
return false;
}
};
//查询应答文件格式
export async function getTree(params?: any) {
return request(`/api/biz-service-ebtp-resps/v1/tdoccatalog/treelistForRsms`, {
@ -54,6 +74,24 @@ export async function glFile(params?: any) {
},
});
};
//保存关联文件
export const saveF = async (fields: any) => {
const hide = message.loading('正在保存');
try {
const success = await glFile({ ...fields }).then(res => { return res.success });
hide();
if (success) {
message.success('保存成功');
return true;
} else {
return false;
}
} catch (error) {
hide();
message.error('保存失败请重试!');
return false;
}
};
//保存
export async function saveData(params: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/detail`, {
@ -63,7 +101,25 @@ export async function saveData(params: any) {
},
});
}
//保存模板
//新增、保存对
export const save = async (fields: any) => {
const hide = message.loading('正在保存');
try {
const success = await saveData({ ...fields }).then(res => { return res.success });
hide();
if (success) {
message.success('保存成功');
return true;
} else {
return false;
}
} catch (error) {
hide();
message.error('保存失败请重试!');
return false;
}
};
//保存模板--接口
export async function saveTem(params: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/template/save`, {
method: 'POST',
@ -72,22 +128,108 @@ export async function saveTem(params: any) {
},
});
}
//删除单项
//保存模板--方法
export const saveT = async (fields: any) => {
const hide = message.loading('正在保存');
try {
const success = await saveTem({ ...fields }).then(res => { return res.success });
hide();
if (success) {
message.success('保存成功');
return true;
} else {
message.error('保存失败');
return false;
}
} catch (error) {
hide();
message.error('保存失败请重试!');
return false;
}
};
// 删除评审项接口
export async function delDetail(params?: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/detail/${params.id}`, {
method: 'DELETE'
});
};
//删除类别
export async function delCategory(params?: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/category/${params.id}`, {
//删除评审项方法
export const delDet = async (fields: any) => {
const hide = message.loading('正在删除');
try {
const success = await delDetail({ ...fields }).then(res => { return res.success });
hide();
if (success) {
message.success('删除成功');
return true;
} else {
return false;
}
} catch (error) {
hide();
message.error('配置失败请重试!');
return false;
}
};
//删除类别接口
export async function delCategory(id?: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/category/${id}`, {
method: 'DELETE'
});
};
//删除打分最小项细则
//删除类别方法
export const delCate = async (id: any) => {
const hide = message.loading('正在删除');
try {
const success = await delCategory(id).then(res => { return res.success });
hide();
if (success) {
message.success('删除成功');
return true;
} else {
return false;
}
} catch (error) {
hide();
message.error('删除失败请重试!');
return false;
}
};
//删除详细评分标准-接口
export async function delStandard(params?: any) {
return request(`/api/biz-service-ebtp-rsms/v1/review/config/standard/${params.id}`, {
method: 'DELETE'
// return request(`/api/biz-service-ebtp-rsms/v1/review/config/standard/${params.id}`, {
// method: 'DELETE'
return request(`/api/biz-service-ebtp-rsms/v1/review/config/standard`, {
method: 'POST',
data:params,
});
};
//删除详细评分标准方法
export const delStan = async (fields: any) => {
const hide = message.loading('正在删除');
try {
const success = await delStandard(fields).then(res => { return res.success });
hide();
if (success) {
// message.success('删除成功');
return true;
} else {
return false;
}
} catch (error) {
hide();
message.error('删除失败请重试!');
return false;
}
};
//初审EXCEL模板
export async function firstTem() {
return request(`/api/biz-service-ebtp-extend/v1/template/warehouse/fhxsc`);
};
//详审EXCEL模板
export async function detailTem() {
return request(`/api/biz-service-ebtp-extend/v1/template/warehouse/pfbz`);
};

View File

@ -0,0 +1,264 @@
import { btnAuthority } from "@/utils/authority";
import FileDown from "@/utils/Download";
import { UploadOutlined } from "@ant-design/icons";
import ProTable, { ActionType, ProColumns } from "@ant-design/pro-table";
import { Button, Col, Dropdown, Form, Input, Menu, message, Modal, Row, Spin, Upload } from "antd";
import React, { useRef, useState } from "react";
import { getTemPage, saveT, useT } from "./service";
import '@/assets/xsy_style.less'
type TemType = {
rvwType: number,//初审1 详审2
commonId: string,//公共id
assessRoomId: string,//评审室id
nodeId: string,//节点id
dis: boolean,
oid: string,//文件id
purchaseMethod: number,//1234 初审 详审 初审有限数量制 详审无报价
reviewId?: string,//detId 详审id firstId 初审id
rePage: () => {},//执行父组件刷新页面的方法
processData: (data: any) => {}//处理数据
parentSpin: (value: any) => {},//控制父组件 spin
}
const TempleteBtns: React.FC<TemType> = (props) => {
//=====================================================================state
const { reviewId, rvwType, assessRoomId, commonId, nodeId, dis, oid, purchaseMethod, rePage, processData, parentSpin } = props;
const FormItem = Form.Item;
const [form] = Form.useForm();
const ref = useRef<ActionType>();
//模板
const [temSave, setTemSave] = useState<boolean>(false);//保存模板
const [temUse, setTemUse] = useState<boolean>(false);//使用模板
const [modalSpin, modalSpinSet] = useState<boolean>(false);//保存模板Spin
const [pageTemData, setPageTemData] = useState<any>({ pageNo: 1, pageSize: 10, rvwType, templateName: "", purchaseMethod }); //查询模板分页数据
const upProps = {
name: 'file',
action: '/api/biz-service-ebtp-rsms/v1/review/config/template/importTemplate',
data: {
id: reviewId, rvwType: rvwType, commonId: commonId, nodeId: nodeId
},
accept: ".xls,.xlsx",
itemRender: () => { return null },
onChange(info: any) {
parentSpin(true);
if (info.file.status === 'done') {
if (info.file?.response?.code == 200) {
message.success(`${info.file.name} 导入成功,保存生效`);
//给表格加key
info.file?.response?.data.categoryList.map((item: any, index: number) => {
item.key = index;
})
processData(info.file?.response);
info2();
} else {
message.error(info.file?.response?.message);
}
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 上传失败`);
rePage();
}
parentSpin(false);
},
};
//模板列表表格
const columnsTemUse: ProColumns<any>[] = [
{ title: '序号', valueType: 'index', },
{ title: '模板名称', dataIndex: 'templateName', },
{ title: '制作人', dataIndex: 'name', },
{ title: '制作时间', width: 200, dataIndex: 'createDate', valueType: 'dateTime' },
{
title: '操作', dataIndex: 'option', width: 100, valueType: 'option',
render: (_, record) => {
return (
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
type='text'
className='xsyBtn'
onClick={async () => {
modalSpinSet(true);
const configId = reviewId;
const id = record.id;
const success = await useT({ configId, id, commonId, nodeId });
if (success) {
setTemUse(false);
parentSpin(true);
info();
rePage();
}
modalSpinSet(false);
}}>使</Button>
)
}
},
];
//=====================================================================func
function info() {
Modal.info({
centered: true,
title: '使用模板后,需重新保存,数据方可留存。',
});
}
function info2() {
Modal.info({
centered: true,
title: '导入EXCEL成功后,需重新保存,数据方可留存。',
});
}
//=====================================================================dom
const menu = (
<Menu style={{ backgroundColor: "white" }}>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
disabled={dis}
type="primary"
key="menuBtnSave"
style={{ margin: '2px 5px' }}
onClick={() => {
assessRoomId != null ?
setTemSave(true)
: message.info('请先保存配置')
}}
></Button>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
disabled={dis}
type="primary"
key="menuBtnUse"
style={{ margin: '2px 5px' }}
onClick={() => {
ref.current?.reload();
setTemUse(true);
}}
>使</Button>
<FileDown
apiUrl={`/api/core-service-ebtp-updownload/v1/attachment/download/oid/${oid}`}
btnName={'下载EXCEL模板'}
style={{ margin: '2px 5px' }}
/>
<Upload {...upProps}>
<Button
hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])}
icon={<UploadOutlined />}
disabled={dis}
type="primary"
key="menuBtnImport"
style={{ margin: '2px 5px' }}
>EXCEL</Button>
</Upload>
</Menu>
);
//表格按钮
const tools = [
<Input placeholder="模板全名或关键字" onChange={(event) => {
let data = pageTemData;
data.templateName = event.target.value;
setPageTemData(data);
}} />,
<Button type="primary" loading={modalSpin} onClick={() => {
if (ref.current) {
ref.current.reload();
}
}}></Button>,
];
return (
<>
<Dropdown.Button overlay={menu}></Dropdown.Button>
<Modal
visible={temSave}
width={"40%"}
onCancel={() => setTemSave(false)}
okButtonProps={{ loading: modalSpin }}
onOk={async () => {
parentSpin(true);
modalSpinSet(true);
const configId = reviewId;
const templateName = form.getFieldsValue().temName;
const allData = { configId, templateName, rvwType, purchaseMethod };
let success = false;
if (configId != '') {
if (templateName != "") {
success = await saveT(allData);
}
} else {
message.error('请先保存页面数据!')
}
if (success) {
setTemSave(false);
rePage();
}
modalSpinSet(false);
parentSpin(false);
}}
centered
title="保存模板"
>
<Spin spinning={modalSpin}>
<Form
labelCol={{ span: 6 }}
wrapperCol={{ span: 16 }}
form={form}
>
<Row>
<Col span={24}><FormItem
name="temName"
label="模板名称"
rules={[
{
required: true,
message: '请输入模板名称',
},
]}
>
<Input placeholder="请输入模板名称" />
</FormItem>
</Col>
</Row>
</Form>
</Spin>
</Modal>
<Modal
visible={temUse}
centered
title="使用模板"
width={1000}
okButtonProps={{ loading: modalSpin }}
onCancel={() => setTemUse(false)}
footer={[<Button type='primary' onClick={() => setTemUse(false)}> </Button>]}
>
<Spin spinning={modalSpin}>
<ProTable
actionRef={ref}
columns={columnsTemUse}//表格
options={false}
search={false}
toolBarRender={() => tools}
request={() =>
getTemPage({ ...pageTemData }).then((res) => {
const result = {
data: res.data.records,
total: res.data.total,
success: res.success,
pageSize: res.pageSize,
current: res.current
};
return result;
})
}
pagination={{
defaultPageSize: 10,
showSizeChanger: false,
onChange: (page, pageSize) => {
let data = pageTemData;
data.pageNo = page;
data.pageSize = pageSize;
setPageTemData(data);
}
}}
/>
</Spin>
</Modal>
</>
)
}
export default TempleteBtns;

View File

@ -1,16 +0,0 @@
import { Card, Tree } from 'antd';
import React, {} from 'react';
const TreeTem: React.FC<{}> = () => {
const roomId = "111"
return (
<>
<Card>
<Tree>
</Tree>
</Card>
</>
)
};
export default TreeTem ;