# 国际化概述
> 金蝶云苍穹与国际习惯对接，便于外籍人员使用。针对于金蝶云苍穹国际化实现，金蝶编写了一些接口以便获取相关国际化设置信息，提供快速实现国际化，并制定了相应的多语言规范，研发过程中，需遵守相应规范。

-----------------------------------------------------------------------------------------

## 获取用户时区

> **说明：目前用户时区主要包含网页版时区和移动版时区**

### 1.获取用户时区

##### 接口名：getUserTimezone
> 获取用户时区时，可以调用微服务方法`IInteService:getUserTimezone(userId)`获取，需要传入用户的id，由接口从上下文信息中自己判断获取的是移动版还是用户版，具体实现类为：`InteServiceImpl`；

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|


**返回值说明：**

返回的是时区的动态对象`DynamicObject`，基本相关数据说明如下，详细具体参数请查看inte_timezone元数据

|字段 | 类型 | 说明|
|---|---|---|
|id | Long | 记录id|
|name | String | 名称|
|number | String | 编码|
|timedif | Integer | 时差|


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
DynamicObject result = service.getUserTimezone(userId);
```


### 2.获取网页版或者移动版时区

##### 接口名：getUserTimezone

> 如果想自定义获取网页版或者是移动版时区，则调用`IInteService:getUserTimezone(userId, clientType)`；

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|
|clientType | String | 是 | 客户端类型|

*clientType可以取值如下*
```java
public class Clients {
    public static final String WEB = "web";
    public static final String WEBSERVICE = "webservice";
    public static final String API = "api";
    public static final String MOBILE = "mobile";
    public static final String BATCH = "batch";
    public static final String WORKFLOW = "workflow";
    public static final String CHAT = "chat";
    public static final String TRIPSI = "TRIPSI";
    public static final String MQ = "MQ";
}

```

**返回值说明：**

 返回的是时区的动态对象`DynamicObject`，基本相关数据说明如下，详细具体参数请查看inte_timezone元数据

|字段 | 类型 | 说明|
|---|---|---|
|id | Long | 记录id|
|name | String | 名称|
|number | String | 编码|
|timedif | Integer | 时差|


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
DynamicObject result = service.getUserTimezone(userId, Clients.WEB);

```

***特别说明：只有传入`Clients.MOBILE`会取移动时区，其它值则统一返回网页版时区***

-----------------------------------------------------------------------------------------

## 获取系统时区

##### 接口名：getSysTimezone

> 获取系统时区时，可以调用微服务方法`IInteService:getSysTimezone()`，不用参数，方法实现在`InteServiceImpl`实现类中，查询到数据之后直接返回系统时区的`DynamicObject`对象；*特别注意：该方法查不到数据会返回`null`,所以需要上层应用自行判断*


**返回值说明：**

 返回的是时区的动态对象`DynamicObject`，基本相关数据说明如下，详细具体参数请查看 inte_timezone 元数据

|字段 | 类型 | 说明|
|---|---|---|
|id | Long | 记录id|
|name | String | 名称|
|number | String | 编码|
|timedif | Integer | 时差|

**代码示例：**

```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
DynamicObject result = service.getSysTimezone();
```

-----------------------------------------------------------------------------------------

## 获取组织时区

##### 接口名：getOrgTimezone
> 获取组织时区，可以调用微服务方法`IInteService:getOrgTimezone(Long orgId)`，传入组织的`Long`型`id`即可，方法实现在`InteServiceImpl`实现类中，查询到数据之后直接返回组织时区的`DynamicObject`对象,如果组织时区不存在，则会返回系统时区；*特别注意：该方法查不到数据会返回`null`,所以需要上层应用自行判断*


**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|orgId | Long | 是 | 组织ID|


**返回值说明：**

 返回的是时区的动态对象`DynamicObject`，基本相关数据说明如下，详细具体参数请查看inte_timezone元数据

|字段 | 类型 | 说明|
|---|---|---|
|id | Long | 记录id|
|name | String | 名称|
|number | String | 编码|
|timedif | Integer | 时差|

**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
DynamicObject result = service.getOrgTimezone(orgId);
```

-----------------------------------------------------------------------------------------

## 获取职能组织时区

##### 接口名：getBizOrgTimezone
> 获取职能组织时区，可以调用微服务方法`IInteService:getBizOrgTimezone(Long orgId)`，传入职能组织的`Long`型`id`即可，方法实现在`InteServiceImpl`实现类中，查询到数据之后直接返回职能组织时区的`DynamicObject`对象,如果时区不存在，则会返回系统时区；*特别注意：该方法查不到数据会返回`null`,所以需要上层应用自行判断*

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|orgId | Long | 是 | 组织ID|


**返回值说明：**

 返回的是时区的动态对象`DynamicObject`，基本相关数据说明如下，详细具体参数请查看inte_timezone元数据

|字段 | 类型 | 说明|
|---|---|---|
|id | Long | 记录id|
|name | String | 名称|
|number | String | 编码|
|timedif | Integer | 时差|


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
DynamicObject result = service.getBizOrgTimezone(orgId);
```
-----------------------------------------------------------------------------------------

## 获取用户国际化设置

##### 接口名：getUserFormat
> 获取用户国际化设置，可以调用微服务方法`IInteService:getUserFormat(Long userID)`，方法实现在`InteServiceImpl`实现类中

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|

**返回值说明：**

key/value的Map数据，详细说明如下

```json
{
	"currencyFormat": {               // 币别格式
		"cnyShowPrefix": "1",           // 货币前缀是否显示
		"currPosFormat": ",¥",          // 正数格式
		"decimalPoint": ".",            // 小数点
		"demoCurrency": DynamicObject,  // 演示币别实体对象
		"negativeFormat": "¥-,",        // 负数格式
		"numGroupFormat": "#,####,####",      // 数字分组格式
		"numSeparator": ",",      // 分隔符
		"zeroShow": "1"           // 零起始位置
	},
	"dateFormat": "yyyy-MM-dd",      // 日期格式
	"numberFormat": {                // 数字格式
		"decimalPoint": ".",           // 小数点
		"negativeFormat": "-,",        // 负数格式
		"numGroupFormat": "#,####,####",  // 数字分组格式
		"numSeparator": ",",      // 数组分组符号
		"zeroShow": "1"           // 零起始位置
	},
	"timeFormat": {      // 时间格式
		"am": "上午",      // 上午符号
		"pm": "下午",      // 下午符号
		"timeFormat": "a h:mm:ss"    // 时间格式信息
	}
}

```

**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.getUserFormat(userId);
```

-----------------------------------------------------------------------------------------

## 修改或更新用户时区

> **说明：目前用户时区主要包含网页版时区和移动版时区**

### 1.修改或更新用户时区

#####  接口名：saveUserTimezone
> 修改或更新用户时区设置，可以调用微服务方法`IInteService:saveUserTimezone(Long userID, DynamicObject timezone)`，该方法中会自行判断保存的是网页版时区还是手机移动时区，方法实现在`InteServiceImpl`实现类中

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|
|timezone | DynamicObject | 是 | 时区信息，对应的实体为inte_timezone|


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
service.saveUserTimezone(userId, timezone);
```


### 2.自定义修改或更新用户时区类型(网页版和移动版)

#####  接口名：saveUserTimezone
> 想自定义修改或更新用户时区类型(网页版和移动版)，可以调用微服务方法`IInteService:saveUserTimezone(Long userID, DynamicObject timezone, String clientType)`，方法实现在`InteServiceImpl`实现类中；

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|
|timezone | DynamicObject | 是 | 时区信息，对应的实体为inte_timezone|
|clientType | String | 是 | 时区类型|


*clientType可以取值如下*
```java
public class Clients {
    public static final String WEB = "web";
    public static final String WEBSERVICE = "webservice";
    public static final String API = "api";
    public static final String MOBILE = "mobile";
    public static final String BATCH = "batch";
    public static final String WORKFLOW = "workflow";
    public static final String CHAT = "chat";
    public static final String TRIPSI = "TRIPSI";
    public static final String MQ = "MQ";
}

```

**代码示例：**
```java
// 保存网页版时区调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
service.saveUserTimezone(userId, timezone, Clients.WEB);
```

-----------------------------------------------------------------------------------------

## 修改或更新业务单元时区

#####  接口名：saveOrgTimezone
> 保存业务单元时区，可以调用微服务方法`IInteService:saveOrgTimezone(Long orgID, DynamicObject timezone)`，方法实现在`InteServiceImpl`实现类中

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|orgID | Long | 是 | 组织ID|
|timezone | DynamicObject | 是 | 时区信息，对应的实体为inte_timezone|


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
service.saveOrgTimezone(orgID, timezone);
```

-----------------------------------------------------------------------------------------

## 获取用户日期格式

#####  接口名：getDateFormat
> 获取用户日期格式，可以调用微服务方法`IInteService:getDateFormat (Long userId);`，方法实现在`InteServiceImpl`实现类中，改方法优先返回用户自定义日期格式，其次是方案格式，以上两种都没有那就返回默认格式，如果以上都没有，那就返回空字符串

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|


**返回值说明：**

String类型的日期格式信息,如：yyyy-MM-dd等

**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
String dateFormat = service.getDateFormat(userId);
```


-----------------------------------------------------------------------------------------

## 获取用户时间格式

#####  接口名：getTimeFormat
> 获取用户时间格式，可以调用微服务方法`IInteService:getTimeFormat (Long userId);`，方法实现在`InteServiceImpl`实现类中，改方法优先返回用户自定义日期格式，其次是方案格式，以上两种都没有那就返回默认格式，如果以上都没有，那就返回空字符串

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|

**返回值说明：**

key/value的Map数据，详细说明如下

```json
{    
	"am": "上午",      // 上午符号
	"pm": "下午",      // 下午符号
	"timeFormat": "a h:mm:ss"    // 时间格式信息
}

```


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.getDateFormat(userId);
```
-----------------------------------------------------------------------------------------

## 获取用户数字格式

#####  接口名：getNumberFormat
> 获取用户数字格式，可以调用微服务方法`IInteService:getNumberFormat(Long userId,int precision);`，方法实现在`InteServiceImpl`实现类中，改方法优先返回用户自定义数据格式，其次是方案格式，以上两种都没有那就返回默认格式，如果以上都没有，那就返回空Map

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|
|precision | Long | 是 | 精度，必传，但是目前没有用到,随意写个int型数据即可|

**返回值说明：**

key/value的Map数据，详细说明如下

```json
{             
  "decimalPoint": ".",           // 小数点
  "negativeFormat": "-,",        // 负数格式
  "numGroupFormat": "#,####,####",  // 数字分组格式
  "numSeparator": ",",      // 数组分组符号
  "zeroShow": "1"           // 零起始位置
}
```


**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.getNumberFormat(userId, precision);
```

-----------------------------------------------------------------------------------------

## 获取用户币别格式

#####  接口名：getCurrencyFormat
> 获取用户币别格式，可以调用微服务方法`IInteService:getCurrencyFormat(Long userId);`，方法实现在`InteServiceImpl`实现类中，改方法优先返回用户自定义币别格式，其次是方案格式，以上两种都没有那就返回默认格式，如果以上都没有，那就返回空Map

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|userId | Long | 是 | 用户ID|

**返回值说明：**

key/value的Map数据，如果数据不存在，则返回空map,详细说明如下

```json
 {        
		"cnyShowPrefix": "1",           // 货币前缀是否显示
		"currPosFormat": ",¥",          // 正数格式
		"decimalPoint": ".",            // 小数点
		"demoCurrency": DynamicObject,  // 演示币别实体对象
		"negativeFormat": "¥-,",        // 负数格式
		"numGroupFormat": "#,####,####",      // 数字分组格式
		"numSeparator": ",",      // 分隔符
		"zeroShow": "1"           // 零起始位置
	}
```

**代码示例：**
```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.getCurrencyFormat(userId);
```

-----------------------------------------------------------------------------------------

## 获取区域格式

#####  接口名：getFormat
> 获取区域格式，可以调用微服务方法`IInteService:getFormat(Long formatId);`，方法实现在`InteServiceImpl`实现类中,如果传0则返回默认的区域格式，如果格式不存在那就返回空Map

**参数说明：**

|参数名称 | 数据类型 | 必选 | 说明|
|---|---|---|---|
|formatId | Long | 是 | 区域格式ID，如果传0则返回默认的区域格式|

**返回值说明：**

key/value的Map数据,如果格式不存在那就返回空Map，详细说明如下

```json
{
	"currencyFormat": {               // 币别格式
		"cnyShowPrefix": "1",           // 货币前缀是否显示
		"currPosFormat": ",¥",          // 正数格式
		"decimalPoint": ".",            // 小数点
		"demoCurrency": 534759879745980,  // 演示币别实体对象id
		"negativeFormat": "¥-,",        // 负数格式
		"numGroupFormat": "#,####,####",      // 数字分组格式
		"numSeparator": ",",      // 分隔符
		"zeroShow": "1"           // 零起始位置
	},
	"dateFormat": "yyyy-MM-dd",      // 日期格式
	"numberFormat": {                // 数字格式
		"decimalPoint": ".",           // 小数点
		"negativeFormat": "-,",        // 负数格式
		"numGroupFormat": "#,####,####",  // 数字分组格式
		"numSeparator": ",",      // 数组分组符号
		"zeroShow": "1"           // 零起始位置
	},
	"timeFormat": {      // 时间格式
		"am": "上午",      // 上午符号
		"pm": "下午",      // 下午符号
		"timeFormat": "a h:mm:ss"    // 时间格式信息
	}
}

```

**代码示例：**

```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.getFormat(formatId);
```

-----------------------------------------------------------------------------------------


## 工作日计划中根据间隔日计算日期

#####  接口名：calculateDateByInterval
> 工作日计划中根据间隔日计算日期，可以调用微服务方法`IInteService:calculateDateByInterval(Long workingPlanId, Date date, Integer interval, Integer intervalType, Integer outputIntervalType)`，方法实现在`InteServiceImpl`实现类中,结果返回为Map<String,Object>

**参数说明：**

|参数名称           | 数据类型  | 必选 | 说明                                |
|---               |---       |---   |---                                  |
|workingPlanId     | Long     | 是   | 工作日计划id                         |
|date              | Date     | 是   | 开始计算日期                         |
|interval          | Integer  | 是   | 间隔天数，大于等于0                   |
|intervalType      | Integer  | 是   | 间隔天数类型：自然日（0）或工作日（1） |
|outputIntervalType| Integer  | 是   | 输出类型：自然日（0）或工作日（1）     |


**返回值说明：**

key/value的Map数据，详细说明如下

```json
{
	"isSuccess": true,    // 计算是否成功,如果为false,则不会返回最后三个字段
	"errorMsg": "",    // 如果计算失败，则说明计算失败的原因   
	"date" : 2020-09-30,    // 返回日期
	"dateType" : 1,    // 日期类型，工作日（1），半工作日（2），休息日（3），节假日（4）
	"workRangeList" : [    // 工作时段
		{
			"starttime": 32400,    // 工作时段开始时间
			"endtime": 43200    // 工作时段结束时间
		},
		{
			"starttime": 46800,
			"endtime": 64800
		}
	],
}

```

**代码示例：**

```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.calculateDateByInterval(1L,new Date(),1,1,1);
```

-----------------------------------------------------------------------------------------


## 工作日计划中根据开始和结束日期计算间隔日

#####  calculateDateByStartAndEndDate
> 工作日计划中根据开始和结束日期计算间隔日，可以调用微服务方法`IInteService:calculateDateByStartAndEndDate(Long workingPlanId, Date startDate, Date endDate)`，方法实现在`InteServiceImpl`实现类中,结果返回为Map<String,Object>

**参数说明：**

|参数名称       | 数据类型 | 必选 | 说明       |
|---           |---       |---  |---         |
|workingPlanId | Long     | 是  | 工作日计划id|
|startDate     | Date     | 是  | 开始日期    |
|endDate       | Date     | 是  | 结束日期    |


**返回值说明：**

key/value的Map数据，详细说明如下

```json
{
	"isSuccess": true,    // 计算是否成功,如果为false,则不会返回最后两个字段
	"errorMsg": "",    // 如果计算失败，则说明计算失败的原因   
	"calendarDayInterval" : 10,    // 间隔自然日
	"workingDayInterval" : 6,    // 间隔工作日
}

```

**代码示例：**

```java
// 调用示例
IInteService service = (IInteService)ServiceFactory.getService(IInteService.class);
Map<String, Object> fmt = service.calculateDateByStartAndEndDate(1L,new Date(),new Date());
```
-----------------------------------------------------------------------------------------

## 获取地址所属区域

`kd.bos.i18n.mservice.I18nServiceHelper` 国际化数据服务帮助类，区域查询统一使用此类调用服务接口。

------

### 1. 获取地址所属区域

##### 服务方法：getTheZone(Long zoneTypeId, Long addrId,  Date date)

> 根据区域类型、国际化地址、日期获取当前地址所属区域值。

**参数说明：**

| 参数名称   | 必填 | 数据类型 | 说明         |
| :--------- | :--- | :------- | :----------- |
| zoneTypeId | 是   | Long     | 区域类型id   |
| addrId     | 是   | Long     | 国际化地址id |
| date       | 是   | Date     | 日期         |

**返回值说明：**

返回的是 Set<Object> 类型的集合（即区域值id的集合）

**代码示例：**

~~~
Set<Object> theZone = I18nServiceHelper.getTheZone(1233869623049334784L, 1244780919038960640L, new Date());
~~~

------

### 2. 批量获取地址所属区域

##### 服务方法：getTheZoneMap(List<Long> zoneTypeIds, Long addrId,  Date date)

> 根据区域类型、国际化地址、日期批量获取当前地址所属区域值。

**参数说明：**

| 参数名称     | 必填 | 数据类型   | 说明         |
| :----------- | :--- | :--------- | :----------- |
| zoneTypeIds  | 是   | List<Long> | 区域类型ids  |
| addrId       | 是   | Long       | 国际化地址id |
| date         | 是   | Date       | 日期         |

**返回值说明：**

返回的是 Set<Object> 类型的集合（即区域值id的集合）

**代码示例：**

~~~
Set<Object> theZone = I18nServiceHelper.getTheZone(1233869623049334784L, 1244780919038960640L, new Date());
~~~

-----------------------------------------------------------------------------------------

## 汇率查询服务

`kd.bos.servicehelper.BusinessDataServiceHelper`业务数据服务帮助类，汇率查询统一使用此类调用服务接口。

------

### 1. 是否开启外币换算配置查询

##### 服务方法：isEnableIndirectRateConversion()

> 查询是否开启外币换算配置服务。

**参数说明：**

无

**返回值说明：**

布尔数据，boolean

**代码示例：**

~~~
boolean enableIndirectRate = BaseDataServiceHelper.isEnableIndirectRateConversion();
~~~

------

### 2. 币种对外币换算配置查询

##### 服务方法：getRateConversionConfig(Long originalCurrency, Long targetCurrency, Date conversionDate)

> 根据原币、目标币、折算日期，获取当前币种对使用的换算方式

**参数说明：**

| 参数名称         | 必填 | 数据类型 | 示例值     | 说明     |      |
| :--------------- | :--- | :------- | :--------- | :------- | :--- |
| originalCurrency | 是   | Long     | 112121     | 原币ID   |      |
| targetCurrency   | 是   | Long     | 212121     | 目标币ID |      |
| conversionDate   | 是   | Date     | 2021-01-01 | 折算日期 |      |

**返回值说明：**

布尔数据，boolean

**代码示例：**

~~~
boolean enableIndirectRate = BaseDataServiceHelper.getRateConversionConfig(1L, 2L, Calendar.getInstance().getTime());
~~~

------

### 3. 币种对换算方式及其汇率值查询

##### 服务方法：getExchangeRateMap(Long originalCurrency, Long targetCurrency, Long exchangeRateType, Date conversionDate)

> 根据外币换算配置，查询原币至目标币的换算方式及对应的直接/间接汇率值。

**参数说明：**

| 参数名称         | 必填 | 数据类型 | 示例值     | 说明       |
| :--------------- | :--- | :------- | :--------- | :--------- |
| originalCurrency | 是   | Long     | 1123121    | 原币ID     |
| targetCurrency   | 是   | Long     | 2121211    | 目标币ID   |
| exchangeRateType | 是   | Long     | 2212121    | 汇率类型ID |
| conversionDate   | 是   | Date     | 2021-01-01 | 折算日期   |

**返回值说明：**

| 参数名称     | 数据类型   | 示例值  | 说明                                                  |
| :----------- | :--------- | :------ | :---------------------------------------------------- |
| quoteType    | boolean    | true    | 换算方式 ( true: 使用间接汇率； false：使用直接汇率 ) |
| exchangeRate | Bigdecimal | 0.56433 | 汇率值（可为null。对应换算方式）                      |

**代码示例：**

~~~
Map<String, Object> exchangeRateByRules = BaseDataServiceHelper.getExchangeRateMap(6L, 1L, 432498951862649856L, Calendar.getInstance().getTime());
~~~

------

### 4. 币种对汇率值查询（按换算方式）

##### 服务方法：getExchangeRateByQuoteType(Long originalCurrency, Long targetCurrency, Long exchangeRateType, Date conversionDate, boolean quoteType)

> 根据换算方式，查询原币至目标币对应的汇率值。

**参数说明：**

| 参数名称         | 必填 | 数据类型 | 示例值     | 说明                |
| :--------------- | :--- | :------- | :--------- | :------------------ |
| originalCurrency | 是   | Long     | 112121     | 原币ID              |
| targetCurrency   | 是   | Long     | 231231     | 目标币ID            |
| exchangeRateType | 是   | Long     | 211111     | 汇率类型ID          |
| conversionDate   | 是   | Date     | 2021-01-01 | 折算日期            |
| quoteType        | 是   | boolean  | true       | 直接汇率 / 间接汇率 |

**返回值说明：**

数值，Bigdecimal

**代码示例：**

~~~
Bigdecimal rate = BaseDataServiceHelper.getExchangeRateByDirection(6L, 1L, 432498951862649856L, Calendar.getInstance().getTime(), true);
~~~

------



## 硬编码多语言化（仅针对于Java语言）

> 说明：支持多语言的应用，研发过程必须遵循[多语言开发规范（最新版）](https://club.kdcloud.com/article/241181198498975488)。不规范的代码，会导致翻译质量不高、未翻译问题。同时，翻译平台提供了代码转换工具、硬编码扫描工具来提取硬编码和检查代码规范。
### 1 硬编码规范
#### 1.1 提示语组合成一句话
例如,在写代码时，想弹窗提示“关于项目的第五次答疑”。

```java
//错误示范：
String bidanswerquestiontheme = "关于" + bidProject.getString("name") + "的第" + numberoftimes + "次答疑";
```

```java
//推荐规范：
String bidanswerquestiontheme = String.format("关于%s的第%s次答疑", bidProject.getString("name"), numberoftimes);
```
#### 1.2 静态常量规范

```java
//错误示范：使用全局变量
//声明全局变量
private static final String MSG_CANCEL_EDITNEWADMIN = "新增管理员未保存，是否放弃保存？";
this.getView().showConfirm(MSG_CANCEL_EDITNEWADMIN, MessageBoxOptions.OKCancel,new ConfirmCallBackListener(eventInfo, this));
```
```java
//推荐规范
//增加一个获取提示语的方法
private String getMsgCancleEditNewAdmin(){
	return "新增管理员未保存，是否放弃保存？";
}
//原来使用静态常量的地方修改为调用获取提示语的方法
this.getView().showConfirm(getMsgCancleEditNewAdmin(), MessageBoxOptions.OKCancel,new ConfirmCallBackListener(eventInfo, this));
```
#### 1.3 多语言字段表长度
多语言字段长度根据业务实际情况设置，一般为`500字节`

#### 1.4 预插数据中不能填写分号
如果填写了分号，在制作多语言包时，分号会被识别为两个语句而截断，导致生成的语句在执行时报错。

#### 1.5 程序提示语中的中文词条写法注意
中文词条要纯正，不要汉语然后夹杂着英文符号。

词条的开头和结尾除非特殊原因最好不要留空格。

#### 1.6 不需要多语言化处理
不需要多语言化处理的词条，需要在代码行末尾加上`/*untrans*/`,扫描工具扫描时，就会跳过该行代码，不进行扫描。
```java
private String getMsgCancleEditNewAdmin(){
	return "新增管理员未保存，是否放弃保存？";/*untrans*/
}
```

### 2 硬编码扫描工具的使用
#### 2.1 配置相关路径
配置工程所在路径，日志输出目录

#### 2.2 点击执行生成properties资源文件
工具会将生成的properties放入java工程的`src/main/java/resources`目录下，默认名称为：`工程名__zh_CN.properties`，文件内容如下(例如，工程名为`bos-int-formplugin`,类名为`FormatEditPlugin`)
```java
#Fri Oct 25 17:12:37 CST 2019
FormatEditPlugin_0=请输入正确的时间格式化字符串
```

#### 2.3 进行相关构建设置-配置gradle
工具会现import所依赖的工程，并修改有硬编码所在代码行，如下
```java
//未使用工具前
try{
		time = FormatFactory.get(FormatTypes.Time).getFormat(formatObject).format(now);
	} catch(KDException e){
	 	this.getView().showErrorNotification("请输入正确的时间格式化字符串");
	 	return;
	}		

```
```java
//使用工具扫描后
//工具自动导入所依赖的工程
import kd.bos.dataentity.resource.ResManager;
try{
		time = FormatFactory.get(FormatTypes.Time).getFormat(formatObject).format(now);
	} catch(KDException e){
	 	this.getView().showErrorNotification(ResManager.loadKDString("请输入正确的时间格式化字符串", "FormatEditPlugin_0", "bos-int-formplugin"));
	 	return;
	}			

```

进行gradle配置，如前面所述，不进行gradle配置，生成的资源文件不会构建到相应工程的jar包中，金蝶云苍穹翻译平台就抽取不到硬编码中文词条，所以需要进行配置，配置如下：


```java
//修改配置前
 task copytolib(type: Copy, dependsOn: build){
	 	group 'build'
	 	description '拷贝本工程构建jar包到lib'
		from 'build/libs'
    		into  outputdir
    		exclude '*source*.jar'
	 }
```
```java
//修改配置后
 task copytolib(type: Copy, dependsOn: build){
	 	group 'build'
	 	description '拷贝本工程构建jar包到lib'
		from 'build/libs'
    		into  outputdir
    		exclude '*source*.jar'
		processResources{
	 		from('src/main/java') {
	 		include '**/*.properties'
	 		}
	 	}
	 }
```


## 地址格式创建接口 InteServiceHelper. commitAddressConfig(AddressConfigInfo addressConfigInfo)
	 接口参数说明
		入口参数
				字段描述	    字段编码	        字段类型	长度/默认值	字段约束
				地址格式编码	addressConfigNumber	String	     25	         NULL
				地址格式名称	addressConfigName	String	     50	         NOT NULL
				所属国家列表	countryIds	        List<Long>	 30	         NOT NULL
				包含行政区划	admindivision	    boolean	     false	     NULL
				行政级次	    level	            int	         3	         NULL
				默认格式	    defaultFormat	    boolean	     false	     NULL
				字段编码	    fieldNumber	        AddressFieldEnum	/	 NULL
				展示	        show	            boolean	     0	         NULL
				必录	        mustInput	        boolean	     0	         NULL
				换行	        newLine	            boolean	     0	         NULL
				包含	        include	            boolean	     false	     NULL
				前缀	        prefix	            String	     30	         NULL
				后缀	        suffix	            String	     30	         NULL
				包含空格	    containBlank	    boolean	     false	     NULL
				属性替换编码	replaceAttrNumber	String	     30	         NULL
		出口参数
				地址格式id	    id	                Long          0	         NULL
				成功            success	            boolean	      true	     NOT NULL
				错误提示	    errMsg	            Map<String,String>hashNap	NOT NULL


​				
​				
##  地址数据迁移接口   ServiceHelper.commitAddressInfo(AddressConfigInfoaddressConfigInfo);

				字段描述	字段编码	            字段类型	字段约束	字段长度/
		出口参数：
				地址id	       id	                long	     0L	          NULL
				成功	       success	            boolean	     true	      NOT NULL
				错误提示	   errMsg	            Map<String,String>hashNap NOT NULL
		入口参数：
				地址编码	   number	            String	     NUll	      30
				地址配置格式   addressConfigId	    Long	     NOT NULL	  19
				地址来源单据   fromForm	            String	     NOT NULL	  25
				国家地区	   country				Long		 NOT NULL	  19
				行政区划	   admindivision	    Long	     NULL	       /
				街道	       street1	            String	     NUll	      255
				街道补充信息   street2	            String	     NUll	      255
				门牌号	       housenum	            String	     NUll	      50
				门牌号补充信息 houseNum2	        String	     NUll	      50
				大厦	       building	            String	     NUll	      30
				楼层	       floor	            String	     NUll	      30
				房间号	       roomNum	            String	     NUll	      30
				邮编1	       postCode1	        String	     NUll	       10
				邮编2	postcode2	String	NUll	10
				邮编3	postcode3	String	NUll	10
				邮编1扩展	postcodeext	String	NUll	10
				PO box名称	pobox	String	NUll	30
				自定义地址字段1	address1	String	NUll	255
				自定义地址字段2	address2	String	NUll	255
				自定义地址字段3	address3	String	NUll	255
				自定义地址字段4	address4	String	NUll	255
				自定义地址字段5	address5	String	NUll	255
				详细信息	detail	String	NUll	512

-----------------------------------------------------------------------------------------

## 身份证件号码校验   I18nServiceHelper.validIdentityCardNo(Long countryId, String identityNo);

				字段描述		字段编码	         字段类型		字段约束	
		出口参数：
				是否验证通过	  isSuccess	          boolean	 
				提示	   		 msg	            String    
		入口参数：
				身份证件号码	  identityNo	      String	    NOT NULL   	     
				国家或地区id    countryId	    	Long	     NOT NULL	  



-----------------------------------------------------------------------------------------

## **批量获取工作日计划的日期和日期类型**

**服务名**：**kd.bos.i18n.mservice.I18nServiceHelper.getDateByWorkingPlan(Long workingPlanId, Date startDate, Date endDate)**

**参数说明：**

| **参数名称**          | **数据类型** | **必填** | **说明**   |
| --------------------- | ------------ | -------- | ---------- |
| `**workingPlanId  **` | **Long**     | 是       | 工作日历id |
| `**startDate  **`     | **Date**     | 否       | 开始时间   |
| `**endDate**`         | **Date**     | 否       | 结束时间   |

 

**返回值说明：**

	返回值名称		数据类型										示例值										说明
	
	isSuccess		Boolean					  					true										是否成功
	
	errorMsg		String										"参数有误"				 					  错误消息
	
	data			Map<String,Object>
					Key:String									2021-11-10									字符串日期，格式为yyyy-MM-dd
					value:	Map<String,Object>
							Key:String							"datetype"			
							value:Integer						1：工作日2：半工作日3：休息日4：节假日			  日期类型
						    Key:String							"workRangeList"
						    value:List<HashMap<String, Integer>>											工作时间列表
						    	序号  名称																
								0	key:String					"startTime" 			
									value:Integer				数值：32400 含义：09:00						工作开始时间 
																											时区：Etc/GMT+0格式：HH:mm
									key:String					"endTime" 
									value:Integer				数值：43200 含义：12:00						工作结束时间



