翻译基于 key 而不是中文,方便以后其他语言扩展 (#1416)

This commit is contained in:
吴多益 2021-01-21 18:13:04 +08:00 committed by GitHub
parent 97a55e6bca
commit 2be472580b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 839 additions and 594 deletions

View File

@ -8,5 +8,13 @@
"bracketSpacing": false, "bracketSpacing": false,
"quoteProps": "consistent", "quoteProps": "consistent",
"arrowParens": "avoid", "arrowParens": "avoid",
"jsxBracketSameLine": false "jsxBracketSameLine": false,
"overrides": [
{
"files": "src/locale/*.ts",
"options": {
"printWidth": 800
}
}
]
} }

View File

@ -358,7 +358,7 @@ Action 行为按钮,是触发页面行为的主要方法之一
"title": "表单设置", "title": "表单设置",
"body": { "body": {
"type": "form", "type": "form",
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm?waitSeconds=1", "api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"controls": [ "controls": [
{ {
"type": "text", "type": "text",
@ -371,6 +371,49 @@ Action 行为按钮,是触发页面行为的主要方法之一
} }
``` ```
### 弹框结合 reload 刷新下拉框的例子
下面是一种典型场景,有个一个下拉框,然后有个按钮能弹框新增数据,新增了之后需要下拉框重新拉取最新列表(这个例子因为没实现新增功能,所以看不出更新,如果看网络请求会发现重新请求了一次)。
```schema: scope="body"
{
"type": "form",
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"name": "myForm",
"controls": [
{
"type": "select",
"name": "group",
"label": "分组",
"source": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/getOptions"
},
{
"label": "新增分组",
"type": "button",
"level": "primary",
"actionType": "dialog",
"reload": "myForm.group",
"dialog": {
"title": "新增分组",
"body": {
"type": "form",
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"controls": [
{
"type": "text",
"name": "groupName",
"label": "分组名"
}
]
}
}
}
]
}
```
可以看到 `reload``myForm.group`,第一个是表单的 name第二个是下拉框的 name。
**属性表** **属性表**
| 属性名 | 类型 | 默认值 | 说明 | | 属性名 | 类型 | 默认值 | 说明 |

View File

@ -66,7 +66,7 @@ order: 13
} }
``` ```
如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。 如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。
例如你调整值为`2020-04-14`这样的格式,查找 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知配置格式应为 `YYYY-MM-DD`,即: 例如你调整值为`2020-04-14`这样的格式,查找 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知配置格式应为 `YYYY-MM-DD`,即:

View File

@ -66,7 +66,7 @@ order: 14
} }
``` ```
如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。 如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。
例如你调整值为`2020-04-14 12:20:10`这样的格式,查找 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知配置格式应为 `YYYY-MM-DD HH:mm:ss`,即: 例如你调整值为`2020-04-14 12:20:10`这样的格式,查找 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知配置格式应为 `YYYY-MM-DD HH:mm:ss`,即:

View File

@ -163,6 +163,7 @@ order: 21
| hideUploadButton | `boolean` | `false` | 隐藏上传按钮 | | hideUploadButton | `boolean` | `false` | 隐藏上传按钮 |
| stateTextMap | object | `{ init: '', pending: '等待上传', uploading: '上传中', error: '上传出错', uploaded: '已上传', ready: '' }` | 上传状态文案 | | stateTextMap | object | `{ init: '', pending: '等待上传', uploading: '上传中', error: '上传出错', uploaded: '已上传', ready: '' }` | 上传状态文案 |
| fileField | `string` | `file` | 如果你不想自己存储,则可以忽略此属性。 | | fileField | `string` | `file` | 如果你不想自己存储,则可以忽略此属性。 |
| btnLabel | `string` | | 上传按钮的文字 |
| downloadUrl | `boolean`或`string` | `""` | 默认显示文件路径的时候会支持直接下载,可以支持加前缀如:`http://xx.dom/filename=` ,如果不希望这样,可以把当前配置项设置为 `false`。 | | downloadUrl | `boolean`或`string` | `""` | 默认显示文件路径的时候会支持直接下载,可以支持加前缀如:`http://xx.dom/filename=` ,如果不希望这样,可以把当前配置项设置为 `false`。 |
| useChunk | `boolean`或`"auto"` | `"auto"` | amis 所在服务器,限制了文件上传大小不得超出 10M所以 amis 在用户选择大文件的时候,自动会改成分块上传模式。 | | useChunk | `boolean`或`"auto"` | `"auto"` | amis 所在服务器,限制了文件上传大小不得超出 10M所以 amis 在用户选择大文件的时候,自动会改成分块上传模式。 |
| chunkSize | `number` | `5 * 1024 * 1024` | 分块大小 | | chunkSize | `number` | `5 * 1024 * 1024` | 分块大小 |

View File

@ -63,6 +63,29 @@ order: 27
想要限制多个类型,则用逗号分隔,例如:`.jpg,.png` 想要限制多个类型,则用逗号分隔,例如:`.jpg,.png`
## 限制文件大小
配置 `limit`,更多属性请参考后面的属性说明。
```schema: scope="body"
{
"type": "form",
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"controls": [
{
"type": "image",
"name": "image",
"label": "限制只能上传宽度大于 1000 的图片",
"accept": ".jpg",
"limit": {
"minWidth": 1000
},
"reciever": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/upload/file"
}
]
}
```
## 支持裁剪 ## 支持裁剪
```schema: scope="body" ```schema: scope="body"

View File

@ -66,7 +66,7 @@ order: 81
} }
``` ```
如果你想要其他格式的月份值,那么可以配置`format`参数用于调整表单项的值格式。 如果你想要其他格式的月份值,那么可以配置`format`参数用于调整表单项的值格式。
例如你调整值为`01`这样的格式,查找 moment 文档可知配置格式应为 `MM`,即: 例如你调整值为`01`这样的格式,查找 moment 文档可知配置格式应为 `MM`,即:

View File

@ -66,7 +66,7 @@ order: 58
} }
``` ```
如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。 如果你想要其他格式的日期值,那么可以配置`format`参数用于调整表单项的值格式。
例如你调整值为`01:11`这样的格式,查找 moment 文档可知配置格式应为 `HH:mm`,即: 例如你调整值为`01:11`这样的格式,查找 moment 文档可知配置格式应为 `HH:mm`,即:

View File

@ -87,7 +87,7 @@ import 'amis/lib/locale/en-US';
## 扩展内置组件的语言 ## 扩展内置组件的语言
如果想扩展其他语言,首先参考 `https://github.com/baidu/amis/blob/master/src/locale/en.ts` 文件,了解需要翻译哪些文字,以中文为 key然后参考后面的示例注册新语言,未翻译的文字都将使用默认语言,即中文。 如果想扩展其他语言,首先参考 `https://github.com/baidu/amis/blob/master/src/locale/en-US.ts` 文件,然后参考后面的示例注册新语言,未翻译的文字都将使用中文。
> 目前这种方式将会在未来修改,为了支持更多语言而不再使用中文为 key > 目前这种方式将会在未来修改,为了支持更多语言而不再使用中文为 key
@ -96,7 +96,7 @@ import 'amis/lib/locale/en-US';
```javascript ```javascript
let amisLib = amisRequire('amis'); let amisLib = amisRequire('amis');
amisLib.registerLocale('jp', { amisLib.registerLocale('jp', {
提交: '送信' 'Form.submit': '送信'
}); });
``` ```
@ -105,6 +105,6 @@ amisLib.registerLocale('jp', {
```javascript ```javascript
import {registerLocale} from 'amis'; import {registerLocale} from 'amis';
registerLocale('jp', { registerLocale('jp', {
提交: '送信' 'Form.submit': '送信'
}); });
``` ```

View File

@ -1078,6 +1078,8 @@
--Switch-onDisabled-color: #fff; --Switch-onDisabled-color: #fff;
--Switch-valueColor: var(--white); --Switch-valueColor: var(--white);
--Switch-width: #{px2rem(50px)}; --Switch-width: #{px2rem(50px)};
--Switch-label: '';
--Switch-checked-label: '';
--Table--unsaved-heading-bg: #e8f0fe; --Table--unsaved-heading-bg: #e8f0fe;
--Table--unsaved-heading-color: #4285f4; --Table--unsaved-heading-color: #4285f4;

View File

@ -17,7 +17,7 @@
i { i {
&:before { &:before {
content: '\5173'; content: var(--Switch-label);
color: var(--Switch-valueColor); color: var(--Switch-valueColor);
text-indent: calc(var(--Switch-width) / 2); text-indent: calc(var(--Switch-width) / 2);
text-transform: uppercase; text-transform: uppercase;
@ -81,7 +81,7 @@
&:after { &:after {
margin-left: calc(var(--Switch-width) - var(--Switch-height)); margin-left: calc(var(--Switch-width) - var(--Switch-height));
content: '\5f00'; content: var(--Switch-checked-label);
color: var(--white); color: var(--white);
text-indent: px2rem(-18px); // todo text-indent: px2rem(-18px); // todo
text-transform: uppercase; text-transform: uppercase;

View File

@ -66,9 +66,9 @@ export class Alert extends React.Component<AlertProps, AlertState> {
} }
static defaultProps = { static defaultProps = {
confirmText: '确认', confirmText: 'confirm',
cancelText: '取消', cancelText: 'cancel',
title: '系统消息', title: 'Alert.info',
alertBtnLevel: 'primary', alertBtnLevel: 'primary',
confirmBtnLevel: 'danger' confirmBtnLevel: 'danger'
}; };
@ -147,8 +147,8 @@ export class Alert extends React.Component<AlertProps, AlertState> {
prompt( prompt(
controls: any, controls: any,
defaultValue?: any, defaultValue?: any,
title: string = '请输入', title: string = 'placeholder.enter',
confirmText: string = '确认' confirmText: string = 'confirm'
) { ) {
if (typeof controls === 'string') { if (typeof controls === 'string') {
// 兼容浏览器标准用法。 // 兼容浏览器标准用法。

View File

@ -32,7 +32,7 @@ export interface ArrayInputProps extends ThemeProps, LocaleProps {
export class ArrayInput extends React.Component<ArrayInputProps> { export class ArrayInput extends React.Component<ArrayInputProps> {
static defaultProps = { static defaultProps = {
placeholder: '<空>', placeholder: 'empty',
itemRender: ({ itemRender: ({
value, value,
onChange onChange
@ -210,7 +210,7 @@ export class ArrayInput extends React.Component<ArrayInputProps> {
disabled={disabled} disabled={disabled}
> >
<Icon icon="plus" className="icon" /> <Icon icon="plus" className="icon" />
<span>{__('新增一条')}</span> <span>{__('Combo.add')}</span>
</Button> </Button>
) : null} ) : null}

View File

@ -160,9 +160,9 @@ export class AssociatedCheckboxes extends BaseCheckboxes<
</div> </div>
{selectdOption.loading ? ( {selectdOption.loading ? (
<p>{__('加载中')}</p> <p>{__('loading')}</p>
) : ( ) : (
<p>{__('点击刷新重新加载')}</p> <p>{__('Transfer.refreshIcon')}</p>
)} )}
</div> </div>
) : rightMode === 'table' ? ( ) : rightMode === 'table' ? (
@ -202,12 +202,12 @@ export class AssociatedCheckboxes extends BaseCheckboxes<
) )
) : ( ) : (
<div className={cx('AssociatedCheckboxes-box')}> <div className={cx('AssociatedCheckboxes-box')}>
{__('配置错误,选项无法与左侧选项对应')} {__('Transfer.configError')}
</div> </div>
) )
) : ( ) : (
<div className={cx('AssociatedCheckboxes-box')}> <div className={cx('AssociatedCheckboxes-box')}>
{__('请先选择左侧数据')} {__('Transfer.selectFromLeft')}
</div> </div>
)} )}
</div> </div>

View File

@ -37,7 +37,7 @@ export class BaseCheckboxes<
S = any S = any
> extends React.Component<T, S> { > extends React.Component<T, S> {
static defaultProps = { static defaultProps = {
placeholder: '暂无选项', placeholder: 'placeholder.noOption',
itemRender: (option: Option) => <span>{option.label}</span> itemRender: (option: Option) => <span>{option.label}</span>
}; };

View File

@ -45,7 +45,7 @@ export class ColorControl extends React.PureComponent<
static defaultProps = { static defaultProps = {
format: 'hex', format: 'hex',
clearable: true, clearable: true,
placeholder: '请选择颜色', placeholder: 'ColorPicker.placeholder',
allowCustomColor: true allowCustomColor: true
// closeOnSelect: true // closeOnSelect: true
}; };

View File

@ -19,76 +19,76 @@ import {localeable, LocaleProps, TranslateFn} from '../locale';
const availableShortcuts: {[propName: string]: any} = { const availableShortcuts: {[propName: string]: any} = {
now: { now: {
label: '现在', label: 'Date.now',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now; return now;
} }
}, },
today: { today: {
label: '今天', label: 'Date.today',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('day'); return now.startOf('day');
} }
}, },
yesterday: { yesterday: {
label: '昨天', label: 'Date.yesterday',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(-1, 'days').startOf('day'); return now.add(-1, 'days').startOf('day');
} }
}, },
thisweek: { thisweek: {
label: '本周一', label: 'Date.monday',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('week').startOf('day'); return now.startOf('week').startOf('day');
} }
}, },
thismonth: { thismonth: {
label: '本月初', label: 'Date.startOfMonth',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('month'); return now.startOf('month');
} }
}, },
prevmonth: { prevmonth: {
label: '上个月初', label: 'Date.startOfLastMonth',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('month').add(-1, 'month'); return now.startOf('month').add(-1, 'month');
} }
}, },
prevquarter: { prevquarter: {
label: '上个季节初', label: 'Date.startOfLastQuarter',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('quarter').add(-1, 'quarter'); return now.startOf('quarter').add(-1, 'quarter');
} }
}, },
thisquarter: { thisquarter: {
label: '本季度初', label: 'Date.startOfQuarter',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.startOf('quarter'); return now.startOf('quarter');
} }
}, },
tomorrow: { tomorrow: {
label: '明天', label: 'Date.tomorrow',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(1, 'days').startOf('day'); return now.add(1, 'days').startOf('day');
} }
}, },
endofthisweek: { endofthisweek: {
label: '本周日', label: 'Date.endOfWeek',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.endOf('week'); return now.endOf('week');
} }
}, },
endofthismonth: { endofthismonth: {
label: '本月底', label: 'Date.endOfMonth',
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.endOf('month'); return now.endOf('month');
} }
@ -100,7 +100,7 @@ const advancedShortcuts = [
regexp: /^(\d+)hoursago$/, regexp: /^(\d+)hoursago$/,
resolve: (__: TranslateFn, _: string, hours: string) => { resolve: (__: TranslateFn, _: string, hours: string) => {
return { return {
label: __('{{hours}}小时前', {hours}), label: __('Date.hoursago', {hours}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.subtract(hours, 'hours'); return now.subtract(hours, 'hours');
} }
@ -111,7 +111,7 @@ const advancedShortcuts = [
regexp: /^(\d+)hourslater$/, regexp: /^(\d+)hourslater$/,
resolve: (__: TranslateFn, _: string, hours: string) => { resolve: (__: TranslateFn, _: string, hours: string) => {
return { return {
label: __('{{hours}}小时后', {hours}), label: __('Date.hourslater', {hours}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(hours, 'hours'); return now.add(hours, 'hours');
} }
@ -122,7 +122,7 @@ const advancedShortcuts = [
regexp: /^(\d+)daysago$/, regexp: /^(\d+)daysago$/,
resolve: (__: TranslateFn, _: string, days: string) => { resolve: (__: TranslateFn, _: string, days: string) => {
return { return {
label: __('{{days}}天前', {days}), label: __('Date.daysago', {days}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.subtract(days, 'days'); return now.subtract(days, 'days');
} }
@ -133,7 +133,7 @@ const advancedShortcuts = [
regexp: /^(\d+)dayslater$/, regexp: /^(\d+)dayslater$/,
resolve: (__: TranslateFn, _: string, days: string) => { resolve: (__: TranslateFn, _: string, days: string) => {
return { return {
label: __('{{days}}天后', {days}), label: __('Date.dayslater', {days}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(days, 'days'); return now.add(days, 'days');
} }
@ -144,7 +144,7 @@ const advancedShortcuts = [
regexp: /^(\d+)weeksago$/, regexp: /^(\d+)weeksago$/,
resolve: (__: TranslateFn, _: string, weeks: string) => { resolve: (__: TranslateFn, _: string, weeks: string) => {
return { return {
label: __('{{weeks}}周前', {weeks}), label: __('Date.weeksago', {weeks}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.subtract(weeks, 'weeks'); return now.subtract(weeks, 'weeks');
} }
@ -155,7 +155,7 @@ const advancedShortcuts = [
regexp: /^(\d+)weekslater$/, regexp: /^(\d+)weekslater$/,
resolve: (__: TranslateFn, _: string, weeks: string) => { resolve: (__: TranslateFn, _: string, weeks: string) => {
return { return {
label: __('{{weeks}}周后', {weeks}), label: __('Date.weekslater', {weeks}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(weeks, 'weeks'); return now.add(weeks, 'weeks');
} }
@ -166,7 +166,7 @@ const advancedShortcuts = [
regexp: /^(\d+)monthsago$/, regexp: /^(\d+)monthsago$/,
resolve: (__: TranslateFn, _: string, months: string) => { resolve: (__: TranslateFn, _: string, months: string) => {
return { return {
label: __('{{months}}月前', {months}), label: __('Date.monthsago', {months}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.subtract(months, 'months'); return now.subtract(months, 'months');
} }
@ -177,7 +177,7 @@ const advancedShortcuts = [
regexp: /^(\d+)monthslater$/, regexp: /^(\d+)monthslater$/,
resolve: (__: TranslateFn, _: string, months: string) => { resolve: (__: TranslateFn, _: string, months: string) => {
return { return {
label: __('{{months}}月后', {months}), label: __('Date.monthslater', {months}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(months, 'months'); return now.add(months, 'months');
} }
@ -188,7 +188,7 @@ const advancedShortcuts = [
regexp: /^(\d+)quartersago$/, regexp: /^(\d+)quartersago$/,
resolve: (__: TranslateFn, _: string, quarters: string) => { resolve: (__: TranslateFn, _: string, quarters: string) => {
return { return {
label: __('{{quarters}}季度前', {quarters}), label: __('Date.quartersago', {quarters}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.subtract(quarters, 'quarters'); return now.subtract(quarters, 'quarters');
} }
@ -199,7 +199,7 @@ const advancedShortcuts = [
regexp: /^(\d+)quarterslater$/, regexp: /^(\d+)quarterslater$/,
resolve: (__: TranslateFn, _: string, quarters: string) => { resolve: (__: TranslateFn, _: string, quarters: string) => {
return { return {
label: __('{{quarters}}季度后', {quarters}), label: __('Date.quarterslater', {quarters}),
date: (now: moment.Moment) => { date: (now: moment.Moment) => {
return now.add(quarters, 'quarters'); return now.add(quarters, 'quarters');
} }

View File

@ -53,7 +53,7 @@ export interface DateRangePickerState {
const availableRanges: {[propName: string]: any} = { const availableRanges: {[propName: string]: any} = {
'today': { 'today': {
label: '今天', label: 'Date.today',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('day'); return now.startOf('day');
}, },
@ -63,7 +63,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'yesterday': { 'yesterday': {
label: '昨天', label: 'Date.yesterday',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.add(-1, 'days').startOf('day'); return now.add(-1, 'days').startOf('day');
}, },
@ -73,7 +73,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'1dayago': { '1dayago': {
label: '最近1天', label: 'DateRange.lastDay',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.add(-1, 'days'); return now.add(-1, 'days');
}, },
@ -83,7 +83,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'7daysago': { '7daysago': {
label: '最近7天', label: 'DateRange.last7Days',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.add(-7, 'days').startOf('day'); return now.add(-7, 'days').startOf('day');
}, },
@ -93,7 +93,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'90daysago': { '90daysago': {
label: '最近90天', label: 'DateRange.last90Days',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.add(-90, 'days').startOf('day'); return now.add(-90, 'days').startOf('day');
}, },
@ -103,7 +103,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'prevweek': { 'prevweek': {
label: '上周', label: 'DateRange.lastWeek',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('week').add(-1, 'weeks'); return now.startOf('week').add(-1, 'weeks');
}, },
@ -113,7 +113,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'thismonth': { 'thismonth': {
label: '本月', label: 'DateRange.thisMonth',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('month'); return now.startOf('month');
}, },
@ -123,7 +123,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'prevmonth': { 'prevmonth': {
label: '上个月', label: 'DateRange.lastMonth',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('month').add(-1, 'month'); return now.startOf('month').add(-1, 'month');
}, },
@ -133,7 +133,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'prevquarter': { 'prevquarter': {
label: '上个季度', label: 'DateRange.lastQuarter',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('quarter').add(-1, 'quarter'); return now.startOf('quarter').add(-1, 'quarter');
}, },
@ -143,7 +143,7 @@ const availableRanges: {[propName: string]: any} = {
}, },
'thisquarter': { 'thisquarter': {
label: '本季度', label: 'DateRange.thisQuarter',
startDate: (now: moment.Moment) => { startDate: (now: moment.Moment) => {
return now.startOf('quarter'); return now.startOf('quarter');
}, },
@ -158,7 +158,7 @@ export class DateRangePicker extends React.Component<
DateRangePickerState DateRangePickerState
> { > {
static defaultProps = { static defaultProps = {
placeholder: '请选择日期范围', placeholder: 'DateRange.placeholder',
format: 'X', format: 'X',
inputFormat: 'YYYY-MM-DD', inputFormat: 'YYYY-MM-DD',
joinValues: true, joinValues: true,
@ -577,8 +577,7 @@ export class DateRangePicker extends React.Component<
embed embed
} = this.props; } = this.props;
const __ = this.props.translate; const __ = this.props.translate;
let viewMode: 'days' | 'months' | 'years' | 'months' | 'days' | 'time' = let viewMode: 'days' | 'months' | 'years' | 'time' = 'days';
'days';
const {startDate, endDate} = this.state; const {startDate, endDate} = this.state;
return ( return (
@ -625,10 +624,10 @@ export class DateRangePicker extends React.Component<
})} })}
onClick={this.confirm} onClick={this.confirm}
> >
{__('确认')} {__('confirm')}
</a> </a>
<a className="rdtBtn rdtBtnCancel" onClick={this.close}> <a className="rdtBtn rdtBtnCancel" onClick={this.close}>
{__('取消')} {__('cancle')}
</a> </a>
</div> </div>
)} )}
@ -707,7 +706,7 @@ export class DateRangePicker extends React.Component<
> >
{arr.length ? ( {arr.length ? (
<span className={`${ns}DateRangePicker-value`}> <span className={`${ns}DateRangePicker-value`}>
{arr.join(__(''))} {arr.join(__('DateRange.valueConcat'))}
</span> </span>
) : ( ) : (
<span className={`${ns}DateRangePicker-placeholder`}> <span className={`${ns}DateRangePicker-placeholder`}>

View File

@ -103,7 +103,7 @@ export class ImageGallery extends React.Component<
container={modalContainer} container={modalContainer}
> >
<a <a
data-tooltip={__('关闭')} data-tooltip={__('Dialog.close')}
data-position="left" data-position="left"
className={cx('ImageGallery-close')} className={cx('ImageGallery-close')}
onClick={this.close} onClick={this.close}

View File

@ -22,7 +22,7 @@ interface RenderResult {
export class ListMenu extends React.Component<ListMenuProps> { export class ListMenu extends React.Component<ListMenuProps> {
static defaultProps = { static defaultProps = {
placeholder: '暂无选项', placeholder: 'placeholder.noOption',
itemRender: (option: Option) => <>{option.label}</>, itemRender: (option: Option) => <>{option.label}</>,
getItemProps: (props: {item: Option; index: number}) => null getItemProps: (props: {item: Option; index: number}) => null
}; };

View File

@ -31,7 +31,7 @@ export class BaseRadios<
selected: Option | undefined | null; selected: Option | undefined | null;
static defaultProps = { static defaultProps = {
placeholder: '暂无选项', placeholder: 'placeholder.noOption',
itemRender: (option: Option) => <span>{option.label}</span> itemRender: (option: Option) => <span>{option.label}</span>
}; };
static resolveSelected( static resolveSelected(

View File

@ -35,7 +35,7 @@ export class LocationPicker extends React.Component<
LocationState LocationState
> { > {
static defaultProps = { static defaultProps = {
placeholder: '请选择位置', placeholder: 'LocationPicker.placeholder',
clearable: false clearable: false
}; };
domRef: React.RefObject<HTMLDivElement> = React.createRef(); domRef: React.RefObject<HTMLDivElement> = React.createRef();

View File

@ -65,7 +65,7 @@ export class Modal extends React.Component<ModalProps, ModalState> {
<div {...rest} className={cx('Modal-header', className)}> <div {...rest} className={cx('Modal-header', className)}>
{showCloseButton !== false ? ( {showCloseButton !== false ? (
<a <a
data-tooltip={__('关闭弹窗')} data-tooltip={__('Dialog.close')}
data-position="left" data-position="left"
onClick={onClose} onClick={onClose}
className={cx('Modal-close')} className={cx('Modal-close')}

View File

@ -26,8 +26,8 @@ export class ResultBox extends React.Component<ResultBoxProps> {
'clearable' | 'placeholder' | 'itemRender' | 'inputPlaceholder' 'clearable' | 'placeholder' | 'itemRender' | 'inputPlaceholder'
> = { > = {
clearable: false, clearable: false,
placeholder: '暂无结果', placeholder: 'placeholder.noData',
inputPlaceholder: '手动输入内容', inputPlaceholder: 'placeholder.enter',
itemRender: (option: any) => ( itemRender: (option: any) => (
<span>{`${option.scopeLabel || ''}${option.label}`}</span> <span>{`${option.scopeLabel || ''}${option.label}`}</span>
) )
@ -150,7 +150,7 @@ export class ResultBox extends React.Component<ResultBoxProps> {
<span className={cx('ResultBox-singleValue')}>{result}</span> <span className={cx('ResultBox-singleValue')}>{result}</span>
) : allowInput && !disabled ? null : ( ) : allowInput && !disabled ? null : (
<span className={cx('ResultBox-placeholder')}> <span className={cx('ResultBox-placeholder')}>
{__(placeholder || '')} {__(placeholder || 'placeholder.noData')}
</span> </span>
)} )}
@ -176,12 +176,7 @@ export class ResultBox extends React.Component<ResultBoxProps> {
{clearable && {clearable &&
!disabled && !disabled &&
(Array.isArray(result) ? result.length : result) ? ( (Array.isArray(result) ? result.length : result) ? (
<a <a onClick={this.clearValue} className={cx('ResultBox-clear')}>
// data-tooltip="清空"
// data-position="bottom"
onClick={this.clearValue}
className={cx('ResultBox-clear')}
>
<Icon icon="close" className="icon" /> <Icon icon="close" className="icon" />
</a> </a>
) : null} ) : null}

View File

@ -24,7 +24,7 @@ export interface ResultListProps extends ThemeProps, LocaleProps {
export class ResultList extends React.Component<ResultListProps> { export class ResultList extends React.Component<ResultListProps> {
static defaultProps: Pick<ResultListProps, 'placeholder' | 'itemRender'> = { static defaultProps: Pick<ResultListProps, 'placeholder' | 'itemRender'> = {
placeholder: '请先选择数据', placeholder: 'placeholder.selectData',
itemRender: (option: any) => ( itemRender: (option: any) => (
<span>{`${option.scopeLabel || ''}${option.label}`}</span> <span>{`${option.scopeLabel || ''}${option.label}`}</span>
) )

View File

@ -107,7 +107,7 @@ export class SearchBox extends React.Component<SearchBoxProps> {
disabled={disabled} disabled={disabled}
onChange={this.handleChange} onChange={this.handleChange}
value={value || ''} value={value || ''}
placeholder={__(placeholder || '输入关键字')} placeholder={__(placeholder || 'placeholder.enter')}
ref={this.inputRef} ref={this.inputRef}
autoComplete="off" autoComplete="off"
onKeyDown={this.handleKeyDown} onKeyDown={this.handleKeyDown}

View File

@ -354,20 +354,20 @@ export class Select extends React.Component<SelectProps, SelectState> {
multiple: false, multiple: false,
clearable: true, clearable: true,
creatable: false, creatable: false,
createBtnLabel: '新增选项', createBtnLabel: 'Select.createLabel',
searchPromptText: '输入内容进行检索', searchPromptText: 'Select.searchPromptText',
loadingPlaceholder: '加载中..', loadingPlaceholder: 'loading',
noResultsText: '未找到任何结果', noResultsText: 'noResult',
clearAllText: '移除所有', clearAllText: 'Select.clearAll',
clearValueText: '移除', clearValueText: 'Select.clear',
placeholder: '请选择', placeholder: 'Select.placeholder',
valueField: 'value', valueField: 'value',
labelField: 'label', labelField: 'label',
resetValue: '', resetValue: '',
inline: false, inline: false,
disabled: false, disabled: false,
checkAll: false, checkAll: false,
checkAllLabel: '全选', checkAllLabel: 'Select.checkAll',
defaultCheckAll: false, defaultCheckAll: false,
overlayPlacement: 'auto' overlayPlacement: 'auto'
}; };
@ -814,7 +814,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
})} })}
> >
{removable ? ( {removable ? (
<a data-tooltip="移除" data-position="left"> <a data-tooltip={__('Select.clear')} data-position="left">
<Icon <Icon
icon="minus" icon="minus"
className="icon" className="icon"

View File

@ -31,8 +31,8 @@ export interface TabsTransferProps
export class TabsTransfer extends React.Component<TabsTransferProps> { export class TabsTransfer extends React.Component<TabsTransferProps> {
static defaultProps = { static defaultProps = {
selectTitle: '请选择', selectTitle: 'Select.placeholder',
resultTitle: '当前选择', resultTitle: 'Transfer.selectd',
itemRender: (option: Option) => <span>{option.label}</span> itemRender: (option: Option) => <span>{option.label}</span>
}; };
@ -115,7 +115,7 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
if (!Array.isArray(options) || !options.length) { if (!Array.isArray(options) || !options.length) {
return ( return (
<div className={cx('TabsTransfer-placeholder')}> <div className={cx('TabsTransfer-placeholder')}>
{__(placeholder || '暂无选项')} {__(placeholder || 'placeholder.noOption')}
</div> </div>
); );
} }
@ -136,7 +136,7 @@ export class TabsTransfer extends React.Component<TabsTransferProps> {
> >
{searchResult !== null {searchResult !== null
? [ ? [
<Tab title={__('搜索结果')} key={0} eventKey={0}> <Tab title={__('searchResult')} key={0} eventKey={0}>
{this.renderSearchResult(searchResult)} {this.renderSearchResult(searchResult)}
</Tab> </Tab>
] ]

View File

@ -79,8 +79,8 @@ export interface TransferState {
export class Transfer extends React.Component<TransferProps, TransferState> { export class Transfer extends React.Component<TransferProps, TransferState> {
static defaultProps = { static defaultProps = {
selectTitle: '请选择', selectTitle: 'Select.placeholder',
resultTitle: '当前选择', resultTitle: 'Transfer.selectd',
itemRender: (option: Option) => <span>{option.label}</span> itemRender: (option: Option) => <span>{option.label}</span>
}; };
@ -238,7 +238,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
disabled || !options.length ? 'is-disabled' : '' disabled || !options.length ? 'is-disabled' : ''
)} )}
> >
{__('全选')} {__('Select.placeholder')}
</a> </a>
) : null} ) : null}
</div> </div>
@ -248,7 +248,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
<InputBox <InputBox
value={this.state.inputValue} value={this.state.inputValue}
onChange={this.handleSearch} onChange={this.handleSearch}
placeholder={__('请输入关键字')} placeholder={__('Transfer.searchKeyword')}
clearable={false} clearable={false}
onKeyDown={this.handleSearchKeyDown} onKeyDown={this.handleSearchKeyDown}
> >
@ -463,7 +463,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
disabled || !this.valueArray.length ? 'is-disabled' : '' disabled || !this.valueArray.length ? 'is-disabled' : ''
)} )}
> >
{__('清空')} {__('clear')}
</a> </a>
</div> </div>
<ResultList <ResultList
@ -472,7 +472,7 @@ export class Transfer extends React.Component<TransferProps, TransferState> {
disabled={disabled} disabled={disabled}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder={__('请先选择左侧数据')} placeholder={__('Transfer.selectFromLeft')}
/> />
</div> </div>
</div> </div>

View File

@ -118,14 +118,14 @@ export class TreeSelector extends React.Component<
extractValue: false, extractValue: false,
delimiter: ',', delimiter: ',',
hideRoot: true, hideRoot: true,
rootLabel: '顶级', rootLabel: 'Tree.root',
rootValue: 0, rootValue: 0,
cascade: false, cascade: false,
selfDisabledAffectChildren: true, selfDisabledAffectChildren: true,
rootCreateTip: '添加一级节点', rootCreateTip: 'Tree.addRoot',
createTip: '添加子节点', createTip: 'Tree.addChild',
editTip: '编辑该节点', editTip: 'Tree.editNode',
removeTip: '移除该节点' removeTip: 'Tree.removeNode'
}; };
componentWillMount() { componentWillMount() {
@ -436,12 +436,12 @@ export class TreeSelector extends React.Component<
<input <input
onChange={this.handleInputChange} onChange={this.handleInputChange}
value={inputValue} value={inputValue}
placeholder={__('请输入')} placeholder={__('placeholder.enter')}
/> />
<a data-tooltip={__('取消')} onClick={this.handleCancel}> <a data-tooltip={__('cancle')} onClick={this.handleCancel}>
<Icon icon="close" className="icon" /> <Icon icon="close" className="icon" />
</a> </a>
<a data-tooltip={__('确认')} onClick={this.handleConfirm}> <a data-tooltip={__('confirm')} onClick={this.handleConfirm}>
<Icon icon="check" className="icon" /> <Icon icon="check" className="icon" />
</a> </a>
</div> </div>

View File

@ -180,10 +180,10 @@ export class CustomDaysView extends DaysView {
{this.props.requiredConfirm ? ( {this.props.requiredConfirm ? (
<div key="button" className="rdtActions"> <div key="button" className="rdtActions">
<a className="rdtBtn rdtBtnConfirm" onClick={this.confirm}> <a className="rdtBtn rdtBtnConfirm" onClick={this.confirm}>
{__('确认')} {__('confirm')}
</a> </a>
<a className="rdtBtn rdtBtnCancel" onClick={this.cancel}> <a className="rdtBtn rdtBtnCancel" onClick={this.cancel}>
{__('取消')} {__('cancle')}
</a> </a>
</div> </div>
) : null} ) : null}
@ -219,7 +219,7 @@ export class CustomDaysView extends DaysView {
<div className="rdtCenter"> <div className="rdtCenter">
<a className="rdtSwitch" onClick={this.props.showView('years')}> <a className="rdtSwitch" onClick={this.props.showView('years')}>
{date.format(__('YYYY年'))} {date.format(__('dateformat.year'))}
</a> </a>
<a <a
className="rdtSwitch" className="rdtSwitch"

View File

@ -62,11 +62,11 @@ export class CustomMonthsView extends MonthsView {
className="rdtSwitch" className="rdtSwitch"
onClick={this.props.showView('years')} onClick={this.props.showView('years')}
> >
{this.props.viewDate.format(__('YYYY年'))} {this.props.viewDate.format(__('dateformat.year'))}
</th> </th>
) : ( ) : (
<th className="rdtSwitch"> <th className="rdtSwitch">
{this.props.viewDate.format(__('YYYY年'))} {this.props.viewDate.format(__('dateformat.year'))}
</th> </th>
)} )}

View File

@ -49,11 +49,11 @@ export class QuarterView extends React.Component<QuarterViewProps> {
</th> </th>
{canClick ? ( {canClick ? (
<th className="rdtSwitch" onClick={this.props.showView('years')}> <th className="rdtSwitch" onClick={this.props.showView('years')}>
{this.props.viewDate.format(__('YYYY年'))} {this.props.viewDate.format(__('dateformat.year'))}
</th> </th>
) : ( ) : (
<th className="rdtSwitch"> <th className="rdtSwitch">
{this.props.viewDate.format(__('YYYY年'))} {this.props.viewDate.format(__('dateformat.year'))}
</th> </th>
)} )}

View File

@ -44,7 +44,7 @@ export class CustomYearsView extends YearsView {
« «
</th> </th>
<th className="rdtSwitch"> <th className="rdtSwitch">
{__('{{from}}年-{{to}}年', {from: year, to: year + 9})} {__('year-to-year', {from: year, to: year + 9})}
</th> </th>
<th className="rdtNext" onClick={this.props.addTime(10, 'years')}> <th className="rdtNext" onClick={this.props.addTime(10, 'years')}>
» »

View File

@ -6,8 +6,9 @@ import NumberInput from '../NumberInput';
import DatePicker from '../DatePicker'; import DatePicker from '../DatePicker';
import Select from '../Select'; import Select from '../Select';
import Switch from '../Switch'; import Switch from '../Switch';
import {LocaleProps} from '../../locale';
export interface ValueProps extends ThemeProps { export interface ValueProps extends ThemeProps, LocaleProps {
value: any; value: any;
onChange: (value: any) => void; onChange: (value: any) => void;
field: FieldSimple; field: FieldSimple;
@ -16,7 +17,14 @@ export interface ValueProps extends ThemeProps {
export class Value extends React.Component<ValueProps> { export class Value extends React.Component<ValueProps> {
render() { render() {
const {classnames: cx, field, value, onChange, op} = this.props; const {
classnames: cx,
field,
value,
onChange,
op,
translate: __
} = this.props;
let input: JSX.Element | undefined = undefined; let input: JSX.Element | undefined = undefined;
if (field.type === 'text') { if (field.type === 'text') {
@ -30,7 +38,7 @@ export class Value extends React.Component<ValueProps> {
} else if (field.type === 'number') { } else if (field.type === 'number') {
input = ( input = (
<NumberInput <NumberInput
placeholder={field.placeholder || '请输入数字'} placeholder={field.placeholder || __('NumberInput.placeholder')}
min={field.minimum} min={field.minimum}
max={field.maximum} max={field.maximum}
value={value ?? field.defaultValue} value={value ?? field.defaultValue}
@ -40,7 +48,7 @@ export class Value extends React.Component<ValueProps> {
} else if (field.type === 'date') { } else if (field.type === 'date') {
input = ( input = (
<DatePicker <DatePicker
placeholder={field.placeholder || '请选择日期'} placeholder={field.placeholder || __('Date.placeholder')}
format={field.format || 'YYYY-MM-DD'} format={field.format || 'YYYY-MM-DD'}
inputFormat={field.inputFormat || 'YYYY-MM-DD'} inputFormat={field.inputFormat || 'YYYY-MM-DD'}
value={value ?? field.defaultValue} value={value ?? field.defaultValue}
@ -52,7 +60,7 @@ export class Value extends React.Component<ValueProps> {
input = ( input = (
<DatePicker <DatePicker
viewMode="time" viewMode="time"
placeholder={field.placeholder || '请选择时间'} placeholder={field.placeholder || 'Time.placeholder'}
format={field.format || 'HH:mm'} format={field.format || 'HH:mm'}
inputFormat={field.inputFormat || 'HH:mm'} inputFormat={field.inputFormat || 'HH:mm'}
value={value ?? field.defaultValue} value={value ?? field.defaultValue}

View File

@ -36,6 +36,9 @@ import {
makeTranslator, makeTranslator,
register as registerLocale register as registerLocale
} from './locale'; } from './locale';
import 'locale/zh-CN';
import animation from './utils/Animation'; import animation from './utils/Animation';
export * from './Schema'; export * from './Schema';

View File

@ -1,212 +1,196 @@
import {register} from '../locale'; import {register} from '../locale';
register('en-US', { register('en-US', {
'确认': 'Confirm', 'Alert.info': 'System Info',
'取消': 'Cancel', 'asc': 'Asc',
'YYYY年': 'YYYY', 'cancel': 'Cancel',
'{{from}}年-{{to}}年': '{{from}} - {{to}}', 'Card.dragTip': 'Drag top button to sort',
'请选择日期': 'Select Date', 'Card.toggleDrag': 'Toggle drag to sort',
'请选择日期以及时间': 'Select Datetime', 'City.street': 'Enter street info',
'请选择时间': 'Select Time', 'clear': 'Clear',
'系统消息': 'System Info', 'ColorPicker.placeholder': 'Select color',
'加载中': 'Loading', 'Combo.add': 'New',
'点击刷新重新加载': 'Click to refresh', 'Combo.dragDropSort': 'Drag to sort',
'请先选择左侧数据': 'Select from left first.', 'Combo.invalidData': 'invalid data, please remove',
'请选择颜色': 'Select color', 'Combo.maxLength': 'Maximum item ia {{MaxLength}}}. Please delete some',
'现在': 'Now', 'Combo.minLength': 'A least {{minLength}} item. Please add more',
'今天': 'Today', 'Combo.type': 'Type',
'昨天': 'Yesterday', 'confirm': 'Confirm',
'本周一': 'Monday', 'Copyable.tip': 'Copy',
'本月初': 'Earlier this month', 'CRUD.exportCSV': 'Export CSV',
'上个月初': 'Earlier last month', 'CRUD.exportExcel': 'Export Excel',
'上个季节初': 'Earlier last quarter', 'CRUD.fetchFailed': 'Fetch failed',
'明天': 'Tomorrow', 'CRUD.filter': 'Filter',
'本周日': 'Sunday', 'CRUD.invalidArray': 'data.items must be an array',
'本月底': 'last day of this month', 'CRUD.invalidData': 'data is empty',
'{{hours}}小时前': '{{hours}} hour(s) ago', 'CRUD.loadMore': 'Load more',
'{{hours}}小时后': '{{hours}} hour(s) after', 'CRUD.perPage': 'Per page',
'{{days}}天前': '{{days}} day(s) ago', 'CRUD.stat': '{{page}} of {{lastPage}} total: {{total}}.',
'{{days}}天后': '{{days}} day(s) after', 'Date.daysago': '{{days}} day(s) ago',
'{{weeks}}周前': '{{weeks}} week(s) ago', 'Date.dayslater': '{{days}} day(s) later',
'{{weeks}}周后': '{{weeks}} week(s) after', 'Date.endOfMonth': 'last day of the month',
'{{months}}月前': '{{months}} month(s) ago', 'Date.endOfWeek': 'Saturday',
'{{months}}月后': '{{months}} month(s) after', 'Date.hoursago': '{{hours}} hour(s) ago',
'{{quarters}}季度前': '{{quarters}} quarter(s) ago', 'Date.hourslater': '{{hours}} hour(s) later',
'{{quarters}}季度后': '{{quarters}} quarter(s) after', 'Date.invalid': 'Invalid date',
' 至 ': ' to ', 'Date.monday': 'Monday',
'最近1天': 'Last day', 'Date.monthsago': '{{months}} month(s) ago',
'最近7天': 'Last 7 days', 'Date.monthslater': '{{months}} month(s) later',
'最近90天': 'Last 90 days', 'Date.now': 'Now',
'上周': 'Last week', 'Date.placeholder': 'Select Date',
'本月': 'This month', 'Date.quartersago': '{{quarters}} quarter(s) ago',
'上个月': 'Last month', 'Date.quarterslater': '{{quarters}} quarter(s) later',
'上个季节': 'Last quarter', 'Date.startOfLastMonth': 'First day of the last month',
'本季度': 'This quarter', 'Date.startOfLastQuarter': 'First day of the last quarter',
'请选择日期范围': 'Select Daterange', 'Date.startOfMonth': 'First day of the month',
'关闭': 'Close', 'Date.startOfQuarter': 'First day of the quarter',
'暂无选项': 'No options', 'Date.today': 'Today',
'请选择位置': 'Pick location', 'Date.tomorrow': 'Tomorrow',
'无': 'None', 'Date.weeksago': '{{weeks}} week(s) ago',
'没有数据': 'No data', 'Date.weekslater': '{{weeks}} week(s) later',
'请先选择数据': 'Select data first', 'Date.yesterday': 'Yesterday',
'请选择': 'Select', 'dateformat.year': 'YYYY',
'全选': 'Check all', 'DateRange.last7Days': 'Last 7 days',
'搜索结果': 'Search result', 'DateRange.last90Days': 'Last 90 days',
'清空': 'Clear', 'DateRange.lastDay': 'Last day',
'当前选择': 'Selected', 'DateRange.lastMonth': 'Last month',
'添加一级节点': 'Add root node', 'DateRange.lastQuarter': 'Last quarter',
'添加子节点': 'Add child', 'DateRange.lastWeek': 'Last week',
'编辑该节点': 'Edit this node', 'DateRange.placeholder': 'Select a Date range',
'移除该节点': 'Remove this node', 'DateRange.thisMonth': 'This month',
'请输入': 'Enter', 'DateRange.thisQuarter': 'This quarter',
'请输入关键字': 'Enter keywords', 'DateRange.valueConcat': ' to ',
'新增选项': 'New option', 'DateTime.placeholder': 'Select Datetime',
'请输入街道信息': 'Enter street info', 'delete': 'Delete',
'删除': 'Delete', 'deleteConfirm': 'Are your sure to delete?',
'新增': 'New', 'deleteFailed': 'Delete failed',
'新增一条': 'Add a data', 'desc': 'Desc',
'新增一条数据': 'Add a data', 'Dialog.close': 'Close',
'类型': 'Type', 'fetchFailed': 'Fetch api failed',
'拖拽排序': 'Drag to sort', 'File.continueAdd': 'Continue add',
'删除失败': 'Delete failed', 'File.dragDrop': `Drag 'n' drop some files here`,
'确认要删除?': 'Are you sure you want to delete?', 'File.errorRetry': 'File upload failed, please try again',
'组合表单成员数量不够,低于设定的最小{{minLength}}个,请添加更多的成员。': 'File.failed': 'Failed files.',
'The number of combined form members is not enough. It is lower than the minimum {{minLength}} set. Please add more members.', 'File.invalidType': '{{files}} does not match type `{{accept}}`',
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。': 'File.maxSize': '{{filename}} you selected exceeds the maximum limit of {{maxsize}} (in bytes)',
'The number of combined form members exceeds the set maximum of {{MaxLength}}}. Please delete the extra members.', 'File.pause': 'Pause uplaod',
'子表单验证失败,请仔细检查': 'Validate failed, please check this Subform.', 'File.repick': 'Repick',
'成员{{index}}': 'Member {{index}}', 'File.result': 'Successfully uploaded {{uploaded}} files, failed to upload {{failed}} files',
'清空数据': 'Clear data', 'File.retry': 'Retry',
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。': 'File.start': 'Start upload',
'The file {{filename}} you selected has a size of {actualsize}} which exceeds the maximum limit of {{maxsize}}. Please select again.', 'File.upload': 'Upload',
'File.uploadFailed': 'return data of udpload api is empty',
'您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。': 'File.uploading': 'Uploading',
'The file you added {{files}} does not match the setting of the type `{{accept}}`. Please check it carefully.', 'Form.loadOptionsFailed': 'Failed to load options because: {{reason}}',
'把文件拖到这,然后松完成添加!': 'Form.submit': 'Submit',
'Drag the file here, then release to finish adding!', 'Form.title': 'Form',
'把图片拖到这,然后松开完成添加!': 'Form.unique': 'Current value is not unique',
'Drag the picture here, then release to finish adding!', 'Form.validateFailed': 'Form input validation failed',
'重新上传': 'Repick', 'Image.configError': 'Can only set one of crop or multiple',
'重试上传': 'Retry', 'Image.crop': 'Crop image',
'继续添加': 'Continue add', 'Image.dragDrop': `Drag 'n' drop some photos here`,
'上传文件': 'Upload file', 'Image.height': 'height: {{height}}px',
'移除': 'Remove', 'Image.limitMax': 'Minimum image size is {{info}}',
'暂停上传': 'Pause uplaod', 'Image.limitMin': 'Maximum image size is {{info}}',
'开始上传': 'Start upload', 'Image.limitRatio': 'Please upload image with the size ratio of {{ration}}',
'已成功上传{{uploaded}}个文件,{{failed}}个文件上传失败,': 'Image.pasteTip': 'You can paste image from the clipboard',
'Successfully uploaded {{uploaded}} files, failed to upload {{failed}} files,', 'Image.placeholder': 'Click to select image or drag into this area',
'失败文件': 'Failed files.', 'Image.size': 'size: ({{width}}px x {{height}}px)',
'高度{{height}}px': 'height: {{height}}px', 'Image.sizeNotEqual': 'The image you selected does not meet the size requirements {{info}}',
'宽度{{width}}px': 'width: {{width}}px', 'Image.width': 'width: {{width}}px',
'尺寸({{width}} x {{height}}': 'size: ({{width}}px x {{height}}px)', 'Image.zoomIn': 'Zoom In',
'您选择的图片不符合尺寸要求, 请上传{{info}}的图片': 'link': 'Link',
'The picture you selected does not meet the size requirements. Please upload the picture of {{info}}', 'loading': 'Loading',
'您选择的图片不符合尺寸要求, 请上传不要超过{{info}}的图片': 'LocationPicker.placeholder': 'Pick location',
'The picture you selected does not meet the size requirements. Please upload a picture that does not exceed {{info}}`.', 'Month.placeholder': 'Select a month',
'您选择的图片不符合尺寸要求, 请上传不要小于{{info}}的图片': 'Nav.sourceError': 'Fetch link error',
'The picture you selected does not meet the size requirements. Please upload a picture no less than {{info}}', 'networkError': 'Network error or missing CORS configuration',
'您选择的图片不符合尺寸要求, 请上传尺寸比率为 {{ratio}} 的图片': 'noResult': 'No Result',
'The picture you selected does not meet the size requirements. Please upload the picture with the size ratio of ${ration}', 'NumberInput.placeholder': 'Please enter a number',
'文件上传失败请重试': 'File upload failed, please try again', 'Options.addPlaceholder': 'Please enter a name',
'文件上传中': 'File uploading', 'Options.deleteAPI': 'Must have deleteAPI',
'查看大图': 'Zoom In', 'Options.editLabel': 'Edit {{label}}',
'裁剪图片': 'Crop picture', 'Options.label': 'option',
'当前状态支持从剪切板中粘贴图片文件。': 'placeholder.empty': '<Empty>',
'The current state supports pasting picture files from the clipboard.', 'placeholder.enter': 'Enter',
'表单': 'Form', 'placeholder.noData': 'No data',
'提交': 'Submit', 'placeholder.noOption': 'No option',
'初始化失败': 'Initialization failed', 'placeholder.selectData': 'Select data',
'保存成功': 'Saved successfully', 'Quarter.placeholder': 'Select a quarter',
'保存失败': 'Save failed', 'Repeat.pre': 'Per',
'依赖的部分字段没有通过验证,请注意填写!': 'reset': 'Reset',
'Some of the dependent fields failed to pass the verification, please fill in!', 'saveFailed': 'Save failed',
'请输入名称': 'Please enter a name', 'saveSuccess': 'Saved successfully',
'编辑{{label}}': 'Edit {{label}}', 'search': 'Search',
'每': 'Per', 'searchResult': 'Search result',
'编辑详情': 'Detail', 'Select.checkAll': 'Check all',
'删除当前行': 'Delete current row', 'Select.clear': 'Clear',
'操作': 'Operation', 'Select.clearAll': 'Clear all',
'新增一行': 'Add a row', 'Select.createLabel': 'New option',
'暂无标签': 'No tag yet', 'Select.placeholder': 'Select',
'新增:{{label}}': 'New {{label}}', 'Select.searchPromptText': 'Input to search',
'顶级': 'Root', 'sort': 'Sort',
'点击复制': 'Copy', 'SubForm.button': 'Config',
'{{page}}/{{lastPage}} 总共:{{total}} 项。': 'SubForm.editDetail': 'Edit Detail',
'{{page}} of {{lastPage}} total: {{total}}.', 'Table.addRow': 'Add a row',
'每页显示': 'Per page', 'Table.columnsVisibility': 'Click to control columns visibility',
'加载更多': 'Load more', 'Table.deleteRow': 'Delete current row',
'筛选': 'Filter', 'Table.discard': 'Discard',
'搜索': 'Search', 'Table.dragTip': 'Drag the button on the left to sort',
'日期无效': 'Invalid date', 'Table.editing': 'You should finished editing',
'关闭弹窗': 'Close', 'Table.editRow': 'Edit current row',
'链接': 'Link', 'Table.modified': 'There are {{modified}} records have been modified, you can:',
'当前有 {{modified}} 条记录修改了内容, 但并没有提交。请选择:': 'Table.moved': 'There are {{moved}} records changed the order, you can:',
'There are currently {{modified}} records that have modified the contents, but they have not been submitted. Please select:', 'Table.operation': 'Operation',
'放弃': 'Give up', 'Table.playload': 'Must have playload',
'当前有 {{moved}} 条记录修改了顺序, 但并没有提交。请选择:': 'Table.startSort': 'Click to start sorting',
'There are currently {{moved}} records that have changed the order, but have not been committed. Please select:', 'Table.valueField': 'Must have valueField',
'点击开始排序': 'Click to start sorting', 'Tag.placeholder': 'No tag yet',
'点击选择显示列': 'Click to select columns to display', 'Tag.tip': 'Recently used tag',
'请拖动左边的按钮进行排序': 'Please drag the button on the left to sort', 'Text.add': 'New {{label}}',
'排序': 'Sort', 'Time.placeholder': 'Select Time',
'正序': 'Asc', 'Transfer.configError': 'Config error',
'降序': 'Desc', 'Transfer.refreshIcon': 'Click to refresh',
'返回数据格式不正确payload.data 没有数据': 'Transfer.searchKeyword': 'Enter keywords',
'The return data format is incorrect, nothing is in `payload.data`', 'Transfer.selectd': 'Selected',
'获取失败': 'Fetch failed', 'Transfer.selectFromLeft': 'Select from the left',
'返回数据格式不正确payload.data.items 必须是数组': 'Tree.addChild': 'Add child',
'The return data format is incorrect, payload.data.items Must be an array', 'Tree.addRoot': 'Add root node',
'验证错误': 'Validate failed', 'Tree.editNode': 'Edit this node',
'表单验证失败,请仔细检查': 'Form validation failed, please check carefully', 'Tree.removeNode': 'Remove this node',
'验证失败': 'Validate failed', 'Tree.root': 'Root',
'当前值不唯一': 'Current value is not unique', 'validate.equals': 'value must be $1',
'加载选项失败,原因:{{reason}}': 'validate.equalsField': 'value must be $1',
'Failed to load options because: {{reason}}', 'validate.gt': 'Please enter a value greater than $1',
'获取失败,请重试': 'Fetch failed, please try again', 'validate.isAlpha': 'Please enter letters',
'请仔细检查表单规则,部分表单项没通过验证': 'validate.isAlphanumeric': 'Please enter letters or numbers',
'Please check the form rules carefully. Some form items fail to pass the verification', 'validate.isEmail': 'Email format is incorrect',
'Email 格式不正确': 'Email format is incorrect', 'validate.isFloat': 'Please enter a floating point value',
'这是必填项': 'This is required', 'validate.isId': 'invalid ID Card number',
'Url 格式不正确': 'Incorrect URL format', 'validate.isInt': 'Please enter an integer number',
'请输入整型数字': 'Please enter an integer number', 'validate.isJson': 'invalid JSON format.',
'请输入字母': 'Please enter letters', 'validate.isLength': 'Please make sure the length of contents is $1',
'请输入数字': 'Please enter a number', 'validate.isNumeric': 'Please enter a number',
'请输入字母或者数字': 'Please enter letters or numbers', 'validate.isPhoneNumber': 'invalid phone number',
'请输入浮点型数值': 'Please enter a floating point value', 'validate.isRequired': 'This is required',
'只能输入字母、数字、`-` 和 `_`.': 'validate.isTelNumber': 'invalid telephone number',
'You can only enter letters, numbers, `-` and`_` .', 'validate.isUrl': 'Incorrect URL format',
'格式不正确, 请输入符合规则为 `${1|raw}` 的内容。': 'validate.isUrlPath': 'You can only enter letters, numbers, `-` and`_` .',
'The format is not correct. Please enter the content with the rule `${1| raw}`.', 'validate.isWords': 'Please enter word',
'请输入更多的内容,至少输入 $1 个字符。': 'validate.isZipcode': 'invalid postal address',
'Please enter more, at least $1 characters.', 'validate.lt': 'Please enter a value less than $1',
'请控制内容长度, 不要输入 $1 个字符以上': 'validate.matchRegexp': 'The format is not correct. Please enter the content with the rule `${1| raw}`.',
'Please control the content length, do not enter more than $1 characters', 'validate.maximum': 'The input value exceeds the maximum value of $1',
'当前输入值超出最大值 $1请检查': 'validate.maxLength': 'Please control the content length, do not enter more than $1 letters',
'The current input value exceeds the maximum value of $1, please check', 'validate.minimum': 'The input value is lower than the minimum value of $1',
'请输入小于 $1 的值': 'Please enter a value less than $1', 'validate.minLength': 'Please enter more, at least $1 characters.',
'当前输入值低于最小值 $1请检查': 'validate.notEmptyString': 'Please do not enter all blank characters',
'The current input value is lower than the minimum value of $1, please check', 'validateFailed': 'Validate failed,',
'请输入大于 $1 的值': 'Please enter a value greater than $1', 'Wizard.configError': 'Config error',
'请检查 Json 格式。': 'Please check the JSON format.', 'Wizard.finish': 'Finish',
'请输入长度为 $1 的内容': 'Wizard.next': 'Next',
'Please enter make sure the length of contents is $1', 'Wizard.prev': 'Prev',
'请不要全输入空白字符': 'Please do not enter all blank characters', 'Wizard.saveAndNext': 'Save & Next',
'输入的数据与 $1 值不一致': 'year-to-year': '{{from}} - {{to}}',
'The entered data is inconsistent with the value of $1', 'Year.placeholder': 'Select a Year'
'输入的数据与 $1 不一致': 'The entered data is inconsistent with $1',
'请输入合法的手机号码': 'Please enter a valid mobile phone number',
'请输入合法的电话号码': 'Please enter a valid phone number',
'请输入合法的邮编地址': 'Please enter a legal postal address',
'请输入合法的身份证号': 'Please enter a valid ID number',
'系统错误': 'System Error',
'<空>': '<Empty>',
'可拖拽排序': 'Drag and drop sorting',
'上一步': 'Prev',
'下一步': 'Next',
'导出 CSV': 'Export CSV',
'保存并下一步': 'Save & Next',
'完成': 'Finish',
'点击选择图片或者将图片拖入该区域':
'Click to select the picture or drag the picture into the area',
'重置': 'Reset'
}); });

196
src/locale/zh-CN.ts Normal file
View File

@ -0,0 +1,196 @@
import {register} from '../locale';
register('zh-CN', {
'Alert.info': '系统消息',
'asc': '正序',
'cancel': '取消',
'Card.dragTip': '请拖动顶部的按钮进行排序',
'Card.toggleDrag': '对卡片进行排序操作',
'City.street': '请输入街道信息',
'clear': '清空',
'ColorPicker.placeholder': '请选择颜色',
'Combo.add': '新增',
'Combo.dragDropSort': '拖拽排序',
'Combo.invalidData': '数据非法,或者数据已失效,请移除',
'Combo.maxLength': '组合表单超出{{maxLength}}个,请删除',
'Combo.minLength': '组合表单数量不足{{minLength}}个,请添加更多',
'Combo.type': '类型',
'confirm': '确认',
'Copyable.tip': '点击复制',
'CRUD.exportCSV': '导出 CSV',
'CRUD.exportExcel': '导出 Excel',
'CRUD.fetchFailed': '获取失败',
'CRUD.filter': '筛选',
'CRUD.invalidArray': 'data.items 必须是数组',
'CRUD.invalidData': '返回数据格式不正确data 没有数据',
'CRUD.loadMore': '加载更多',
'CRUD.perPage': '每页显示',
'CRUD.stat': '{{page}}/{{lastPage}} 总共:{{total}} 项',
'Date.daysago': '{{days}}天前',
'Date.dayslater': '{{days}}天后',
'Date.endOfMonth': '本月最后一天',
'Date.endOfWeek': '周日',
'Date.hoursago': '{{hours}}小时前',
'Date.hourslater': '{{hours}}小时后',
'Date.invalid': '日期无效',
'Date.monday': '本周一',
'Date.monthsago': '{{months}}月前',
'Date.monthslater': '{{months}}月后',
'Date.now': '现在',
'Date.placeholder': '请选择日期',
'Date.quartersago': '{{quarters}}季度前',
'Date.quarterslater': '{{quarters}}季度后',
'Date.startOfLastMonth': '上个月第一天',
'Date.startOfLastQuarter': '上个季度第一天',
'Date.startOfMonth': '本月第一天',
'Date.startOfQuarter': '本季度第一天',
'Date.today': '今天',
'Date.tomorrow': '明天',
'Date.weeksago': '{{weeks}}周前',
'Date.weekslater': '{{weeks}}周后',
'Date.yesterday': '昨天',
'dateformat.year': 'YYYY年',
'DateRange.last7Days': '最近7天',
'DateRange.last90Days': '最近90天',
'DateRange.lastDay': '最近1天',
'DateRange.lastMonth': '上个月',
'DateRange.lastQuarter': '上个季度',
'DateRange.lastWeek': '上周',
'DateRange.placeholder': '请选择日期范围',
'DateRange.thisMonth': '这个月',
'DateRange.thisQuarter': '这个季度',
'DateRange.valueConcat': ' 至 ',
'DateTime.placeholder': '请选择日期以及时间',
'delete': '删除',
'deleteConfirm': '确认要删除?',
'deleteFailed': '删除失败',
'desc': '降序',
'Dialog.close': '关闭',
'fetchFailed': '初始化失败',
'File.continueAdd': '继续添加',
'File.dragDrop': '将文件拖拽到此处',
'File.errorRetry': '文件上传失败请重试',
'File.failed': '失败文件',
'File.invalidType': '{{files}} 不符合类型的 {{accept}} 的设定,请仔细检查',
'File.maxSize': '{{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} (字节)的限制',
'File.pause': '暂停上传',
'File.repick': '重新选择',
'File.result': '已成功上传 {{uploaded}} 个文件,{{failed}} 个文件上传失败,',
'File.retry': '重试上传',
'File.start': '开始上传',
'File.upload': '上传文件',
'File.uploadFailed': '接口返回错误,请仔细检查',
'File.uploading': '文件上传中',
'Form.loadOptionsFailed': '加载选项失败,原因:{{reason}}',
'Form.submit': '提交',
'Form.title': '表单',
'Form.unique': '当前值不唯一',
'Form.validateFailed': '依赖的部分字段没有通过验证',
'Image.configError': '图片多选配置和裁剪配置只能设置一个',
'Image.crop': '裁剪图片',
'Image.dragDrop': '将图片拖拽到此处',
'Image.height': '高度 {{height}}px',
'Image.limitRatio': '请上传尺寸比率为 {{ratio}} 的图片',
'Image.pasteTip': '可以粘贴剪切板中的图片',
'Image.placeholder': '点击选择图片或拖拽图片到这里',
'Image.size': '尺寸({{width}} x {{height}}',
'Image.sizeMax': '请上传不要大于{{info}}的图片',
'Image.sizeMin': '请上传不要小于{{info}}的图片',
'Image.sizeNotEqual': '请上传{{info}}的图片',
'Image.width': '宽度 {{width}}px',
'Image.zoomIn': '查看大图',
'link': '链接',
'loading': '加载中',
'LocationPicker.placeholder': '请选择位置',
'Month.placeholder': '请选择月份',
'Nav.sourceError': '获取链接错误',
'networkError': '网络错误,可能是未配置跨域 CORS',
'noResult': '未找到任何结果',
'NumberInput.placeholder': '请输入数字',
'Options.addPlaceholder': '请输入名称',
'Options.deleteAPI': '必须设置 deleteAPI',
'Options.editLabel': '编辑{{label}}',
'Options.label': '选项',
'placeholder.empty': '<空>',
'placeholder.enter': '请输入',
'placeholder.noData': '暂无数据',
'placeholder.noOption': '暂无选项',
'placeholder.selectData': '请先选择数据',
'Quarter.placeholder': '请选择季度',
'Repeat.pre': '每',
'reset': '重置',
'saveFailed': '保存失败',
'saveSuccess': '保存成功',
'search': '搜索',
'searchResult': '搜索结果',
'Select.checkAll': '全选',
'Select.clear': '移除',
'Select.clearAll': '移除所有',
'Select.createLabel': '新增选项',
'Select.placeholder': '请选择',
'Select.searchPromptText': '输入内容进行检索',
'sort': '排序',
'SubForm.button': '设置',
'SubForm.editDetail': '编辑详情',
'Table.addRow': '新增一行',
'Table.columnsVisibility': '点击选择显示列',
'Table.deleteRow': '删除当前行',
'Table.discard': '放弃',
'Table.dragTip': '请拖动左边的按钮进行排序',
'Table.editing': '请先处理表格编辑项',
'Table.editRow': '编辑当前行',
'Table.modified': '当前有 {{modified}} 条记录修改但没有提交,你可以:',
'Table.moved': '当前有 {{moved}} 条记录修改了顺序但没有提交,你可以:',
'Table.operation': '操作',
'Table.playload': 'action 上请配置 payload, 否则不清楚要删除哪个',
'Table.startSort': '点击开始排序',
'Table.valueField': '请配置 valueField',
'Tag.placeholder': '暂无标签',
'Tag.tip': '最近使用的标签',
'Text.add': '新增:{{label}}}',
'Time.placeholder': '请选择时间',
'Transfer.configError': '配置错误,选项无法与左侧选项对应',
'Transfer.refreshIcon': '点击刷新重新加载',
'Transfer.searchKeyword': '请输入关键字',
'Transfer.selectd': '当前选择',
'Transfer.selectFromLeft': '请从左侧选择数据',
'Tree.addChild': '添加子节点',
'Tree.addRoot': '添加一级节点',
'Tree.editNode': '编辑该节点',
'Tree.removeNode': '移除该节点',
'Tree.root': '顶级',
'validate.equals': '输入的数据与 $1 不一致',
'validate.equalsField': '输入的数据与 $1 值不一致',
'validate.gt': '请输入大于 $1 的值',
'validate.isAlpha': '请输入字母',
'validate.isAlphanumeric': '请输入字母或者数字',
'validate.isEmail': 'Email 格式不正确',
'validate.isFloat': '请输入浮点型数值',
'validate.isId': '请输入合法的身份证号',
'validate.isInt': '请输入整型数字',
'validate.isJson': 'JSON 格式不正确',
'validate.isLength': '请输入长度为 $1 的内容',
'validate.isNumeric': '请输入数字',
'validate.isPhoneNumber': '请输入合法的手机号码',
'validate.isRequired': '这是必填项',
'validate.isTelNumber': '请输入合法的电话号码',
'validate.isUrl': 'URL 格式不正确',
'validate.isUrlPath': '只能输入字母、数字、`-` 和 `_`.',
'validate.isWords': '请输入单词',
'validate.isZipcode': '请输入合法的邮编地址',
'validate.lt': '请输入小于 $1 的值',
'validate.matchRegexp': '格式不正确, 请输入符合规则为 `${1|raw}` 的内容。',
'validate.maximum': '当前输入值超出最大值 $1',
'validate.maxLength': '请控制内容长度, 不要输入 $1 个以上字符',
'validate.minimum': '当前输入值低于最小值 $1',
'validate.minLength': '请输入更多的内容,至少输入 $1 个字符。',
'validate.notEmptyString': '请不要全输入空白字符',
'validateFailed': '表单验证失败',
'Wizard.configError': '配置错误',
'Wizard.finish': '完成',
'Wizard.next': '下一步',
'Wizard.prev': '上一步',
'Wizard.saveAndNext': '保存并下一步',
'year-to-year': '{{from}} 年 - {{to}} 年',
'Year.placeholder': '请选择年'
});

View File

@ -1612,7 +1612,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
return ( return (
<div className={cx('Crud-statistics')}> <div className={cx('Crud-statistics')}>
{__('{{page}}/{{lastPage}} 总共:{{total}} 项。', { {__('CRUD.stat', {
page: store.page, page: store.page,
lastPage: store.lastPage, lastPage: store.lastPage,
total: store.total total: store.total
@ -1645,11 +1645,11 @@ export default class CRUD extends React.Component<CRUDProps, any> {
return ( return (
<div className={cx('Crud-pageSwitch')}> <div className={cx('Crud-pageSwitch')}>
{__('每页显示')} {__('CRUD.perPage')}
<Select <Select
classPrefix={ns} classPrefix={ns}
searchable={false} searchable={false}
placeholder={__('请选择')} placeholder={__('Select.placeholder')}
options={perPages} options={perPages}
value={store.perPage + ''} value={store.perPage + ''}
onChange={(value: any) => this.handleChangePage(1, value.value)} onChange={(value: any) => this.handleChangePage(1, value.value)}
@ -1672,7 +1672,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
} }
size="sm" size="sm"
> >
{__('加载更多')} {__('CRUD.loadMore')}
</Button> </Button>
</div> </div>
) : ( ) : (
@ -1695,7 +1695,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
})} })}
> >
<Icon icon="filter" className="icon m-r-xs" /> <Icon icon="filter" className="icon m-r-xs" />
{__('筛选')} {__('CRUD.filter')}
</button> </button>
); );
} }
@ -1719,7 +1719,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
}} }}
size="sm" size="sm"
> >
{__('导出 CSV')} {__('CRUD.exportCSV')}
</Button> </Button>
); );
} }
@ -1893,7 +1893,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
{store.selectedItems.map((item, index) => ( {store.selectedItems.map((item, index) => (
<div key={index} className={cx(`Crud-value`)}> <div key={index} className={cx(`Crud-value`)}>
<span <span
data-tooltip={__('删除')} data-tooltip={__('delete')}
data-position="bottom" data-position="bottom"
className={cx('Crud-valueIcon')} className={cx('Crud-valueIcon')}
onClick={this.unSelectItem.bind(this, item, index)} onClick={this.unSelectItem.bind(this, item, index)}
@ -1911,7 +1911,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
</div> </div>
))} ))}
<a onClick={this.clearSelection} className={cx('Crud-selectionClear')}> <a onClick={this.clearSelection} className={cx('Crud-selectionClear')}>
{__('清空')} {__('clear')}
</a> </a>
</div> </div>
); );
@ -1954,9 +1954,9 @@ export default class CRUD extends React.Component<CRUDProps, any> {
? render( ? render(
'filter', 'filter',
{ {
title: __('条件过滤'), title: __('CRUD.filter'),
mode: 'inline', mode: 'inline',
submitText: __('搜索'), submitText: __('search'),
...filter, ...filter,
type: 'form', type: 'form',
api: null api: null

View File

@ -179,7 +179,7 @@ export default class Cards extends React.Component<GridProps, object> {
]; ];
static defaultProps: Partial<GridProps> = { static defaultProps: Partial<GridProps> = {
className: '', className: '',
placeholder: '没有数据', placeholder: 'placeholder.noData',
source: '$items', source: '$items',
selectable: false, selectable: false,
headerClassName: '', headerClassName: '',
@ -706,7 +706,7 @@ export default class Cards extends React.Component<GridProps, object> {
{child} {child}
{store.dragging ? ( {store.dragging ? (
<div className={cx('Cards-dragTip')} ref={this.dragTipRef}> <div className={cx('Cards-dragTip')} ref={this.dragTipRef}>
{__('请拖动顶部的按钮进行排序')} {__('Card.dragTip')}
</div> </div>
) : null} ) : null}
</div> </div>
@ -804,7 +804,7 @@ export default class Cards extends React.Component<GridProps, object> {
<Button <Button
iconOnly iconOnly
key="dragging-toggle" key="dragging-toggle"
tooltip={__('对卡片进行排序操作')} tooltip={__('Card.toggleDrag')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }

View File

@ -65,7 +65,7 @@ export const HocCopyable = () => (Component: React.ComponentType<any>): any => {
<Component {...this.props} wrapperComponent={''} noHoc /> <Component {...this.props} wrapperComponent={''} noHoc />
<a <a
key="edit-btn" key="edit-btn"
data-tooltip={__('点击复制')} data-tooltip={__('Copyable.tip')}
className={cx('Field-copyBtn')} className={cx('Field-copyBtn')}
onClick={this.handleClick.bind(this, content)} onClick={this.handleClick.bind(this, content)}
> >

View File

@ -117,7 +117,7 @@ export class DateField extends React.Component<DateProps, DateState> {
} }
viewValue = !viewValue ? ( viewValue = !viewValue ? (
<span className="text-danger">{__('日期无效')}</span> <span className="text-danger">{__('Date.invalid')}</span>
) : ( ) : (
viewValue viewValue
); );

View File

@ -192,14 +192,14 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
ret.push({ ret.push({
type: 'button', type: 'button',
actionType: 'cancel', actionType: 'cancel',
label: __('取消') label: __('cancle')
}); });
if (confirm) { if (confirm) {
ret.push({ ret.push({
type: 'button', type: 'button',
actionType: 'confirm', actionType: 'confirm',
label: __('确认'), label: __('confirm'),
primary: true primary: true
}); });
} }
@ -477,7 +477,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
<div className={cx('Modal-header', headerClassName)}> <div className={cx('Modal-header', headerClassName)}>
{showCloseButton !== false && !store.loading ? ( {showCloseButton !== false && !store.loading ? (
<a <a
data-tooltip={__('关闭')} data-tooltip={__('Dialog.close')}
data-position="left" data-position="left"
onClick={this.handleSelfClose} onClick={this.handleSelfClose}
className={cx('Modal-close')} className={cx('Modal-close')}
@ -493,7 +493,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
<div className={cx('Modal-header', headerClassName)}> <div className={cx('Modal-header', headerClassName)}>
{showCloseButton !== false && !store.loading ? ( {showCloseButton !== false && !store.loading ? (
<a <a
data-tooltip={__('关闭')} data-tooltip={__('Dialog.close')}
onClick={this.handleSelfClose} onClick={this.handleSelfClose}
className={cx('Modal-close')} className={cx('Modal-close')}
> >
@ -506,7 +506,7 @@ export default class Dialog extends React.Component<DialogProps, DialogState> {
</div> </div>
) : showCloseButton !== false && !store.loading ? ( ) : showCloseButton !== false && !store.loading ? (
<a <a
data-tooltip={__('关闭')} data-tooltip={__('Dialog.close')}
onClick={this.handleSelfClose} onClick={this.handleSelfClose}
className={cx('Modal-close')} className={cx('Modal-close')}
> >

View File

@ -203,14 +203,14 @@ export default class Drawer extends React.Component<DrawerProps, object> {
ret.push({ ret.push({
type: 'button', type: 'button',
actionType: 'close', actionType: 'close',
label: __('取消') label: __('cancle')
}); });
if (confirm) { if (confirm) {
ret.push({ ret.push({
type: 'button', type: 'button',
actionType: 'confirm', actionType: 'confirm',
label: __('确认'), label: __('confirm'),
primary: true primary: true
}); });
} }

View File

@ -57,9 +57,9 @@ export default class CheckboxesControl extends React.Component<
static defaultProps = { static defaultProps = {
columnsCount: 1, columnsCount: 1,
multiple: true, multiple: true,
placeholder: '暂无选项', placeholder: 'placeholder.noOption',
creatable: false, creatable: false,
createBtnLabel: '新增选项' createBtnLabel: 'Select.createLabel'
}; };
componentDidMount() { componentDidMount() {
@ -141,7 +141,8 @@ export default class CheckboxesControl extends React.Component<
labelClassName, labelClassName,
labelField, labelField,
removable, removable,
editable editable,
translate: __
} = this.props; } = this.props;
return ( return (
@ -157,7 +158,7 @@ export default class CheckboxesControl extends React.Component<
> >
{String(option[labelField || 'label'])} {String(option[labelField || 'label'])}
{removable ? ( {removable ? (
<a data-tooltip="移除" data-position="left"> <a data-tooltip={__('Select.clear')} data-position="left">
<Icon <Icon
icon="minus" icon="minus"
className="icon" className="icon"

View File

@ -400,7 +400,7 @@ export class CityPicker extends React.Component<
value={street} value={street}
onChange={this.handleStreetChange} onChange={this.handleStreetChange}
onBlur={this.handleStreetEnd} onBlur={this.handleStreetEnd}
placeholder={__('请输入街道信息')} placeholder={__('City.street')}
disabled={disabled} disabled={disabled}
/> />
) : null} ) : null}

View File

@ -182,7 +182,7 @@ export interface ComboControlSchema extends FormBaseControl {
/** /**
* *
* @default <> * @default empty
*/ */
placeholder?: string; placeholder?: string;
@ -283,14 +283,14 @@ export default class ComboControl extends React.Component<ComboProps> {
formClassName: '', formClassName: '',
subFormMode: 'normal', subFormMode: 'normal',
draggableTip: '', draggableTip: '',
addButtonText: '新增', addButtonText: 'Combo.add',
canAccessSuperData: false, canAccessSuperData: false,
addIcon: true, addIcon: true,
dragIcon: '', dragIcon: '',
deleteIcon: '', deleteIcon: '',
tabsMode: false, tabsMode: false,
tabsStyle: '', tabsStyle: '',
placeholder: '<空>' placeholder: 'empty'
}; };
static propsList: Array<string> = [ static propsList: Array<string> = [
'minLength', 'minLength',
@ -520,7 +520,7 @@ export default class ComboControl extends React.Component<ComboProps> {
if (isEffectiveApi(deleteApi, ctx)) { if (isEffectiveApi(deleteApi, ctx)) {
const confirmed = await env.confirm( const confirmed = await env.confirm(
deleteConfirmText ? filter(deleteConfirmText, ctx) : __('确认要删除?') deleteConfirmText ? filter(deleteConfirmText, ctx) : __('deleteConfirm')
); );
if (!confirmed) { if (!confirmed) {
// 如果不确认,则跳过! // 如果不确认,则跳过!
@ -530,7 +530,7 @@ export default class ComboControl extends React.Component<ComboProps> {
const result = await env.fetcher(deleteApi as Api, ctx); const result = await env.fetcher(deleteApi as Api, ctx);
if (!result.ok) { if (!result.ok) {
env.notify('error', __('删除失败')); env.notify('error', __('deleteFailed'));
return; return;
} }
} }
@ -680,14 +680,12 @@ export default class ComboControl extends React.Component<ComboProps> {
if (minLength && (!Array.isArray(value) || value.length < minLength)) { if (minLength && (!Array.isArray(value) || value.length < minLength)) {
return __( return __(
(messages && messages.minLengthValidateFailed) || (messages && messages.minLengthValidateFailed) || 'Combo.minLength',
'组合表单成员数量不够,低于设定的最小{{minLength}}个,请添加更多的成员。',
{minLength} {minLength}
); );
} else if (maxLength && Array.isArray(value) && value.length > maxLength) { } else if (maxLength && Array.isArray(value) && value.length > maxLength) {
return __( return __(
(messages && messages.maxLengthValidateFailed) || (messages && messages.maxLengthValidateFailed) || 'Combo.maxLength',
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。',
{maxLength} {maxLength}
); );
} else if (this.subForms.length && (!nullable || value)) { } else if (this.subForms.length && (!nullable || value)) {
@ -695,8 +693,7 @@ export default class ComboControl extends React.Component<ComboProps> {
values => { values => {
if (~values.indexOf(false)) { if (~values.indexOf(false)) {
return __( return __(
(messages && messages.validateFailed) || (messages && messages.validateFailed) || 'validateFailed'
'子表单验证失败,请仔细检查'
); );
} }
@ -896,7 +893,11 @@ export default class ComboControl extends React.Component<ComboProps> {
renderPlaceholder() { renderPlaceholder() {
const {placeholder, translate: __} = this.props; const {placeholder, translate: __} = this.props;
return <span className="text-muted">{__(placeholder || '没有数据')}</span>; return (
<span className="text-muted">
{__(placeholder || 'placeholder.noData')}
</span>
);
} }
renderTabsMode() { renderTabsMode() {
@ -963,7 +964,7 @@ export default class ComboControl extends React.Component<ComboProps> {
) : ( ) : (
'' ''
), ),
label: __(addButtonText || '新增'), label: __(addButtonText || 'Combo.add'),
level: 'info', level: 'info',
size: 'sm', size: 'sm',
closeOnClick: true closeOnClick: true
@ -982,10 +983,10 @@ export default class ComboControl extends React.Component<ComboProps> {
<a <a
onClick={this.addItem} onClick={this.addItem}
data-position="left" data-position="left"
data-tooltip={__('新增一条数据')} data-tooltip={__('Combo.add')}
> >
{addIcon ? <Icon icon="plus" className="icon" /> : null} {addIcon ? <Icon icon="plus" className="icon" /> : null}
<span>{__(addButtonText || '新增')}</span> <span>{__(addButtonText || 'Combo.add')}</span>
</a> </a>
) )
) : null} ) : null}
@ -1009,7 +1010,7 @@ export default class ComboControl extends React.Component<ComboProps> {
className={cx( className={cx(
`Combo-tab-delBtn ${!store.removable ? 'is-disabled' : ''}` `Combo-tab-delBtn ${!store.removable ? 'is-disabled' : ''}`
)} )}
data-tooltip={__('删除')} data-tooltip={__('delete')}
data-position="bottom" data-position="bottom"
> >
{deleteIcon ? ( {deleteIcon ? (
@ -1044,7 +1045,7 @@ export default class ComboControl extends React.Component<ComboProps> {
<Tab <Tab
title={filter( title={filter(
tabsLabelTpl || tabsLabelTpl ||
__('成员{{index}}', {index: (data as any).index + 1}), __('{{index}}', {index: (data as any).index + 1}),
data data
)} )}
key={this.keys[index] || (this.keys[index] = guid())} key={this.keys[index] || (this.keys[index] = guid())}
@ -1056,7 +1057,7 @@ export default class ComboControl extends React.Component<ComboProps> {
> >
{condition && typeSwitchable !== false ? ( {condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}> <div className={cx('Combo-itemTag')}>
<label>{__('类型')}</label> <label>{__('Combo.type')}</label>
<Select <Select
onChange={this.handleComboTypeChange.bind(this, index)} onChange={this.handleComboTypeChange.bind(this, index)}
options={(conditions as Array<ComboCondition>).map( options={(conditions as Array<ComboCondition>).map(
@ -1099,7 +1100,7 @@ export default class ComboControl extends React.Component<ComboProps> {
) )
) : ( ) : (
<Alert2 level="warning" className="m-b-none"> <Alert2 level="warning" className="m-b-none">
{__('数据非法,或者数据已失效,请移除')} {__('Combo.invalidData')}
</Alert2> </Alert2>
)} )}
</div> </div>
@ -1187,7 +1188,7 @@ export default class ComboControl extends React.Component<ComboProps> {
className={cx( className={cx(
`Combo-delBtn ${!store.removable ? 'is-disabled' : ''}` `Combo-delBtn ${!store.removable ? 'is-disabled' : ''}`
)} )}
data-tooltip={__('删除')} data-tooltip={__('delete')}
data-position="bottom" data-position="bottom"
> >
{deleteIcon ? ( {deleteIcon ? (
@ -1226,7 +1227,7 @@ export default class ComboControl extends React.Component<ComboProps> {
<div className={cx('Combo-itemDrager')}> <div className={cx('Combo-itemDrager')}>
<a <a
key="drag" key="drag"
data-tooltip={__('拖拽排序')} data-tooltip={__('Combo.dragDropSort')}
data-position="bottom" data-position="bottom"
> >
{dragIcon ? ( {dragIcon ? (
@ -1239,7 +1240,7 @@ export default class ComboControl extends React.Component<ComboProps> {
) : null} ) : null}
{condition && typeSwitchable !== false ? ( {condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}> <div className={cx('Combo-itemTag')}>
<label>{__('类型')}</label> <label>{__('Combo.type')}</label>
<Select <Select
onChange={this.handleComboTypeChange.bind(this, index)} onChange={this.handleComboTypeChange.bind(this, index)}
options={(conditions as Array<ComboCondition>).map( options={(conditions as Array<ComboCondition>).map(
@ -1283,7 +1284,7 @@ export default class ComboControl extends React.Component<ComboProps> {
) )
) : ( ) : (
<Alert2 level="warning" className="m-b-none"> <Alert2 level="warning" className="m-b-none">
{__('数据非法,或者数据已失效,请移除')} {__('Combo.invalidData')}
</Alert2> </Alert2>
)} )}
</div> </div>
@ -1303,7 +1304,7 @@ export default class ComboControl extends React.Component<ComboProps> {
'add-button', 'add-button',
{ {
type: 'dropdown-button', type: 'dropdown-button',
label: __(addButtonText || '新增'), label: __(addButtonText || 'Combo.add'),
level: 'info', level: 'info',
size: 'sm', size: 'sm',
closeOnClick: true closeOnClick: true
@ -1323,10 +1324,10 @@ export default class ComboControl extends React.Component<ComboProps> {
type="button" type="button"
onClick={this.addItem} onClick={this.addItem}
className={cx(`Button Combo-addBtn`, addButtonClassName)} className={cx(`Button Combo-addBtn`, addButtonClassName)}
data-tooltip={__('新增一条数据')} data-tooltip={__('Combo.add')}
> >
{addIcon ? <Icon icon="plus" className="icon" /> : null} {addIcon ? <Icon icon="plus" className="icon" /> : null}
<span>{__(addButtonText || '新增')}</span> <span>{__(addButtonText || 'Combo.add')}</span>
</button> </button>
) )
) : null} ) : null}
@ -1380,7 +1381,7 @@ export default class ComboControl extends React.Component<ComboProps> {
<div className={cx(`Combo-item`)}> <div className={cx(`Combo-item`)}>
{condition && typeSwitchable !== false ? ( {condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}> <div className={cx('Combo-itemTag')}>
<label>{__('类型')}</label> <label>{__('Combo.type')}</label>
<Select <Select
onChange={this.handleComboTypeChange.bind(this, 0)} onChange={this.handleComboTypeChange.bind(this, 0)}
options={(conditions as Array<ComboCondition>).map(item => ({ options={(conditions as Array<ComboCondition>).map(item => ({
@ -1416,14 +1417,14 @@ export default class ComboControl extends React.Component<ComboProps> {
) )
) : ( ) : (
<Alert2 level="warning" className="m-b-none"> <Alert2 level="warning" className="m-b-none">
{__('数据非法,或者数据已失效,请移除')} {__('Combo.invalidData')}
</Alert2> </Alert2>
)} )}
</div> </div>
</div> </div>
{value && nullable ? ( {value && nullable ? (
<a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}> <a className={cx('Combo-setNullBtn')} href="#" onClick={this.setNull}>
{__('清空数据')} {__('clear')}
</a> </a>
) : null} ) : null}
</div> </div>

View File

@ -343,7 +343,7 @@ export default class DateControl extends React.PureComponent<
export class DateControlRenderer extends DateControl { export class DateControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择日期', placeholder: 'Date.placeholder',
dateFormat: 'YYYY-MM-DD', dateFormat: 'YYYY-MM-DD',
timeFormat: '', timeFormat: '',
strictMode: false strictMode: false
@ -356,7 +356,7 @@ export class DateControlRenderer extends DateControl {
export class DatetimeControlRenderer extends DateControl { export class DatetimeControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择日期以及时间', placeholder: 'DateTime.placeholder',
inputFormat: 'YYYY-MM-DD HH:mm:ss', inputFormat: 'YYYY-MM-DD HH:mm:ss',
dateFormat: 'LL', dateFormat: 'LL',
timeFormat: 'HH:mm:ss', timeFormat: 'HH:mm:ss',
@ -371,7 +371,7 @@ export class DatetimeControlRenderer extends DateControl {
export class TimeControlRenderer extends DateControl { export class TimeControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择时间', placeholder: 'Time.placeholder',
inputFormat: 'HH:mm', inputFormat: 'HH:mm',
dateFormat: '', dateFormat: '',
timeFormat: 'HH:mm', timeFormat: 'HH:mm',
@ -386,7 +386,7 @@ export class TimeControlRenderer extends DateControl {
export class MonthControlRenderer extends DateControl { export class MonthControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择月份', placeholder: 'Month.placeholder',
inputFormat: 'YYYY-MM', inputFormat: 'YYYY-MM',
dateFormat: 'MM', dateFormat: 'MM',
timeFormat: '', timeFormat: '',
@ -401,7 +401,7 @@ export class MonthControlRenderer extends DateControl {
export class QuarterControlRenderer extends DateControl { export class QuarterControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择季度', placeholder: 'Quarter.placeholder',
inputFormat: 'YYYY [Q]Q', inputFormat: 'YYYY [Q]Q',
dateFormat: 'YYYY [Q]Q', dateFormat: 'YYYY [Q]Q',
timeFormat: '', timeFormat: '',
@ -416,7 +416,7 @@ export class QuarterControlRenderer extends DateControl {
export class YearControlRenderer extends DateControl { export class YearControlRenderer extends DateControl {
static defaultProps = { static defaultProps = {
...DateControl.defaultProps, ...DateControl.defaultProps,
placeholder: '请选择年', placeholder: 'Year.placeholder',
inputFormat: 'YYYY', inputFormat: 'YYYY',
dateFormat: 'YYYY', dateFormat: 'YYYY',
timeFormat: '', timeFormat: '',

View File

@ -251,7 +251,6 @@ export default class FileControl extends React.Component<FileProps, FileState> {
maxSize: 0, maxSize: 0,
maxLength: 0, maxLength: 0,
placeholder: '', placeholder: '',
btnLabel: '文件上传',
reciever: '/api/upload/file', reciever: '/api/upload/file',
fileField: 'file', fileField: 'file',
joinValues: true, joinValues: true,
@ -435,14 +434,11 @@ export default class FileControl extends React.Component<FileProps, FileState> {
[].slice.call(files, 0, allowed).forEach((file: FileX) => { [].slice.call(files, 0, allowed).forEach((file: FileX) => {
if (maxSize && file.size > maxSize) { if (maxSize && file.size > maxSize) {
this.props.env.alert( this.props.env.alert(
__( __('File.maxSize', {
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。',
{
filename: file.name, filename: file.name,
actualSize: ImageControl.formatFileSize(file.size), actualSize: ImageControl.formatFileSize(file.size),
maxSize: ImageControl.formatFileSize(maxSize) maxSize: ImageControl.formatFileSize(maxSize)
} })
)
); );
file.state = 'invalid'; file.state = 'invalid';
} else { } else {
@ -497,7 +493,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
// }); // });
env.alert( env.alert(
__('您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。', { __('File.invalidType', {
files: files.map((item: any) => `${item.name}`).join(' '), files: files.map((item: any) => `${item.name}`).join(' '),
accept accept
}) })
@ -634,7 +630,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
if (this.resolve) { if (this.resolve) {
this.resolve( this.resolve(
this.state.files.some(file => file.state === 'error') this.state.files.some(file => file.state === 'error')
? __('文件上传失败请重试') ? __('File.errorRetry')
: null : null
); );
this.resolve = undefined; this.resolve = undefined;
@ -717,7 +713,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
) )
.then(ret => { .then(ret => {
if (ret.status || !ret.data) { if (ret.status || !ret.data) {
throw new Error(ret.msg || __('上传失败, 请重试')); throw new Error(ret.msg || __('File.errorRetry'));
} }
onProgress(1); onProgress(1);
@ -737,7 +733,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
}); });
}) })
.catch(error => { .catch(error => {
cb(error.message || __('上传失败, 请重试'), file); cb(error.message || __('File.errorRetry'), file);
}); });
} }
@ -874,7 +870,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
progressArr = tasks.map(() => 0); progressArr = tasks.map(() => 0);
if (!ret.data) { if (!ret.data) {
throw new Error(__('接口返回错误,请仔细检查')); throw new Error(__('File.uploadFailed'));
} }
state = { state = {
@ -1036,7 +1032,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
this.startUpload(); this.startUpload();
}); });
} else if (this.state.files.some(item => item.state === 'error')) { } else if (this.state.files.some(item => item.state === 'error')) {
return __('文件上传失败请重试'); return __('File.errorRetry');
} }
} }
@ -1096,7 +1092,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
{isDragActive ? ( {isDragActive ? (
<div className={cx('FileControl-acceptTip')}> <div className={cx('FileControl-acceptTip')}>
{__('把文件拖到这,然后松完成添加!')} {__('File.dragDrop')}
</div> </div>
) : ( ) : (
<> <>
@ -1110,10 +1106,12 @@ export default class FileControl extends React.Component<FileProps, FileState> {
> >
<Icon icon="upload" className="icon" /> <Icon icon="upload" className="icon" />
{!multiple && files.length {!multiple && files.length
? __('重新上传') ? __('File.repick')
: multiple && files.length : multiple && files.length
? __('继续添加') ? __('File.continueAdd')
: __('上传文件')} : btnLabel
? btnLabel
: __('File.upload')}
</Button> </Button>
) : null} ) : null}
@ -1156,7 +1154,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
) : null} ) : null}
{file.state !== 'uploading' && !disabled ? ( {file.state !== 'uploading' && !disabled ? (
<a <a
data-tooltip={__('移除')} data-tooltip={__('Select.clear')}
className={cx('FileControl-clear')} className={cx('FileControl-clear')}
onClick={() => this.removeFile(file, index)} onClick={() => this.removeFile(file, index)}
> >
@ -1200,12 +1198,12 @@ export default class FileControl extends React.Component<FileProps, FileState> {
{failed ? ( {failed ? (
<div className={cx('FileControl-sum')}> <div className={cx('FileControl-sum')}>
{__('已成功上传{{uploaded}}个文件,{{failed}}个文件上传失败,', { {__('File.result', {
uploaded, uploaded,
failed failed
})} })}
<a onClick={this.retry}>{__('重试上传')}</a> <a onClick={this.retry}>{__('File.retry')}</a>
{__('失败文件。')} {__('File.failed')}
</div> </div>
) : null} ) : null}
@ -1216,7 +1214,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
className={cx('FileControl-uploadBtn')} className={cx('FileControl-uploadBtn')}
onClick={this.toggleUpload} onClick={this.toggleUpload}
> >
{__(uploading ? '暂停上传' : '开始上传')} {__(uploading ? 'File.pause' : 'File.start')}
</Button> </Button>
) : null} ) : null}
</div> </div>

View File

@ -280,7 +280,7 @@ export default class ImageControl extends React.Component<
accept: 'image/jpeg, image/jpg, image/png, image/gif', accept: 'image/jpeg, image/jpg, image/png, image/gif',
reciever: '/api/upload', reciever: '/api/upload',
hideUploadButton: false, hideUploadButton: false,
placeholder: '点击选择图片或者将图片拖入该区域', placeholder: 'Image.placeholder点击选择图片或者将图片拖入该区域',
joinValues: true, joinValues: true,
extractValue: false, extractValue: false,
delimiter: ',', delimiter: ',',
@ -326,12 +326,12 @@ export default class ImageControl extends React.Component<
__: TranslateFn __: TranslateFn
): string { ): string {
if (!width) { if (!width) {
return __('高度{{height}}px', {height: height}); return __('Image.height', {height: height});
} else if (!height) { } else if (!height) {
return __('宽度{{width}}px', {width: width}); return __('Image.width', {width: width});
} }
return __('尺寸({{width}} x {{height}}', {width, height}); return __('Image.size', {width, height});
} }
state: ImageState = { state: ImageState = {
@ -456,9 +456,7 @@ export default class ImageControl extends React.Component<
const __ = this.props.translate; const __ = this.props.translate;
if (crop && props.multiple) { if (crop && props.multiple) {
props.env && props.env && props.env.alert && props.env.alert(__('Image.configError'));
props.env.alert &&
props.env.alert(__('图片多选配置和裁剪配置冲突,目前不能二者都支持!'));
return null; return null;
} }
@ -506,7 +504,7 @@ export default class ImageControl extends React.Component<
// }); // });
env.alert( env.alert(
__('您添加的文件{{files}}不符合类型的`{{accept}}`的设定,请仔细检查。', { __('File.invalidType', {
files: files.map((file: any) => `${file.name}`).join(' '), files: files.map((file: any) => `${file.name}`).join(' '),
accept accept
}) })
@ -597,7 +595,7 @@ export default class ImageControl extends React.Component<
); );
} }
env.notify('error', error || __('图片上传失败,请重试')); env.notify('error', error || __('File.errorRetry'));
} else { } else {
newFile = { newFile = {
name: file.name, name: file.name,
@ -652,7 +650,7 @@ export default class ImageControl extends React.Component<
if (this.resolve) { if (this.resolve) {
this.resolve( this.resolve(
this.files.some(file => file.state === 'error') this.files.some(file => file.state === 'error')
? __('文件上传失败请重试') ? __('File.errorRetry')
: null : null
); );
this.resolve = undefined; this.resolve = undefined;
@ -852,14 +850,11 @@ export default class ImageControl extends React.Component<
[].slice.call(files, 0, allowed).forEach((file: FileX) => { [].slice.call(files, 0, allowed).forEach((file: FileX) => {
if (maxSize && file.size > maxSize) { if (maxSize && file.size > maxSize) {
this.props.env.alert( this.props.env.alert(
__( __('File.maxSize', {
'您选择的文件 {{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制,请重新选择。',
{
filename: file.name, filename: file.name,
actualSize: ImageControl.formatFileSize(file.size), actualSize: ImageControl.formatFileSize(file.size),
maxSize: ImageControl.formatFileSize(maxSize) maxSize: ImageControl.formatFileSize(maxSize)
} })
)
); );
return; return;
} }
@ -913,33 +908,30 @@ export default class ImageControl extends React.Component<
(limit.width && limit.width != width) || (limit.width && limit.width != width) ||
(limit.height && limit.height != height) (limit.height && limit.height != height)
) { ) {
error = __('您选择的图片不符合尺寸要求, 请上传{{info}}的图片', { error = __('Image.sizeNotEqual', {
info: ImageControl.sizeInfo(limit.width, limit.height, __) info: ImageControl.sizeInfo(limit.width, limit.height, __)
}); });
} else if ( } else if (
(limit.maxWidth && limit.maxWidth < width) || (limit.maxWidth && limit.maxWidth < width) ||
(limit.maxHeight && limit.maxHeight < height) (limit.maxHeight && limit.maxHeight < height)
) { ) {
error = __('您选择的图片不符合尺寸要求, 请上传不要超过{{info}}的图片', { error = __('Image.limitMax', {
info: ImageControl.sizeInfo(limit.maxWidth, limit.maxHeight, __) info: ImageControl.sizeInfo(limit.maxWidth, limit.maxHeight, __)
}); });
} else if ( } else if (
(limit.minWidth && limit.minWidth > width) || (limit.minWidth && limit.minWidth > width) ||
(limit.minHeight && limit.minHeight > height) (limit.minHeight && limit.minHeight > height)
) { ) {
error = __('您选择的图片不符合尺寸要求, 请上传不要小于{{info}}的图片', { error = __('Image.limitMin', {
info: ImageControl.sizeInfo(limit.minWidth, limit.minHeight, __) info: ImageControl.sizeInfo(limit.minWidth, limit.minHeight, __)
}); });
} else if ( } else if (
limit.aspectRatio && limit.aspectRatio &&
Math.abs(width / height - limit.aspectRatio) > 0.01 Math.abs(width / height - limit.aspectRatio) > 0.01
) { ) {
error = __( error = __(limit.aspectRatioLabel || 'Image.limitRatio', {
'您选择的图片不符合尺寸要求, 请上传尺寸比率为 {{ratio}} 的图片', ratio: limit.aspectRatio
{ });
ratio: limit.aspectRatioLabel || limit.aspectRatio
}
);
} }
if (error) { if (error) {
@ -961,7 +953,7 @@ export default class ImageControl extends React.Component<
this._send(file, this.props.reciever as string, {}, onProgress) this._send(file, this.props.reciever as string, {}, onProgress)
.then((ret: Payload) => { .then((ret: Payload) => {
if (ret.status) { if (ret.status) {
throw new Error(ret.msg || __('上传失败, 请重试')); throw new Error(ret.msg || __('File.errorRetry'));
} }
const obj: FileValue = { const obj: FileValue = {
@ -972,7 +964,7 @@ export default class ImageControl extends React.Component<
cb(null, file, obj); cb(null, file, obj);
}) })
.catch(error => cb(error.message || __('上传失败,请重试'), file)); .catch(error => cb(error.message || __('File.errorRetry'), file));
} }
_send( _send(
@ -1082,7 +1074,7 @@ export default class ImageControl extends React.Component<
this.startUpload(); this.startUpload();
}); });
} else if (this.files.some(item => item.state === 'error')) { } else if (this.files.some(item => item.state === 'error')) {
return __('文件上传失败请重试'); return __('File.errorRetry');
} }
} }
@ -1115,7 +1107,7 @@ export default class ImageControl extends React.Component<
<a <a
className={cx('ImageControl-cropCancel')} className={cx('ImageControl-cropCancel')}
onClick={this.cancelCrop} onClick={this.cancelCrop}
data-tooltip={__('取消')} data-tooltip={__('cancle')}
data-position="left" data-position="left"
> >
<Icon icon="close" className="icon" /> <Icon icon="close" className="icon" />
@ -1123,7 +1115,7 @@ export default class ImageControl extends React.Component<
<a <a
className={cx('ImageControl-cropConfirm')} className={cx('ImageControl-cropConfirm')}
onClick={this.handleCrop} onClick={this.handleCrop}
data-tooltip={__('确认')} data-tooltip={__('confirm')}
data-position="left" data-position="left"
> >
<Icon icon="check" className="icon" /> <Icon icon="check" className="icon" />
@ -1167,7 +1159,7 @@ export default class ImageControl extends React.Component<
'is-reject': isDragReject 'is-reject': isDragReject
})} })}
> >
{__('把图片拖到这,然后松开完成添加!')} {__('Image.dragDrop')}
</div> </div>
) : ( ) : (
<> <>
@ -1187,7 +1179,7 @@ export default class ImageControl extends React.Component<
<> <>
<a <a
className={cx('ImageControl-itemClear')} className={cx('ImageControl-itemClear')}
data-tooltip={__('移除')} data-tooltip={__('Select.clear')}
data-position="bottom" data-position="bottom"
onClick={this.removeFile.bind( onClick={this.removeFile.bind(
this, this,
@ -1206,7 +1198,7 @@ export default class ImageControl extends React.Component<
> >
<Icon icon="retry" className="icon" /> <Icon icon="retry" className="icon" />
<p className="ImageControl-itemInfoError"> <p className="ImageControl-itemInfoError">
{__('重新上传')} {__('File.repick')}
</p> </p>
</a> </a>
</> </>
@ -1220,7 +1212,7 @@ export default class ImageControl extends React.Component<
)} )}
key="clear" key="clear"
className={cx('ImageControl-itemClear')} className={cx('ImageControl-itemClear')}
data-tooltip={__('移除')} data-tooltip={__('Select.clear')}
> >
<Icon icon="close" className="icon" /> <Icon icon="close" className="icon" />
</a> </a>
@ -1228,7 +1220,7 @@ export default class ImageControl extends React.Component<
key="info" key="info"
className={cx('ImageControl-itemInfo')} className={cx('ImageControl-itemInfo')}
> >
<p>{__('文件上传中')}</p> <p>{__('File.uploading')}</p>
<div className={cx('ImageControl-progress')}> <div className={cx('ImageControl-progress')}>
<span <span
style={{ style={{
@ -1280,7 +1272,7 @@ export default class ImageControl extends React.Component<
)} )}
<a <a
data-tooltip={__('查看大图')} data-tooltip={__('Image.zoomIn')}
data-position="bottom" data-position="bottom"
target="_blank" target="_blank"
rel="noopener" rel="noopener"
@ -1298,7 +1290,7 @@ export default class ImageControl extends React.Component<
reCropable !== false && reCropable !== false &&
!disabled ? ( !disabled ? (
<a <a
data-tooltip={__('裁剪图片')} data-tooltip={__('Image.crop')}
data-position="bottom" data-position="bottom"
onClick={this.editImage.bind(this, key)} onClick={this.editImage.bind(this, key)}
> >
@ -1307,7 +1299,7 @@ export default class ImageControl extends React.Component<
) : null} ) : null}
{!disabled ? ( {!disabled ? (
<a <a
data-tooltip={__('移除')} data-tooltip={__('Select.clear')}
data-position="bottom" data-position="bottom"
onClick={this.removeFile.bind( onClick={this.removeFile.bind(
this, this,
@ -1349,7 +1341,7 @@ export default class ImageControl extends React.Component<
{isFocused ? ( {isFocused ? (
<span className={cx('ImageControl-pasteTip')}> <span className={cx('ImageControl-pasteTip')}>
{__('当前状态支持从剪切板中粘贴图片文件。')} {__('Image.pasteTip')}
</span> </span>
) : null} ) : null}
</label> </label>
@ -1362,7 +1354,7 @@ export default class ImageControl extends React.Component<
disabled={!hasPending} disabled={!hasPending}
onClick={this.toggleUpload} onClick={this.toggleUpload}
> >
{__(uploading ? '暂停上传' : '开始上传')} {__(uploading ? 'File.pause' : 'File.start')}
</Button> </Button>
) : null} ) : null}

View File

@ -1260,7 +1260,6 @@ export function asFormItem(config: Omit<FormItemConfig, 'component'>) {
if (config.validate && !Control.prototype.validate) { if (config.validate && !Control.prototype.validate) {
const fn = config.validate; const fn = config.validate;
Control.prototype.validate = function () { Control.prototype.validate = function () {
// console.warn('推荐直接在类中定义,而不是 FormItem HOC 的参数中传入。');
const host = { const host = {
input: this input: this
}; };

View File

@ -198,7 +198,7 @@ export default class MatrixCheckbox extends React.Component<
.fetcher(source, data) .fetcher(source, data)
.then(ret => { .then(ret => {
if (!ret.ok) { if (!ret.ok) {
throw new Error(ret.msg || __('数据请求错误')); throw new Error(ret.msg || __('fetchFailed'));
} }
if (!this.mounted) { if (!this.mounted) {
return resolve(); return resolve();

View File

@ -50,7 +50,7 @@ export default class NestedSelectControl extends React.Component<
static defaultProps: Partial<NestedSelectProps> = { static defaultProps: Partial<NestedSelectProps> = {
cascade: false, cascade: false,
withChildren: false, withChildren: false,
searchPromptText: '输入内容进行检索', searchPromptText: 'Select.searchPromptText',
checkAll: true, checkAll: true,
checkAllLabel: '全选' checkAllLabel: '全选'
}; };
@ -127,12 +127,13 @@ export default class NestedSelectControl extends React.Component<
selectedOptions, selectedOptions,
labelField, labelField,
placeholder, placeholder,
translate: __,
disabled disabled
} = this.props; } = this.props;
if (!(selectedOptions && selectedOptions.length > 0)) { if (!(selectedOptions && selectedOptions.length > 0)) {
return ( return (
<div className={cx('NestedSelect-placeholder')}>{placeholder}</div> <div className={cx('NestedSelect-placeholder')}>{__(placeholder)}</div>
); );
} }

View File

@ -247,7 +247,7 @@ export function registerOptionsControl(config: OptionsConfig) {
joinValues: true, joinValues: true,
extractValue: false, extractValue: false,
multiple: false, multiple: false,
placeholder: '请选择', placeholder: 'Select.placeholder',
resetValue: '', resetValue: '',
deleteConfirmText: '确定要删除?', deleteConfirmText: '确定要删除?',
...Control.defaultProps ...Control.defaultProps
@ -714,7 +714,7 @@ export function registerOptionsControl(config: OptionsConfig) {
type: 'text', type: 'text',
name: labelField || 'label', name: labelField || 'label',
label: false, label: false,
placeholder: __('请输入名称') placeholder: __('Options.addPlaceholder')
} }
]; ];
} }
@ -825,7 +825,7 @@ export function registerOptionsControl(config: OptionsConfig) {
type: 'text', type: 'text',
name: labelField || 'label', name: labelField || 'label',
label: false, label: false,
placeholder: __('请输入名称') placeholder: __('Options.addPlaceholder')
} }
]; ];
} }
@ -835,8 +835,8 @@ export function registerOptionsControl(config: OptionsConfig) {
: await onOpenDialog( : await onOpenDialog(
{ {
type: 'dialog', type: 'dialog',
title: __('编辑{{label}}', { title: __('Options.editLabel', {
label: optionLabel || '选项' label: optionLabel || __('Options.label')
}), }),
body: { body: {
type: 'form', type: 'form',
@ -859,7 +859,7 @@ export function registerOptionsControl(config: OptionsConfig) {
); );
if (!payload.ok) { if (!payload.ok) {
env.notify('error', payload.msg || __('保存失败,请仔细检查')); env.notify('error', payload.msg || __('saveFailed'));
result = null; result = null;
} else { } else {
result = payload.data || result; result = payload.data || result;
@ -924,7 +924,7 @@ export function registerOptionsControl(config: OptionsConfig) {
// 通过 deleteApi 删除。 // 通过 deleteApi 删除。
try { try {
if (!deleteApi) { if (!deleteApi) {
throw new Error(__('请配置 deleteApi')); throw new Error(__('Options.deleteAPI'));
} }
const result = await env.fetcher(deleteApi!, ctx, { const result = await env.fetcher(deleteApi!, ctx, {
@ -932,7 +932,7 @@ export function registerOptionsControl(config: OptionsConfig) {
}); });
if (!result.ok) { if (!result.ok) {
env.notify('error', result.msg || __('删除失败,请重试')); env.notify('error', result.msg || __('deleteFailed'));
} else if (source) { } else if (source) {
this.reload(); this.reload();
} else { } else {

View File

@ -484,7 +484,7 @@ export default class PickerControl extends React.PureComponent<
{render( {render(
'modal', 'modal',
{ {
title: __('请选择'), title: __('Select.placeholder'),
size: size, size: size,
type: modalMode, type: modalMode,
body: { body: {

View File

@ -197,7 +197,7 @@ export default class RepeatControl extends React.Component<RepeatProps, any> {
<div className="repeat-control hbox"> <div className="repeat-control hbox">
{input ? ( {input ? (
<div className="col v-middle" style={{width: 30}}> <div className="col v-middle" style={{width: 30}}>
<span>{__('')}</span> <span>{__('Repeat.pre')}</span>
</div> </div>
) : null} ) : null}

View File

@ -41,7 +41,7 @@ export default class RichTextControl extends React.Component<
imageEditable: true, imageEditable: true,
reciever: '/api/upload/image', reciever: '/api/upload/image',
videoReciever: '/api/upload/video', videoReciever: '/api/upload/video',
placeholder: '请输入', placeholder: 'placeholder.enter',
options: { options: {
toolbarButtonsSM: [ toolbarButtonsSM: [
'paragraphFormat', 'paragraphFormat',

View File

@ -100,7 +100,7 @@ export default class SubFormControl extends React.PureComponent<
addButtonClassName: '', addButtonClassName: '',
editButtonClassName: '', editButtonClassName: '',
labelField: 'label', labelField: 'label',
btnLabel: '设置' btnLabel: 'SubForm.button'
}; };
state: SubFormState = { state: SubFormState = {
@ -230,7 +230,7 @@ export default class SubFormControl extends React.PureComponent<
key={key} key={key}
> >
<span <span
data-tooltip={__('删除')} data-tooltip={__('delete')}
data-position="bottom" data-position="bottom"
className={`${ns}Select-valueIcon`} className={`${ns}Select-valueIcon`}
onClick={this.removeItem.bind(this, key)} onClick={this.removeItem.bind(this, key)}
@ -240,7 +240,7 @@ export default class SubFormControl extends React.PureComponent<
<span <span
onClick={this.open.bind(this, key)} onClick={this.open.bind(this, key)}
className={`${ns}SubForm-valueLabel`} className={`${ns}SubForm-valueLabel`}
data-tooltip={__('编辑详情')} data-tooltip={__('SubForm.editDetail')}
data-position="bottom" data-position="bottom"
> >
{(value && {(value &&
@ -268,10 +268,10 @@ export default class SubFormControl extends React.PureComponent<
onClick={this.addItem} onClick={this.addItem}
className={cx(`${ns}Button ${ns}SubForm-addBtn`, addButtonClassName)} className={cx(`${ns}Button ${ns}SubForm-addBtn`, addButtonClassName)}
disabled={disabled} disabled={disabled}
data-tooltip={__('新增一条数据')} data-tooltip={__('Combo.add')}
> >
<Icon icon="plus" className="icon" /> <Icon icon="plus" className="icon" />
<span>{__('新增')}</span> <span>{__('Combo.add')}</span>
</button> </button>
]; ];
} }
@ -300,7 +300,7 @@ export default class SubFormControl extends React.PureComponent<
btnClassName btnClassName
)} )}
onClick={this.open.bind(this, 0)} onClick={this.open.bind(this, 0)}
data-tooltip={__('编辑详情')} data-tooltip={__('SubForm.editDetail')}
data-position="bottom" data-position="bottom"
> >
<span className={`${ns}SubForm-valueLabel`}> <span className={`${ns}SubForm-valueLabel`}>

View File

@ -222,19 +222,13 @@ export default class FormTable extends React.Component<TableProps, TableState> {
// todo: 如果当前正在编辑中,表单提交了,应该先让正在编辑的东西提交然后再做验证。 // todo: 如果当前正在编辑中,表单提交了,应该先让正在编辑的东西提交然后再做验证。
if (~this.state.editIndex) { if (~this.state.editIndex) {
return __('请先处理表格编辑项'); return __('Table.editing');
} }
if (minLength && (!Array.isArray(value) || value.length < minLength)) { if (minLength && (!Array.isArray(value) || value.length < minLength)) {
return __( return __('Combo.minLength', {minLength});
'组合表单成员数量不够,低于设定的最小{{minLength}}个,请添加更多的成员。',
{minLength}
);
} else if (maxLength && Array.isArray(value) && value.length > maxLength) { } else if (maxLength && Array.isArray(value) && value.length > maxLength) {
return __( return __('Combo.maxLength', {maxLength});
'组合表单成员数量超出,超出设定的最大{{maxLength}}个,请删除多余的成员。',
{maxLength}
);
} else { } else {
const subForms: Array<any> = []; const subForms: Array<any> = [];
Object.keys(this.subForms).forEach( Object.keys(this.subForms).forEach(
@ -244,7 +238,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
return Promise.all(subForms.map(item => item.validate())).then( return Promise.all(subForms.map(item => item.validate())).then(
values => { values => {
if (~values.indexOf(false)) { if (~values.indexOf(false)) {
return __('内部表单验证失败'); return __('Form.validateFailed');
} }
return; return;
@ -275,7 +269,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
if (isEffectiveApi(addApi, ctx)) { if (isEffectiveApi(addApi, ctx)) {
const payload = await env.fetcher(addApi, ctx); const payload = await env.fetcher(addApi, ctx);
if (payload && !payload.ok) { if (payload && !payload.ok) {
env.notify('error', payload.msg || __('请求失败')); env.notify('error', payload.msg || __('fetchFailed'));
return; return;
} else if (payload && payload.ok) { } else if (payload && payload.ok) {
toAdd = payload.data; toAdd = payload.data;
@ -313,9 +307,9 @@ export default class FormTable extends React.Component<TableProps, TableState> {
action.actionType === 'delete' action.actionType === 'delete'
) { ) {
if (!valueField) { if (!valueField) {
return env.alert(__('请配置 valueField')); return env.alert(__('Table.valueField'));
} else if (!action.payload) { } else if (!action.payload) {
return env.alert(__('action 上请配置 payload, 否则不清楚要删除哪个')); return env.alert(__('Table.playload'));
} }
const rows = Array.isArray(value) ? value.concat() : []; const rows = Array.isArray(value) ? value.concat() : [];
@ -407,7 +401,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
} }
if (remote && !remote.ok) { if (remote && !remote.ok) {
env.notify('error', remote.msg || __('保存失败')); env.notify('error', remote.msg || __('saveFailed'));
return; return;
} else if (remote && remote.ok) { } else if (remote && remote.ok) {
item = { item = {
@ -465,7 +459,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
const ctx = createObject(data, item); const ctx = createObject(data, item);
if (isEffectiveApi(deleteApi, ctx)) { if (isEffectiveApi(deleteApi, ctx)) {
const confirmed = await env.confirm( const confirmed = await env.confirm(
deleteConfirmText ? filter(deleteConfirmText, ctx) : __('确认要删除?') deleteConfirmText ? filter(deleteConfirmText, ctx) : __('deleteConfirm')
); );
if (!confirmed) { if (!confirmed) {
// 如果不确认,则跳过! // 如果不确认,则跳过!
@ -475,7 +469,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
const result = await env.fetcher(deleteApi, ctx); const result = await env.fetcher(deleteApi, ctx);
if (!result.ok) { if (!result.ok) {
env.notify('error', __('删除失败')); env.notify('error', __('deleteFailed'));
return; return;
} }
} }
@ -514,7 +508,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
size="sm" size="sm"
key={key} key={key}
level="link" level="link"
tooltip={__('新增一行')} tooltip={__('Table.addRow')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -581,7 +575,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
size="sm" size="sm"
key={key} key={key}
level="link" level="link"
tooltip={__('编辑当前行')} tooltip={__('Table.editRow')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -605,7 +599,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
size="sm" size="sm"
key={key} key={key}
level="link" level="link"
tooltip={__('保存')} tooltip={__('save')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -629,7 +623,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
size="sm" size="sm"
key={key} key={key}
level="link" level="link"
tooltip={__('取消')} tooltip={__('cancle')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -664,7 +658,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
size="sm" size="sm"
key={key} key={key}
level="link" level="link"
tooltip={__('删除当前行')} tooltip={__('Table.deleteRow')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -685,7 +679,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
columns.push({ columns.push({
type: 'operation', type: 'operation',
buttons: btns, buttons: btns,
label: __('操作'), label: __('Table.operation'),
className: 'v-middle nowrap', className: 'v-middle nowrap',
fixed: 'right', fixed: 'right',
width: '1%', width: '1%',

View File

@ -60,8 +60,8 @@ export default class TagControl extends React.PureComponent<
labelField: 'label', labelField: 'label',
valueField: 'value', valueField: 'value',
multiple: true, multiple: true,
placeholder: '暂无标签', placeholder: 'Tag.placeholder',
optionsTip: '最近您使用的标签' optionsTip: 'Tag.tip'
}; };
state = { state = {
@ -324,7 +324,7 @@ export default class TagControl extends React.PureComponent<
{...getInputProps({ {...getInputProps({
name, name,
ref: this.input, ref: this.input,
placeholder: __(placeholder || '暂无标签'), placeholder: __(placeholder || 'Tag.placeholder'),
value: this.state.inputValue, value: this.state.inputValue,
onKeyDown: this.handleKeyDown, onKeyDown: this.handleKeyDown,
onFocus: this.handleFocus, onFocus: this.handleFocus,

View File

@ -600,7 +600,7 @@ export default class TextControl extends React.PureComponent<
> >
{option.isNew ? ( {option.isNew ? (
<span> <span>
{__('新增:{{label}}', {label: option.label})} {__('Text.add', {label: option.label})}
<Icon icon="enter" className="icon" /> <Icon icon="enter" className="icon" />
</span> </span>
) : ( ) : (

View File

@ -153,7 +153,7 @@ export class BaseTransferRenderer<
const result = const result =
payload.data.options || payload.data.items || payload.data; payload.data.options || payload.data.items || payload.data;
if (!Array.isArray(result)) { if (!Array.isArray(result)) {
throw new Error('期望接口返回数组信息'); throw new Error('CRUD.invalidArray');
} }
return result.map(item => { return result.map(item => {

View File

@ -62,7 +62,7 @@ export interface TreeProps
export default class TreeControl extends React.Component<TreeProps> { export default class TreeControl extends React.Component<TreeProps> {
static defaultProps: Partial<TreeProps> = { static defaultProps: Partial<TreeProps> = {
placeholder: '选项加载中...', placeholder: 'loading',
multiple: false, multiple: false,
rootLabel: '顶级', rootLabel: '顶级',
rootValue: '', rootValue: '',

View File

@ -87,8 +87,8 @@ export default class TreeSelectControl extends React.Component<
TreeSelectState TreeSelectState
> { > {
static defaultProps = { static defaultProps = {
placeholder: '请选择', placeholder: 'Select.placeholder',
optionsPlaceholder: '暂无数据', optionsPlaceholder: 'placeholder.noData',
multiple: false, multiple: false,
clearable: true, clearable: true,
rootLabel: '顶级', rootLabel: '顶级',

View File

@ -306,8 +306,8 @@ export interface FormProps extends RendererProps, Omit<FormSchema, 'mode'> {
export default class Form extends React.Component<FormProps, object> { export default class Form extends React.Component<FormProps, object> {
static defaultProps = { static defaultProps = {
title: '表单', title: 'Form.title',
submitText: '提交', submitText: 'Form.submit',
initFetch: true, initFetch: true,
wrapWithPanel: true, wrapWithPanel: true,
mode: 'normal', mode: 'normal',
@ -320,9 +320,9 @@ export default class Form extends React.Component<FormProps, object> {
}, },
panelClassName: 'Panel--default', panelClassName: 'Panel--default',
messages: { messages: {
fetchFailed: '初始化失败', fetchFailed: 'fetchFailed',
saveSuccess: '保存成功', saveSuccess: 'saveSuccess',
saveFailed: '保存失败' saveFailed: 'saveFailed'
}, },
wrapperComponent: '', wrapperComponent: '',
finishedField: 'finished', finishedField: 'finished',
@ -821,7 +821,7 @@ export default class Form extends React.Component<FormProps, object> {
if (Array.isArray(action.required) && action.required.length) { if (Array.isArray(action.required) && action.required.length) {
return store.validateFields(action.required).then(result => { return store.validateFields(action.required).then(result => {
if (!result) { if (!result) {
env.notify('error', __('依赖的部分字段没有通过验证,请注意填写!')); env.notify('error', __('Form.validateFailed'));
} else { } else {
this.handleAction( this.handleAction(
e, e,

View File

@ -124,7 +124,7 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
{enlargeAble ? ( {enlargeAble ? (
<div key="overlay" className={cx('Image-overlay')}> <div key="overlay" className={cx('Image-overlay')}>
<a <a
data-tooltip={__('查看大图')} data-tooltip={__('Image.zoomIn')}
data-position="bottom" data-position="bottom"
target="_blank" target="_blank"
onClick={this.handleEnlarge} onClick={this.handleEnlarge}

View File

@ -54,7 +54,7 @@ export class LinkField extends React.Component<LinkProps, object> {
target={htmlTarget || (blank ? '_blank' : '_self')} target={htmlTarget || (blank ? '_blank' : '_self')}
className={cx('Link', className)} className={cx('Link', className)}
> >
{body ? render('body', body) : finnalHref || value || __('链接')} {body ? render('body', body) : finnalHref || value || __('link')}
</a> </a>
); );
} }

View File

@ -254,7 +254,7 @@ export default class List extends React.Component<ListProps, object> {
]; ];
static defaultProps: Partial<ListProps> = { static defaultProps: Partial<ListProps> = {
className: '', className: '',
placeholder: '没有数据', placeholder: 'placeholder.noData',
source: '$items', source: '$items',
selectable: false, selectable: false,
headerClassName: '', headerClassName: '',

View File

@ -180,7 +180,7 @@ export class Navigation extends React.Component<
if (!payload.ok) { if (!payload.ok) {
this.setState({ this.setState({
error: payload.msg || __('获取链接错误') error: payload.msg || __('Nav.sourceError')
}); });
} else { } else {
const links = Array.isArray(payload.data) const links = Array.isArray(payload.data)

View File

@ -209,7 +209,7 @@ export const HocPopOver = (
type: popOver.mode, type: popOver.mode,
actions: [ actions: [
{ {
label: __('关闭'), label: __('Dialog.close'),
type: 'button', type: 'button',
actionType: 'cancel' actionType: 'cancel'
} }

View File

@ -423,12 +423,12 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (
: [ : [
{ {
type: 'button', type: 'button',
label: __('取消'), label: __('cancle'),
actionType: 'cancel' actionType: 'cancel'
}, },
{ {
label: __('确认'), label: __('confirm'),
type: 'submit', type: 'submit',
primary: true primary: true
} }

View File

@ -102,7 +102,7 @@ export default class Service extends React.Component<ServiceProps> {
static defaultProps: Partial<ServiceProps> = { static defaultProps: Partial<ServiceProps> = {
messages: { messages: {
fetchFailed: '初始化失败' fetchFailed: 'fetchFailed'
} }
}; };

View File

@ -251,7 +251,7 @@ export class HeadCellFilterDropDown extends React.Component<
key="DropDown-menu-reset" key="DropDown-menu-reset"
onClick={this.handleReset.bind(this)} onClick={this.handleReset.bind(this)}
> >
{__('重置')} {__('reset')}
</li> </li>
) : null} ) : null}
</ul> </ul>

View File

@ -91,14 +91,14 @@ export class HeadCellSearchDropDown extends React.Component<
{ {
type: 'button-group', type: 'button-group',
name: 'orderDir', name: 'orderDir',
label: __('排序'), label: __('sort'),
options: [ options: [
{ {
label: __('正序'), label: __('asc'),
value: 'asc' value: 'asc'
}, },
{ {
label: __('降序'), label: __('desc'),
value: 'desc' value: 'desc'
} }
] ]
@ -123,18 +123,18 @@ export class HeadCellSearchDropDown extends React.Component<
actions: [ actions: [
{ {
type: 'button', type: 'button',
label: __('重置'), label: __('reset'),
actionType: 'reset' actionType: 'reset'
}, },
{ {
type: 'button', type: 'button',
label: __('取消'), label: __('cancle'),
actionType: 'cancel' actionType: 'cancel'
}, },
{ {
label: __('搜索'), label: __('search'),
type: 'submit', type: 'submit',
primary: true primary: true
} }

View File

@ -262,7 +262,7 @@ export class TableBody extends React.Component<TableBodyProps> {
) : ( ) : (
<tr className={cx('Table-placeholder')}> <tr className={cx('Table-placeholder')}>
<td colSpan={columns.length}> <td colSpan={columns.length}>
{render('placeholder', placeholder || '暂无数据')} {render('placeholder', placeholder || 'placeholder.noData')}
</td> </td>
</tr> </tr>
)} )}

View File

@ -337,7 +337,7 @@ export default class Table extends React.Component<TableProps, object> {
]; ];
static defaultProps: Partial<TableProps> = { static defaultProps: Partial<TableProps> = {
className: '', className: '',
placeholder: '暂无数据', placeholder: 'placeholder.noData',
tableClassName: '', tableClassName: '',
source: '$items', source: '$items',
selectable: false, selectable: false,
@ -1162,19 +1162,16 @@ export default class Table extends React.Component<TableProps, object> {
<div className={cx('Table-heading', headingClassName)} key="heading"> <div className={cx('Table-heading', headingClassName)} key="heading">
{!saveImmediately && store.modified && !hideQuickSaveBtn ? ( {!saveImmediately && store.modified && !hideQuickSaveBtn ? (
<span> <span>
{__( {__('Table.modified', {
'当前有 {{modified}} 条记录修改了内容, 但并没有提交。请选择:',
{
modified: store.modified modified: store.modified
} })}
)}
<button <button
type="button" type="button"
className={cx('Button Button--xs Button--success m-l-sm')} className={cx('Button Button--xs Button--success m-l-sm')}
onClick={this.handleSave} onClick={this.handleSave}
> >
<Icon icon="check" className="icon m-r-xs" /> <Icon icon="check" className="icon m-r-xs" />
{__('提交')} {__('Form.submit')}
</button> </button>
<button <button
type="button" type="button"
@ -1182,12 +1179,12 @@ export default class Table extends React.Component<TableProps, object> {
onClick={this.reset} onClick={this.reset}
> >
<Icon icon="close" className="icon m-r-xs" /> <Icon icon="close" className="icon m-r-xs" />
{__('放弃')} {__('Table.discard')}
</button> </button>
</span> </span>
) : store.moved ? ( ) : store.moved ? (
<span> <span>
{__('当前有 {{moved}} 条记录修改了顺序, 但并没有提交。请选择:', { {__('Table.moved', {
moved: store.moved moved: store.moved
})} })}
<button <button
@ -1196,7 +1193,7 @@ export default class Table extends React.Component<TableProps, object> {
onClick={this.handleSaveOrder} onClick={this.handleSaveOrder}
> >
<Icon icon="check" className="icon m-r-xs" /> <Icon icon="check" className="icon m-r-xs" />
{__('提交')} {__('Form.submit')}
</button> </button>
<button <button
type="button" type="button"
@ -1204,7 +1201,7 @@ export default class Table extends React.Component<TableProps, object> {
onClick={this.reset} onClick={this.reset}
> >
<Icon icon="close" className="icon m-r-xs" /> <Icon icon="close" className="icon m-r-xs" />
{__('放弃')} {__('Table.discard')}
</button> </button>
</span> </span>
) : title ? ( ) : title ? (
@ -1706,7 +1703,7 @@ export default class Table extends React.Component<TableProps, object> {
return ( return (
<DropDownButton <DropDownButton
{...rest} {...rest}
tooltip={__('点击选择显示列')} tooltip={__('Table.columnsVisibility')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -1744,7 +1741,7 @@ export default class Table extends React.Component<TableProps, object> {
disabled={!!store.modified} disabled={!!store.modified}
classPrefix={ns} classPrefix={ns}
key="dragging-toggle" key="dragging-toggle"
tooltip={__('点击开始排序')} tooltip={__('Table.startSort')}
tooltipContainer={ tooltipContainer={
env && env.getModalContainer ? env.getModalContainer : undefined env && env.getModalContainer ? env.getModalContainer : undefined
} }
@ -1932,7 +1929,7 @@ export default class Table extends React.Component<TableProps, object> {
}} }}
size="sm" size="sm"
> >
{__('导出 Excel')} {__('CRUD.exportExcel')}
</Button> </Button>
); );
} }
@ -2037,7 +2034,7 @@ export default class Table extends React.Component<TableProps, object> {
{child} {child}
{store.dragging ? ( {store.dragging ? (
<div className={cx('Table-dragTip')} ref={this.dragTipRef}> <div className={cx('Table-dragTip')} ref={this.dragTipRef}>
{__('请拖动左边的按钮进行排序')} {__('Table.dragTip')}
</div> </div>
) : null} ) : null}
</div> </div>

View File

@ -157,7 +157,7 @@ export default class Task extends React.Component<TaskProps, TaskState> {
className: 'b-a bg-white table-responsive', className: 'b-a bg-white table-responsive',
tableClassName: 'table table-striped m-b-none', tableClassName: 'table table-striped m-b-none',
taskNameLabel: '任务名称', taskNameLabel: '任务名称',
operationLabel: '操作', operationLabel: 'Table.operation',
statusLabel: '状态', statusLabel: '状态',
remarkLabel: '备注说明', remarkLabel: '备注说明',
btnText: '上线', btnText: '上线',
@ -370,6 +370,7 @@ export default class Task extends React.Component<TaskProps, TaskState> {
readyStatusCode, readyStatusCode,
loadingStatusCode, loadingStatusCode,
canRetryStatusCode, canRetryStatusCode,
translate: __,
render render
} = this.props; } = this.props;
const items = this.state.items; const items = this.state.items;
@ -381,7 +382,7 @@ export default class Task extends React.Component<TaskProps, TaskState> {
<thead> <thead>
<tr> <tr>
<th>{taskNameLabel}</th> <th>{taskNameLabel}</th>
<th>{operationLabel}</th> <th>{__(operationLabel)}</th>
<th>{statusLabel}</th> <th>{statusLabel}</th>
<th>{remarkLabel}</th> <th>{remarkLabel}</th>
</tr> </tr>

View File

@ -174,10 +174,10 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
readOnly: false, readOnly: false,
messages: {}, messages: {},
actionClassName: '', actionClassName: '',
actionPrevLabel: '上一步', actionPrevLabel: 'Wizard.prev',
actionNextLabel: '下一步', actionNextLabel: 'Wizard.next',
actionNextSaveLabel: '保存并下一步', actionNextSaveLabel: 'Wizard.saveAndNext',
actionFinishLabel: '完成' actionFinishLabel: 'Wizard.finish'
}; };
static propsList: Array<string> = [ static propsList: Array<string> = [
@ -916,7 +916,8 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
classPrefix: ns, classPrefix: ns,
classnames: cx, classnames: cx,
popOverContainer, popOverContainer,
mode mode,
translate: __
} = this.props; } = this.props;
const currentStep = this.state.currentStep; const currentStep = this.state.currentStep;
@ -962,9 +963,9 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
} }
) )
) : currentStep === -1 ? ( ) : currentStep === -1 ? (
'初始中。。' __('loading')
) : ( ) : (
<p className="text-danger"></p> <p className="text-danger">{__('Wizard.configError')}</p>
)} )}
</div> </div>
{this.renderFooter()} {this.renderFooter()}

View File

@ -192,7 +192,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
if (!json.ok) { if (!json.ok) {
self.updateMessage( self.updateMessage(
json.msg || options.errorMessage || self.__('获取失败'), json.msg || options.errorMessage || self.__('CRUD.fetchFailed'),
true true
); );
getEnv(self).notify( getEnv(self).notify(
@ -207,9 +207,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
); );
} else { } else {
if (!json.data) { if (!json.data) {
throw new Error( throw new Error(self.__('CRUD.invalidData'));
self.__('返回数据格式不正确payload.data 没有数据')
);
} }
self.updatedAt = Date.now(); self.updatedAt = Date.now();
@ -243,9 +241,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
} }
if (!Array.isArray(items)) { if (!Array.isArray(items)) {
throw new Error( throw new Error(self.__('CRUD.invalidArray'));
self.__('返回数据格式不正确payload.data.items 必须是数组')
);
} else { } else {
// 确保成员是对象。 // 确保成员是对象。
items.map((item: any) => items.map((item: any) =>
@ -375,7 +371,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
if (!json.ok) { if (!json.ok) {
self.updateMessage( self.updateMessage(
json.msg || options.errorMessage || self.__('保存失败'), json.msg || options.errorMessage || self.__('saveFailed'),
true true
); );
getEnv(self).notify( getEnv(self).notify(

View File

@ -304,7 +304,9 @@ export const FormStore = ServiceStore.named('FormStore')
} }
self.updateMessage( self.updateMessage(
json.msg || `${msgs.join('\n')}` || self.__('验证错误'), json.msg ||
`${msgs.join('\n')}` ||
self.__('Form.validateFailed'),
true true
); );
} else { } else {
@ -391,9 +393,9 @@ export const FormStore = ServiceStore.named('FormStore')
let valid = yield validate(hooks); let valid = yield validate(hooks);
if (!valid) { if (!valid) {
const msg = failedMessage ?? self.__('表单验证失败,请仔细检查'); const msg = failedMessage ?? self.__('Form.validateFailed');
msg && getEnv(self).notify('error', msg); msg && getEnv(self).notify('error', msg);
throw new Error(self.__('验证失败')); throw new Error(self.__('Form.validateFailed'));
} }
if (fn) { if (fn) {

View File

@ -474,7 +474,7 @@ export const FormItemStore = StoreNode.named('FormItemStore')
if (!json.ok) { if (!json.ok) {
setErrorFlag !== false && setErrorFlag !== false &&
setError( setError(
self.__('加载选项失败,原因:{{reason}}', { self.__('Form.loadOptionsFailed', {
reason: json.msg || (config && config.errorMessage) reason: json.msg || (config && config.errorMessage)
}) })
); );

View File

@ -133,7 +133,7 @@ export const ServiceStore = iRendererStore
e.stack && console.error(e.stack); e.stack && console.error(e.stack);
let message = e.message || e; let message = e.message || e;
if (e && e.message === 'Network Error') { if (e && e.message === 'Network Error') {
message = self.__('网络错误,可能是未配置跨域 CORS'); message = self.__('networkError');
} }
env.notify('error', message); env.notify('error', message);
return; return;
@ -226,7 +226,7 @@ export const ServiceStore = iRendererStore
e.stack && console.error(e.stack); e.stack && console.error(e.stack);
let message = e.message || e; let message = e.message || e;
if (e && e.message === 'Network Error') { if (e && e.message === 'Network Error') {
message = self.__('网络错误,可能是未配置跨域 CORS'); message = self.__('networkError');
} }
env.notify('error', message); env.notify('error', message);
return; return;
@ -270,7 +270,7 @@ export const ServiceStore = iRendererStore
updateMessage( updateMessage(
json.msg || json.msg ||
(options && options.errorMessage) || (options && options.errorMessage) ||
self.__('保存失败'), self.__('saveFailed'),
true true
); );
throw new ServerError(self.msg, json); throw new ServerError(self.msg, json);
@ -364,7 +364,7 @@ export const ServiceStore = iRendererStore
updateMessage( updateMessage(
json.msg || json.msg ||
(options && options.errorMessage) || (options && options.errorMessage) ||
self.__('获取失败,请重试'), self.__('fetchFailed'),
true true
); );
getEnv(self).notify( getEnv(self).notify(
@ -413,7 +413,7 @@ export const ServiceStore = iRendererStore
e.stack && console.error(e.stack); e.stack && console.error(e.stack);
let message = e.message || e; let message = e.message || e;
if (e && e.message === 'Network Error') { if (e && e.message === 'Network Error') {
message = self.__('网络错误,可能是未配置跨域 CORS'); message = self.__('networkError');
} }
env.notify('error', message); env.notify('error', message);
} }

View File

@ -222,32 +222,32 @@ export function addRule(
export const validateMessages: { export const validateMessages: {
[propName: string]: string; [propName: string]: string;
} = { } = {
isEmail: 'Email 格式不正确', isEmail: 'validate.isEmail',
isRequired: '这是必填项', isRequired: 'validate.isRequired',
isUrl: 'Url 格式不正确', isUrl: 'validate.isUrl',
isInt: '请输入整型数字', isInt: 'validate.isInt',
isAlpha: '请输入字母', isAlpha: 'validate.isAlpha',
isNumeric: '请输入数字', isNumeric: 'validate.isNumeric',
isAlphanumeric: '请输入字母或者数字', isAlphanumeric: 'validate.isAlphanumeric',
isFloat: '请输入浮点型数值', isFloat: 'validate.isFloat',
isWords: '请输入字母', isWords: 'validate.isWords',
isUrlPath: '只能输入字母、数字、`-` 和 `_`.', isUrlPath: 'validate.isUrlPath',
matchRegexp: '格式不正确, 请输入符合规则为 `${1|raw}` 的内容。', matchRegexp: 'validate.matchRegexp',
minLength: '请输入更多的内容,至少输入 $1 个字符。', minLength: 'validate.minLength',
maxLength: '请控制内容长度, 不要输入 $1 个字符以上', maxLength: 'validate.maxLength',
maximum: '当前输入值超出最大值 $1请检查', maximum: 'validate.maximum',
lt: '请输入小于 $1 的值', lt: 'validate.lt',
minimum: '当前输入值低于最小值 $1请检查', minimum: 'validate.minimum',
gt: '请输入大于 $1 的值', gt: 'validate.gt',
isJson: '请检查 Json 格式。', isJson: 'validate.isJson',
isLength: '请输入长度为 $1 的内容', isLength: 'validate.isLength',
notEmptyString: '请不要全输入空白字符', notEmptyString: 'validate.notEmptyString',
equalsField: '输入的数据与 $1 值不一致', equalsField: 'validate.equalsField',
equals: '输入的数据与 $1 不一致', equals: 'validate.equals',
isPhoneNumber: '请输入合法的手机号码', isPhoneNumber: 'validate.isPhoneNumber',
isTelNumber: '请输入合法的电话号码', isTelNumber: 'validate.isTelNumber',
isZipcode: '请输入合法的邮编地址', isZipcode: 'validate.isZipcode',
isId: '请输入合法的身份证号' isId: 'validate.isId'
}; };
export function validate( export function validate(