维护国际化

This commit is contained in:
linxd
2025-07-03 10:21:55 +08:00
parent fafb2cda44
commit cf8e9d0820
61 changed files with 2246 additions and 836 deletions

View File

@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { TreeSelect, message, Spin } from 'antd';
import { getCategoryTree } from '@/servers/api/supplierEvaluate';
import './CategorySelector.less';
import { useIntl } from 'umi';
/**
* CategorySelector组件的属性接口
@ -57,14 +58,18 @@ const CategorySelector: React.FC<CategorySelectorProps> = ({
onChange,
disabled = false,
multiple = true,
placeholder = '请选择品类',
placeholder,
style = { width: '100%' }
}) => {
const intl = useIntl();
// 树形数据状态
const [treeData, setTreeData] = useState<TreeSelectNode[]>([]);
// 加载状态
const [loading, setLoading] = useState<boolean>(false);
// 如果没有提供placeholder使用国际化的默认值
const defaultPlaceholder = intl.formatMessage({ id: 'supplierTaskManage.placeholder.selectCategory' });
/**
* 将后端返回的品类数据格式化为TreeSelect需要的格式
* @param {any[]} data - 后端返回的原始品类数据
@ -79,7 +84,7 @@ const CategorySelector: React.FC<CategorySelectorProps> = ({
// 类型为1的节点是叶子节点只有叶子节点可选
const isLeaf = item.type === '1';
const node: TreeSelectNode = {
title: item.categoryName || '未命名',
title: item.categoryName || intl.formatMessage({ id: 'supplierTaskManage.categoryName.unnamed' }),
key: item.id || `key-${Math.random()}`,
value: item.id || `value-${Math.random()}`,
isLeaf: isLeaf,
@ -111,11 +116,11 @@ const CategorySelector: React.FC<CategorySelectorProps> = ({
setTreeData(formattedTreeData);
} else {
console.error('获取品类数据格式错误:', response);
message.error('获取品类数据失败');
message.error(intl.formatMessage({ id: 'supplierTaskManage.message.fetchCategoryFailed' }));
}
}).catch(error => {
console.error('获取品类数据失败:', error);
message.error('获取品类数据失败');
message.error(intl.formatMessage({ id: 'supplierTaskManage.message.fetchCategoryFailed' }));
}).finally(() => {
setLoading(false);
});
@ -153,7 +158,7 @@ const CategorySelector: React.FC<CategorySelectorProps> = ({
value={value}
onChange={handleChange}
style={style}
placeholder={placeholder}
placeholder={placeholder || defaultPlaceholder}
disabled={disabled}
allowClear
showSearch

View File

@ -4,6 +4,7 @@ import type { TablePaginationConfig } from 'antd/es/table';
import { SearchOutlined } from '@ant-design/icons';
import { getUserList } from '@/servers/api/user';
import './EvaluateTaskPersonnelSelector.less';
import { useIntl } from 'umi';
const { Search } = Input;
@ -41,6 +42,7 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
filterUserIds = [],
onClose,
}) => {
const intl = useIntl();
// 搜索关键词
const [keyword, setKeyword] = useState<string>('');
@ -100,15 +102,15 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
setPersonnel(personnelData);
} else {
message.error(response?.message || '获取用户列表失败');
message.error(response?.message || intl.formatMessage({ id: 'supplierTaskManage.message.fetchUserListFailed' }));
}
} catch (error) {
console.error('获取人员数据失败:', error);
message.error('获取人员数据失败,请稍后重试');
message.error(intl.formatMessage({ id: 'supplierTaskManage.message.fetchPersonnelFailed' }));
} finally {
setLoading(false);
}
}, [keyword, pagination]); // 移除selectedPersonnelIds依赖
}, [keyword, pagination, filter, filterUserIds, intl]); // 添加intl依赖
/**
* 初始化人员数据
@ -153,12 +155,12 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
// 表格列定义
const columns = [
{
title: '姓名', // 列标题
dataIndex: 'name', // 数据字段名
key: 'name', // 列唯一标识
title: intl.formatMessage({ id: 'supplierTaskManage.column.name' }),
dataIndex: 'name',
key: 'name',
},
{
title: '部门',
title: intl.formatMessage({ id: 'supplierTaskManage.column.userDept' }),
dataIndex: 'userDept',
key: 'userDept',
}
@ -170,22 +172,20 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
<div className="selector-header">
<div className="search-bar">
<Search
placeholder="请输入姓名搜索"
placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.searchName' })}
onSearch={handleSearch}
enterButton={<Button icon={<SearchOutlined />}></Button>}
enterButton={<Button icon={<SearchOutlined />}>{intl.formatMessage({ id: 'supplierTaskManage.button.search' })}</Button>}
/>
</div>
<div className="selected-count">
: <span className="count">{selectedKeys.length}</span>
{intl.formatMessage({ id: 'supplierTaskManage.text.selectedCount' }, { count: selectedKeys.length })}
</div>
</div>
<Table
// 如果 isSelected = true 则禁用勾选
rowSelection={{
selectedRowKeys: selectedKeys,
onChange: handleSelectChange,
getCheckboxProps: (record) => ({
// 如果 isSelected = true 则禁用勾选
disabled: record.isSelected === true,
}),
}}
@ -199,9 +199,9 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
/>
<div className="selector-footer">
<Space>
<Button onClick={onCancel}></Button>
<Button onClick={onCancel}>{intl.formatMessage({ id: 'supplierTaskManage.button.close' })}</Button>
<Button type="primary" onClick={handleConfirm}>
{intl.formatMessage({ id: 'supplierTaskManage.button.confirm' })}
</Button>
</Space>
</div>

View File

@ -9,6 +9,7 @@ import {
Typography,
Tooltip,
} from 'antd';
import { useIntl } from 'umi';
import './ScoreEvaluationTable.less';
const { Text } = Typography;
@ -63,6 +64,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
isDetail = false,
loading = false,
}) => {
const intl = useIntl();
// 表格数据源
const [dataSource, setDataSource] = useState<TableRowItem[]>([]);
@ -196,10 +198,10 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
const columns = [
{
title: '一级指标',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.level1' }),
children: [
{
title: '序号',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.index' }),
dataIndex: 'index',
align: 'center' as const,
key: 'index',
@ -209,7 +211,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
},
},
{
title: '基本指标',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.baseIndicator' }),
align: 'center' as const,
dataIndex: 'baseIndicator',
key: 'baseIndicator',
@ -234,7 +236,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
},
},
{
title: '指标说明',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.indicatorDesc' }),
align: 'center' as const,
dataIndex: 'descIndicator',
key: 'descIndicator',
@ -259,7 +261,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
},
},
{
title: '分值',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.score' }),
align: 'center' as const,
dataIndex: 'stScore',
key: 'stScore',
@ -286,10 +288,10 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
],
},
{
title: '二级指标',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.level2' }),
children: [
{
title: '细分指标',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.subIndicator' }),
dataIndex: 'subIndicator',
key: 'subIndicator',
align: 'center' as const,
@ -297,7 +299,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
render: (text: string) => text || '-',
},
{
title: '分值',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.subScore' }),
dataIndex: 'ndScore',
key: 'ndScore',
width: 80,
@ -305,7 +307,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
render: (text: string) => text || '0',
},
{
title: '评分',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.actualScore' }),
dataIndex: 'score',
key: 'score',
width: 100,
@ -321,13 +323,13 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
value={text ? parseFloat(String(text)) : undefined}
onChange={(val) => handleInputChange(val, record, 'score')}
style={{ width: '100%' }}
placeholder="请输入评分"
placeholder={intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.placeholder.score' })}
/>
);
},
},
{
title: '评分说明',
title: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.remark' }),
dataIndex: 'remark',
key: 'remark',
width: 200,
@ -343,7 +345,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
<TextArea
value={text}
onChange={(e) => handleInputChange(e.target.value, record, 'remark')}
placeholder="请输入评分说明"
placeholder={intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.placeholder.remark' })}
autoSize={{ minRows: 1, maxRows: 3 }}
/>
);
@ -364,7 +366,7 @@ const ScoreEvaluationTable: React.FC<ScoreEvaluationTableProps> = ({
size="middle"
loading={loading}
scroll={{ x: 'max-content' }}
locale={{ emptyText: '无数据' }}
locale={{ emptyText: intl.formatMessage({ id: 'supplierEvaluateScore.scoreTable.emptyText' }) }}
/>
</div>
);

View File

@ -4,6 +4,7 @@ import { RightOutlined, LeftOutlined } from '@ant-design/icons';
import { getSupplierPage } from '@/servers/api/supplier';
import CategorySelector from '@/components/CategorySelector/CategorySelector';
import './SupplierSelector.less';
import { useIntl } from 'umi';
const { Option } = Select;
@ -56,6 +57,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
onSelect,
selectedSuppliers: initialSelectedSuppliers = [],
}) => {
const intl = useIntl();
// 表单实例,用于管理查询条件
const [form] = Form.useForm();
@ -159,14 +161,14 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
});
} else {
// 请求失败,显示错误信息
message.error(response?.message || '获取供应商列表失败');
message.error(response?.message || intl.formatMessage({ id: 'supplierTaskManage.message.fetchSupplierListFailed' }));
setTableListData([]);
setPagination({ current: 1, pageSize: 10, total: 0 });
}
} catch (error) {
// 处理异常情况
console.error('获取供应商列表出错:', error);
message.error('获取供应商列表失败,请稍后重试');
message.error(intl.formatMessage({ id: 'supplierTaskManage.message.fetchSupplierFailed' }));
setTableListData([]);
setPagination({ current: 1, pageSize: 10, total: 0 });
} finally {
@ -233,7 +235,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
// 表格列定义
const columns = [
{
title: '供应商名称',
title: intl.formatMessage({ id: 'supplierTaskManage.column.supplierName' }),
dataIndex: 'supplierName',
ellipsis: true,
render: (supplierName: string) => (
@ -243,7 +245,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
),
},
{
title: '统一社会信用代码',
title: intl.formatMessage({ id: 'supplierTaskManage.column.socialCreditCode' }),
dataIndex: 'socialCreditCode',
ellipsis: true,
render: (socialCreditCode: string) => (
@ -253,7 +255,7 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
),
},
{
title: '准入品类',
title: intl.formatMessage({ id: 'supplierTaskManage.column.categoryName' }),
dataIndex: 'categoryName',
ellipsis: true,
render: (categoryName: string) => (
@ -269,27 +271,27 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
<div className="supplier-selector">
{/* 查询表单 */}
<Form layout="inline" form={form} onFinish={handleSearch} style={{ marginBottom: 30 }}>
<Form.Item name="name" label="供应商名称">
<Input placeholder="供应商名称" allowClear />
<Form.Item name="name" label={intl.formatMessage({ id: 'supplierTaskManage.form.supplierName' })}>
<Input placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.supplierName' })} allowClear />
</Form.Item>
<Form.Item name="deptId" label="部门">
<Select placeholder="请选择部门" allowClear style={{ width: 150 }}>
<Option value="1"></Option>
<Option value="2"></Option>
<Option value="3"></Option>
<Form.Item name="deptId" label={intl.formatMessage({ id: 'supplierTaskManage.form.department' })}>
<Select placeholder={intl.formatMessage({ id: 'supplierTaskManage.placeholder.selectDepartment' })} allowClear style={{ width: 150 }}>
<Option value="1">{intl.formatMessage({ id: 'supplierTaskManage.department.purchase' })}</Option>
<Option value="2">{intl.formatMessage({ id: 'supplierTaskManage.department.technology' })}</Option>
<Option value="3">{intl.formatMessage({ id: 'supplierTaskManage.department.quality' })}</Option>
</Select>
</Form.Item>
<Form.Item name="categoryId" label="所属品类">
<Form.Item name="categoryId" label={intl.formatMessage({ id: 'supplierTaskManage.form.category' })}>
<CategorySelector multiple={false} style={{ width: 150 }} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit"></Button>
<Button type="primary" htmlType="submit">{intl.formatMessage({ id: 'supplierTaskManage.button.search' })}</Button>
</Form.Item>
<Form.Item>
<Button onClick={handleReset}></Button>
<Button onClick={handleReset}>{intl.formatMessage({ id: 'supplierTaskManage.button.reset' })}</Button>
</Form.Item>
</Form>
@ -298,8 +300,8 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
{/* 左侧待选列表 */}
<Col span={10}>
<div className="list-title">
<span className="search-count">{pagination.total}</span>
{intl.formatMessage({ id: 'supplierTaskManage.text.availableSuppliers' })}
<span className="search-count">{intl.formatMessage({ id: 'supplierTaskManage.text.itemCount' }, { count: pagination.total })}</span>
</div>
<Table
rowSelection={{
@ -334,8 +336,8 @@ const SupplierSelector: React.FC<SupplierSelectorProps> = ({
{/* 右侧已选列表 */}
<Col span={10}>
<div className="list-title">
<span className="search-count">{chosenSuppliers.length}</span>
{intl.formatMessage({ id: 'supplierTaskManage.text.selectedSuppliers' })}
<span className="search-count">{intl.formatMessage({ id: 'supplierTaskManage.text.itemCount' }, { count: chosenSuppliers.length })}</span>
</div>
<Table
rowSelection={{