评价打分和年审审核时候需要根据模板的星号项来验证

This commit is contained in:
linxd
2025-08-08 14:51:02 +08:00
parent 8d8d5eb638
commit a524a91494
7 changed files with 156 additions and 66 deletions

View File

@ -14,7 +14,11 @@
margin-left: auto;
}
}
.require{
color: red;
margin-right: 5px;
vertical-align: middle;
}
.content-area {
}

View File

@ -38,6 +38,7 @@ interface ScoreFormItem {
description: string;
examineResult: string;
remark: string;
isStar: string; // 是否为星号项
}
const SupplierAnnualReviewScore: React.FC = () => {
@ -76,7 +77,9 @@ const SupplierAnnualReviewScore: React.FC = () => {
message.warning(intl.formatMessage({ id: 'supplierAnnualReview.score.noScoreItemData' }));
}
} else {
message.error(res.message || intl.formatMessage({ id: 'supplierAnnualReview.detail.getDetailFailed' }));
message.error(
res.message || intl.formatMessage({ id: 'supplierAnnualReview.detail.getDetailFailed' }),
);
}
} catch (error) {
console.error('获取审查详情失败:', error);
@ -128,7 +131,9 @@ const SupplierAnnualReviewScore: React.FC = () => {
message.success(intl.formatMessage({ id: 'supplierAnnualReview.score.submitSuccess' }));
history.goBack();
} else {
message.error(res.message || intl.formatMessage({ id: 'supplierAnnualReview.score.submitFailed' }));
message.error(
res.message || intl.formatMessage({ id: 'supplierAnnualReview.score.submitFailed' }),
);
}
} catch (error) {
console.error('评审提交失败:', error);
@ -142,6 +147,21 @@ const SupplierAnnualReviewScore: React.FC = () => {
try {
// 表单验证
await form.validateFields();
const formValues = form.getFieldsValue();
const scoreVoList = scoreItems.map((item) => ({
id: item.id,
name: item.itemName,
description: item.description,
examineResult: formValues[`examineResult_${item.id}`],
remark: formValues[`remark_${item.id}`] || '',
isStar: item.isStar, // 是否为星号项
}));
// 检查所有星号项是否必填
const validateIsStar = scoreVoList.some((item) => item.isStar == '1' && !item.examineResult);
if (validateIsStar) {
message.warning('请填写所有星号项的评审结果!');
return;
}
// 确认提交
Modal.confirm({
@ -159,7 +179,8 @@ const SupplierAnnualReviewScore: React.FC = () => {
// 获取状态标签
const getStatusTag = (status: string | undefined, statusName: string | undefined) => {
if (!status) return <Tag>{intl.formatMessage({ id: 'supplierAnnualReview.common.unknownStatus' })}</Tag>;
if (!status)
return <Tag>{intl.formatMessage({ id: 'supplierAnnualReview.common.unknownStatus' })}</Tag>;
const color =
AnnualReviewStatusColor[status as keyof typeof AnnualReviewStatusColor] || 'default';
const text =
@ -183,23 +204,47 @@ const SupplierAnnualReviewScore: React.FC = () => {
<Spin spinning={loading}>
{reviewDetail ? (
<>
<Card title={intl.formatMessage({ id: 'supplierAnnualReview.score.basicInfo' })} bordered={false} className={styles['detail-card']}>
<Card
title={intl.formatMessage({ id: 'supplierAnnualReview.score.basicInfo' })}
bordered={false}
className={styles['detail-card']}
>
<Descriptions column={2} bordered>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.reviewTheme' })}>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.reviewTheme' })}
>
{reviewDetail.annualreviewTheme}
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.supplierName' })}>
<a onClick={() => supplierDetailModal?.(reviewDetail.supplierId)}>{reviewDetail.name}</a>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.supplierName' })}
>
<a onClick={() => supplierDetailModal?.(reviewDetail.supplierId)}>
{reviewDetail.name}
</a>
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.department' })}>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.department' })}
>
{reviewDetail.deptName || '-'}
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.reviewer' })}>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.reviewer' })}
>
{reviewDetail.reviewerName || '-'}
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.startTime' })}>{reviewDetail.startTime}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.endTime' })}>{reviewDetail.endTime}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'supplierAnnualReview.list.status' })}>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.startTime' })}
>
{reviewDetail.startTime}
</Descriptions.Item>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.endTime' })}
>
{reviewDetail.endTime}
</Descriptions.Item>
<Descriptions.Item
label={intl.formatMessage({ id: 'supplierAnnualReview.list.status' })}
>
{reviewDetail.reviewStatusName || '-'}
</Descriptions.Item>
</Descriptions>
@ -207,7 +252,11 @@ const SupplierAnnualReviewScore: React.FC = () => {
<Divider />
<Card title={intl.formatMessage({ id: 'supplierAnnualReview.score.examineResult' })} bordered={false} className={styles['detail-card']}>
<Card
title={intl.formatMessage({ id: 'supplierAnnualReview.score.examineResult' })}
bordered={false}
className={styles['detail-card']}
>
<Form form={form} layout="vertical" className={styles['score-form']}>
{scoreItems.length > 0 ? (
<Table
@ -221,20 +270,22 @@ const SupplierAnnualReviewScore: React.FC = () => {
title: intl.formatMessage({ id: 'supplierAnnualReview.score.scoreItem' }),
dataIndex: 'itemName',
width: '15%',
render: (text, record) => (
<div>
{record.isStar == '1' && <span className={styles['require']}>*</span>}
{text}
</div>
),
},
// {
// title: intl.formatMessage({ id: 'supplierAnnualReview.score.scoreItemDesc' }),
// dataIndex: 'description',
// width: '25%',
// },
{
title: intl.formatMessage({ id: 'supplierAnnualReview.detail.examineResult' }),
title: intl.formatMessage({
id: 'supplierAnnualReview.detail.examineResult',
}),
dataIndex: 'examineResult',
width: '25%',
render: (_, record) => (
<Form.Item
name={`examineResult_${record.id}`}
rules={[{ required: true, message: intl.formatMessage({ id: 'supplierAnnualReview.score.pleaseSelectResult' }) }]}
style={{ marginBottom: 0 }}
>
<Radio.Group>
@ -249,17 +300,18 @@ const SupplierAnnualReviewScore: React.FC = () => {
),
},
{
title: intl.formatMessage({ id: 'supplierAnnualReview.score.examineRemark' }),
title: intl.formatMessage({
id: 'supplierAnnualReview.score.examineRemark',
}),
dataIndex: 'remark',
width: '35%',
render: (_, record) => (
<Form.Item
name={`remark_${record.id}`}
style={{ marginBottom: 0 }}
>
<Form.Item name={`remark_${record.id}`} style={{ marginBottom: 0 }}>
<TextArea
rows={2}
placeholder={intl.formatMessage({ id: 'supplierAnnualReview.score.pleaseInputRemark' })}
placeholder={intl.formatMessage({
id: 'supplierAnnualReview.score.pleaseInputRemark',
})}
maxLength={200}
/>
</Form.Item>
@ -268,7 +320,11 @@ const SupplierAnnualReviewScore: React.FC = () => {
]}
/>
) : (
<Empty description={intl.formatMessage({ id: 'supplierAnnualReview.score.noScoreItemData' })} />
<Empty
description={intl.formatMessage({
id: 'supplierAnnualReview.score.noScoreItemData',
})}
/>
)}
<div className={styles['score-actions']}>
@ -285,7 +341,11 @@ const SupplierAnnualReviewScore: React.FC = () => {
</Card>
</>
) : (
!loading && <Empty description={intl.formatMessage({ id: 'supplierAnnualReview.detail.noDetailData' })} />
!loading && (
<Empty
description={intl.formatMessage({ id: 'supplierAnnualReview.detail.noDetailData' })}
/>
)
)}
</Spin>
</Card>

View File

@ -84,10 +84,10 @@ const SupplierEvaluateScoreDetail: React.FC = () => {
id: subItem.id,
subIndicator: subItem.subIndicator,
subScore: subItem.subScore, // 二级指标标准分值
isStar: subItem.starIndicator,
scoreNum: subItem.score || '', // 实际评分值使用API返回的score字段
score: subItem.score || '', // 组件内部显示用
remark: subItem.remark || '',
isStar: subItem.isStar, // 是否必填
};
})
.filter(Boolean) || [],
@ -151,12 +151,12 @@ const SupplierEvaluateScoreDetail: React.FC = () => {
const hasEmptyScore = scoreData.some((item) =>
item.indicatorNdList.some((subItem: any) => {
// 使用scoreNum字段检查是否已评分
return !subItem.scoreNum && subItem.scoreNum !== 0;
return !subItem.scoreNum && subItem.scoreNum !== 0 && subItem.isStar === '1'; // 只检查必填项
}),
);
if (hasEmptyScore) {
message.warning(intl.formatMessage({ id: 'supplierEvaluateScore.message.emptyScore' }));
message.warning("请填写所有必填项的评分!");
return;
}

View File

@ -316,7 +316,7 @@ const handleDisableTemplate = (id: string) => {
name="tenantName"
label={intl.formatMessage({ id: 'supplierTemplateManage.column.tenantName' })}
>
<AccessDepartmentSelect placeholder={'请选择准入单位'} />
<AccessDepartmentSelect placeholder={'请选择创建单位'} />
</Form.Item>
<Form.Item
name="categoryId"