供应商评价模板,禁用逻辑

This commit is contained in:
linxd
2025-07-04 13:14:27 +08:00
parent 359559f61b
commit ba28c1ff51
5 changed files with 157 additions and 68 deletions

View File

@ -1,5 +1,5 @@
// 供应商评价 模板管理新增中的table
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { useIntl } from 'umi';
import { Table, Input, Button, Select, InputNumber, message, Popconfirm, Switch } from 'antd';
import {
@ -37,6 +37,7 @@ interface EvaluateTemplateTableProps {
* - disabledNd二级指标禁用状态独立控制每个二级指标
*/
interface TableRowItem {
id?: string;
key: string;
stId?: string; // 一级指标ID
ndId?: string; // 二级指标ID
@ -60,11 +61,15 @@ interface TableRowItem {
scoreEdit?: string; // 分值是否可编辑(0.是、1.否)
indicatorStEdit?: string; // 该一级指标是否可编辑(0.是、1.否)
indicatorStEditST?: string; // 该一级指标是否可编辑(0.是、1.否)
baseIndicatorEditST?: string; // 基本指标是否可编辑 0.是、1.否
descIndicatorEditST?: string; // 指标说明是否可编辑(0.是、1.否)
scoreEditST?: string; // 分值是否可编辑(0.是、1.否)
baseIndicatorEditST?: string; // 一级指标基本指标是否可编辑 0.是、1.否
descIndicatorEditST?: string; // 一级指标指标说明是否可编辑(0.是、1.否)
scoreEditST?: string; // 一级指标分值是否可编辑(0.是、1.否)
descIndicatorEditNd?: string; // 二级指标说明是否可编辑(0.是、1.否)
baseIndicatorEditNd?: string; // 二级指标基本指标是否可编辑 0.是、1.否
scoreEditNd?: string; // 二级指标分值是否可编辑(0.是、1.否)
indicatorStEditNd?: string; // 二级指标该一级指标是否可编辑(0.是、1.否)
}
const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
@ -81,6 +86,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
const intl = useIntl();
const [dataSource, setDataSource] = useState<TableRowItem[]>([]);
const [indicatorTypes, setIndicatorTypes] = useState<DictItem[]>([]);
const [compIndicatorTypes, setCompIndicatorTypes] = useState<DictItem[]>([]);
const [loadingTypes, setLoadingTypes] = useState<boolean>(false);
const [isFirstDisabled, setIsFirstDisabled] = useState<boolean>(!firstIsAdd);
@ -88,9 +94,11 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
setIsFirstDisabled(!firstIsAdd);
if (disableType) {
const newIndicatorTypes = indicatorTypes.filter((item) => item.code !== disableType);
setIndicatorTypes(newIndicatorTypes);
setCompIndicatorTypes(newIndicatorTypes);
} else {
setCompIndicatorTypes(indicatorTypes);
}
}, [firstIsAdd, disableType]);
}, [firstIsAdd, disableType, indicatorTypes]);
// 获取指标类型字典
const fetchIndicatorTypes = async () => {
@ -145,6 +153,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
key: ndItem.id || `${stItem.id}-${ndIndex}`,
stId: stItem.id,
ndId: ndItem.id,
id: ndItem.id,
baseIndicator: stItem.baseIndicator,
descIndicator: stItem.descIndicator,
stScore: stItem.score,
@ -157,10 +166,16 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
ndOrderBy:
typeof ndItem.orderBy === 'string' ? parseInt(ndItem.orderBy) : ndItem.orderBy,
selected: defaultSelectedIds.includes(ndItem.id), // 根据defaultSelectedIds设置选中状态
// 一级指标禁用选项
indicatorStEditST: stItem.indicatorStEdit,
baseIndicatorEditST: stItem.baseIndicatorEdit,
descIndicatorEditST: stItem.descIndicatorEdit,
scoreEditST: stItem.scoreEdit,
// 二级指标禁用选项
indicatorStEditNd: ndItem.indicatorStEdit,
baseIndicatorEditNd: ndItem.baseIndicatorEdit,
descIndicatorEditNd: ndItem.descIndicatorEdit,
scoreEditNd: ndItem.scoreEdit,
});
});
});
@ -193,10 +208,10 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
const firstItem = level1Items[0];
// 生成唯一的临时ID
const tempStId = `temp-st-${generateUUID(16)}-${stIndex}`;
// const tempStId = `temp-st-${generateUUID(16)}-${stIndex}`;
return {
id: firstItem.stId || tempStId,
id: firstItem.stId,
baseIndicator: firstItem.baseIndicator || '',
descIndicator: firstItem.descIndicator || '',
indicatorStEdit: firstItem.indicatorStEditST || 0,
@ -212,13 +227,17 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
const tempNdId = `temp-nd-${generateUUID(16)}-${stIndex}-${ndIndex}`;
return {
id: item.ndId || tempNdId,
id: item.ndId,
subIndicator: item.subIndicator || '',
score: item.ndScore || '0',
isStar: item.isStar || StarLevel.NO,
orderBy: item.ndOrderBy || ndIndex + 1,
descScore: item.descScore || '',
disabled: item.disabledNd, // 关键点3: 保留二级指标禁用状态确保在回传API格式时不丢失
// 二级指标禁用选项
indicatorNdEdit: item.indicatorStEditNd,
baseIndicatorEdit: item.baseIndicatorEditNd,
descIndicatorEdit: item.descIndicatorEditNd,
scoreEdit: item.scoreEditNd,
};
}),
};
@ -321,6 +340,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
const updateDataSource = (newData: TableRowItem[]) => {
// 确保每行都有唯一稳定的key
const finalData = ensureUniqueKeys(newData);
console.log('finalData', finalData);
setDataSource(finalData);
if (onChange) {
// 转换回API格式再传递给父组件
@ -426,9 +446,11 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
orderBy: dataSource.length + 1, // 确保正确的排序
ndOrderBy: 1, // 设置二级指标初始排序
selected: false, // 默认未选中
// 关键点4确保新添加的行也有正确的禁用属性否则会导致现有禁用状态丢失
disabledSt: false, // 默认不禁用一级指标
disabledNd: false, // 默认不禁用二级指标
descIndicatorEditST: '0',
baseIndicatorEditST: '0',
scoreEditST: '0',
indicatorStEditST: '0',
};
// 制作数据源的副本,避免直接修改状态
const newData = dataSource.map((item) => ({ ...item }));
@ -503,9 +525,11 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
ndOrderBy:
dataSource.filter((item) => item.baseIndicator === parent.baseIndicator).length + 1,
selected: false, // 默认未选中
// 关键点7继承父级的一级指标禁用状态确保同组内禁用状态一致
disabledSt: parent.disabledSt, // 继承父级的一级指标禁用状态
disabledNd: false, // 默认不禁用二级指标
descIndicatorEditNd: '0',
baseIndicatorEditNd: '0',
scoreEditNd: '0',
indicatorStEditNd: '0',
};
// 找到当前记录所在的位置
@ -590,17 +614,64 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
};
const filterColumns = (col: any) => {
if ((isDetail || getUserRole() != 'admin') && ['level1Action', 'indicatorStEditST', 'baseIndicatorEditST', 'descIndicatorEditST', 'scoreEditST'].includes(col.key)) {
if (isDetail) {
return false;
}
if (getUserRole() != 'admin') {
if (
['indicatorStEditST', 'baseIndicatorEditST', 'descIndicatorEditST', 'scoreEditST'].includes(
col.key,
)
) {
return false;
}
}
// if ((isDetail || getUserRole() != 'admin') && ) {
// return false;
// }
return true;
};
const filterColumnsSecond = (col: any) => {
if ((isDetail || getUserRole() != 'admin') && ['level2Action'].includes(col.key)) {
if (isDetail) {
return false;
}
if (getUserRole() != 'admin') {
if (
['indicatorStEditNd', 'baseIndicatorEditNd', 'descIndicatorEditNd', 'scoreEditNd'].includes(
col.key,
)
) {
return false;
}
}
return true;
};
// 判断二级指标中的操作项内是否显示删除按钮
const compShowDelBtnBySecondRecord = (record: TableRowItem) => {
// 如果当前一级指标下有多个二级指标,则显示删除按钮
if (getLevel1RowSpan(record.baseIndicator) > 1) {
// 如果当前二级指标有id,则不显示删除按钮
if (record.id && record.id !== '') {
return false;
} else {
return true;
}
}
return false;
};
const compShowDelBtnByRecord = useCallback((record: TableRowItem) => {
// isFirstDisabled 是否禁用 true false;
// record.indicatorStEditST 是否可编辑 0是 1否
// record.id 是否是新增的 有id是新增的 没有id是新增的
// isFirstDisabled &&
if (record.indicatorStEditST === '1') {
return false;
}
// if (record.id && record.id !== '') {
// return false;
// }
return true;
}, [isFirstDisabled]);
const columns = [
{
title: intl.formatMessage({ id: 'supplierTemplateManage.evaluateTable.levelOne' }),
@ -625,7 +696,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return renderWithRowSpan(text, record, (cellContent) => {
if (isDetail) {
// 在详情模式下,查找并显示字典中对应的名称
const typeItem = indicatorTypes.find((item) => item.code === cellContent);
const typeItem = compIndicatorTypes.find((item) => item.code === cellContent);
return typeItem ? typeItem.dicName : cellContent || '-';
}
@ -638,13 +709,16 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
})}
style={{ width: '100%' }}
loading={loadingTypes}
disabled={record.indicatorStEditST === "1"}
disabled={record.indicatorStEditST === '1'}
>
{indicatorTypes.map((item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
))}
{/* 如果是禁用状态,使用原始数据渲染,否则会显示code值 */}
{(record.indicatorStEditST === '1' ? indicatorTypes : compIndicatorTypes).map(
(item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
),
)}
</Select>
);
});
@ -664,7 +738,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return (
<Input
value={cellContent}
disabled={record.baseIndicatorEditST === "1" || record.indicatorStEditST === "1"}
disabled={record.baseIndicatorEditST === '1' || record.indicatorStEditST === '1'}
onChange={(e) => handleInputChange(e.target.value, record, 'baseIndicator')}
placeholder={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.placeholder.baseIndicator',
@ -688,10 +762,9 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
}
return (
<Switch
defaultChecked={true}
checked={cellContent === "0"}
checked={cellContent === '0'}
onChange={(checked) =>
handleInputChange(checked ? "0" : "1", record, 'baseIndicatorEditST')
handleInputChange(checked ? '0' : '1', record, 'baseIndicatorEditST')
}
/>
);
@ -699,7 +772,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
},
},
{
title: "指标说明",
title: '指标说明',
align: 'center',
dataIndex: 'descIndicator',
key: 'descIndicator',
@ -712,7 +785,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return (
<Input
value={cellContent}
disabled={record.descIndicatorEditST === "1" || record.indicatorStEditST === "1"}
disabled={record.descIndicatorEditST === '1' || record.indicatorStEditST === '1'}
onChange={(e) => handleInputChange(e.target.value, record, 'descIndicator')}
placeholder={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.placeholder.indicatorDescription',
@ -735,15 +808,14 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return cellContent === 1 ? '是' : '否';
}
return (
<>
<Switch
defaultChecked={true}
checked={cellContent === "0"}
onChange={(checked) =>
handleInputChange(checked ? "0" : "1", record, 'descIndicatorEditST')
}
/>
</>
<>
<Switch
checked={cellContent === '0'}
onChange={(checked) =>
handleInputChange(checked ? '0' : '1', record, 'descIndicatorEditST')
}
/>
</>
);
});
},
@ -763,7 +835,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
<InputNumber
min={0}
max={100}
disabled={record.scoreEditST === "1" || record.indicatorStEditST === "1"}
disabled={record.scoreEditST === '1' || record.indicatorStEditST === '1'}
value={parseFloat(cellContent) || 0}
onChange={(val) => handleInputChange(val?.toString() || '0', record, 'stScore')}
style={{ width: '100%' }}
@ -787,9 +859,9 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return (
<Switch
defaultChecked={true}
checked={cellContent === "0"}
checked={cellContent === '0'}
onChange={(checked) =>
handleInputChange(checked ? "0" : "1", record, 'scoreEditST')
handleInputChange(checked ? '0' : '1', record, 'scoreEditST')
}
/>
);
@ -808,7 +880,8 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
<div className="action-buttons">
<Button
type="text"
disabled={isFirstDisabled || record.indicatorStEditST === "1"}
// isFirstDisabled
disabled={record.indicatorStEditST === '1'}
icon={<PlusCircleOutlined />}
onClick={() => {
addLevel1Indicator(record);
@ -829,15 +902,17 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
id: 'supplierTemplateManage.evaluateTable.confirm.cancel',
})}
>
<Button
type="text"
danger
disabled={isFirstDisabled || record.indicatorStEditST === "1"}
icon={<DeleteOutlined />}
title={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.button.deleteLevelOne',
})}
/>
{compShowDelBtnByRecord(record) && (
<Button
type="text"
danger
// disabled={isFirstDisabled || record.indicatorStEditST === '1'}
icon={<DeleteOutlined />}
title={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.button.deleteLevelOne',
})}
/>
)}
</Popconfirm>
</div>
));
@ -858,9 +933,9 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
return (
<Switch
defaultChecked={true}
checked={cellContent === "0"}
checked={cellContent === '0'}
onChange={(checked) =>
handleInputChange(checked ? "0" : "1", record, 'indicatorStEditST')
handleInputChange(checked ? '0' : '1', record, 'indicatorStEditST')
}
/>
);
@ -982,7 +1057,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
})}
/>
{/* 如果该一级指标下有多个二级指标,才允许删除 */}
{getLevel1RowSpan(record.baseIndicator) > 1 && (
{compShowDelBtnBySecondRecord(record) && (
<Popconfirm
title={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.confirm.delete',
@ -991,6 +1066,7 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
okText={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.confirm.ok',
})}
disabled={record.disabledNd}
cancelText={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.confirm.cancel',
})}
@ -998,7 +1074,6 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
<Button
type="text"
danger
disabled={record.disabledNd}
icon={<MinusCircleOutlined />}
title={intl.formatMessage({
id: 'supplierTemplateManage.evaluateTable.button.deleteSubIndicator',
@ -1048,7 +1123,8 @@ const EvaluateTemplateTable: React.FC<EvaluateTemplateTableProps> = ({
}),
}}
/>
{!isDetail && !isFirstDisabled && (
{/* && !isFirstDisabled */}
{!isDetail && (
<div className="add-button-row">
<Button
type="dashed"

View File

@ -3,7 +3,7 @@ import { useState } from "react";
// 获取用户信息 这里没用dva, 因为包装组件写法复杂(当前框架),尤其是有form表单组件时
export const useUser = () => {
const [user, setUser] = useState<any>({
role: 'admin', // 模拟用户权限
role: 'admin1', // 模拟用户权限
});
const getUserInfo = ()=>{
return user;

View File

@ -79,7 +79,7 @@ const SupplierAnnualTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, disp
const fetchTemplateList = async () => {
try {
setLoading(true);
const res = await getAllAnnualTemplates();
const res = await getAllAnnualTemplates({ status: '1' });
if (res.success && res.data) {
// 如果是修改,需要过滤掉自己
if (location.state?.editData) {

View File

@ -44,7 +44,6 @@ interface PageProps extends ConnectProps {
const SupplierTaskManageAdd: React.FC<PageProps> = ({
supplierTaskManage,
dispatch,
breadcrumb,
}) => {
const intl = useIntl();
// 获取dva model中的状态

View File

@ -92,7 +92,7 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
// 获取所有模板列表
const fetchTemplateList = async () => {
try {
const res = await getAllTemplates();
const res = await getAllTemplates({ status: '1' });
if (res.success && res.data) {
// 如果是修改,需要过滤掉自己
if (location.state?.editData) {
@ -234,6 +234,7 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
if (isEdit && templateDetail) {
dataToSubmit.id = templateDetail.id;
}
debugger
setLoading(true);
try {
// 调用API接口
@ -337,6 +338,11 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
// setTemplateData(copiedIndicatorStList);
setTemplateData(res.data.indicatorStList);
// 赋值表单,因为需要传递到组件中判断状态
form.setFieldsValue({
indicatorStMore: res.data.indicatorStMore,
indicatorTypeMore: res.data.indicatorTypeMore,
})
}
} else {
message.error(
@ -502,6 +508,10 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
id: 'supplierTemplateManage.form.selectTemplate',
})}
loading={templateList.length === 0}
showSearch={true}
filterOption={(input, option) => {
return (option?.children ?? '').toLowerCase().includes(input.toLowerCase())
}}
onSelect={handleTemplateSelect}
>
{templateList.map((template) =>
@ -534,11 +544,16 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
</Form.Item>
</Col>
</Row>
{getUserRole() === 'admin' && (
<Row gutter={24}>
<Col span={8}>
<Form.Item label="是否可追加一级指标" name="indicatorStMore">
<Radio.Group>
<Form.Item label="是否可追加一级指标" name="indicatorStMore" hidden={getUserRole() !== 'admin'}>
<Radio.Group onChange={(e) => {
if (e.target.value === IndicatorAddOption.CAN_ADD) {
form.setFieldsValue({
indicatorTypeMore: '',
});
}
}}>
<Radio value={IndicatorAddOption.CAN_ADD}>
{IndicatorAddOptionText[IndicatorAddOption.CAN_ADD]}
</Radio>
@ -555,7 +570,7 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
{({ getFieldValue }) =>
getFieldValue('indicatorStMore') === IndicatorAddOption.CANNOT_ADD ? (
<Col span={8}>
<Form.Item label="禁用指标类型" name="indicatorTypeMore">
<Form.Item label="禁用指标类型" name="indicatorTypeMore" hidden={getUserRole() !== 'admin'}>
<Select
placeholder="请选择禁用指标类型"
options={indicatorTypes}
@ -580,7 +595,6 @@ const SupplierTemplateManageAdd: React.FC<PageProps> = ({ breadcrumb, dispatch }
</Form.Item>
</Col> */}
</Row>
)}
</Card>
<Divider />