feat: i18n

This commit is contained in:
2025-11-21 10:20:37 +08:00
parent f8d075d54b
commit 34e78d62ed
20 changed files with 2124 additions and 0 deletions

78
nl-i18n-sdk/pom.xml Normal file
View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nl</groupId>
<artifactId>nl-verify-check</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>nl-i18n-sdk</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.31.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@@ -0,0 +1,11 @@
package org.nl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LanguageApplication {
public static void main(String[] args) {
SpringApplication.run(LanguageApplication.class, args);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.common;
import org.springframework.http.HttpStatus;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
/**
* @author Zheng Jie
* @date 2018-11-23
* 统一异常处理
*/
public class BadLanguageException extends RuntimeException{
private Integer status = BAD_REQUEST.value();
public BadLanguageException(String msg){
super(msg);
}
public BadLanguageException(HttpStatus status, String msg){
super(msg);
this.status = status.value();
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -0,0 +1,113 @@
package org.nl.common;
import java.io.Serializable;
import java.util.List;
/**
* 表格分页数据对象
*
* @author Lion Li
*/
public class DataCanvers<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private long totalElements;
/**
* 列表数据
*/
private Object content;
/**
* 消息状态码
*/
private String code;
/**
* 消息内容
*/
private String msg;
/**
* 分页
*
* @param list 列表数据
* @param total 总记录数
*/
public DataCanvers(List<T> list, long total) {
this.content = list;
this.totalElements = total;
}
public static DataCanvers buildList(List list) {
DataCanvers rspData = new DataCanvers<>();
rspData.setCode(String.valueOf(HttpStatus.OK.value()));
rspData.setMsg("查询成功");
rspData.setContent(list);
rspData.setTotalElements(list.size());
return rspData;
}
public static <T> DataCanvers<T> build() {
DataCanvers<T> rspData = new DataCanvers<>();
rspData.setCode(String.valueOf(HttpStatus.OK.value()));
rspData.setMsg("查询成功");
return rspData;
}
public static <T> DataCanvers<T> buildJson(Object result) {
DataCanvers<T> rspData = new DataCanvers<>();
rspData.setCode(String.valueOf(HttpStatus.OK.value()));
rspData.setContent(result);
rspData.setMsg("操作成功");
return rspData;
}
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public DataCanvers() {
this.totalElements = totalElements;
}
public DataCanvers(long totalElements, Object content, String code, String msg) {
this.totalElements = totalElements;
this.content = content;
this.code = code;
this.msg = msg;
}
}

View File

@@ -0,0 +1,139 @@
package org.nl.common;
public enum HttpStatus {
CONTINUE(100, org.springframework.http.HttpStatus.Series.INFORMATIONAL, "Continue"),
SWITCHING_PROTOCOLS(101, org.springframework.http.HttpStatus.Series.INFORMATIONAL, "Switching Protocols"),
PROCESSING(102, org.springframework.http.HttpStatus.Series.INFORMATIONAL, "Processing"),
CHECKPOINT(103, org.springframework.http.HttpStatus.Series.INFORMATIONAL, "Checkpoint"),
OK(200, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "OK"),
CREATED(201, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Created"),
ACCEPTED(202, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Accepted"),
NON_AUTHORITATIVE_INFORMATION(203, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Non-Authoritative Information"),
NO_CONTENT(204, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "No Content"),
RESET_CONTENT(205, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Reset Content"),
PARTIAL_CONTENT(206, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Partial Content"),
MULTI_STATUS(207, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Multi-Status"),
ALREADY_REPORTED(208, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "Already Reported"),
IM_USED(226, org.springframework.http.HttpStatus.Series.SUCCESSFUL, "IM Used"),
MULTIPLE_CHOICES(300, org.springframework.http.HttpStatus.Series.REDIRECTION, "Multiple Choices"),
MOVED_PERMANENTLY(301, org.springframework.http.HttpStatus.Series.REDIRECTION, "Moved Permanently"),
FOUND(302, org.springframework.http.HttpStatus.Series.REDIRECTION, "Found"),
/** @deprecated */
@Deprecated
MOVED_TEMPORARILY(302, org.springframework.http.HttpStatus.Series.REDIRECTION, "Moved Temporarily"),
SEE_OTHER(303, org.springframework.http.HttpStatus.Series.REDIRECTION, "See Other"),
NOT_MODIFIED(304, org.springframework.http.HttpStatus.Series.REDIRECTION, "Not Modified"),
/** @deprecated */
@Deprecated
USE_PROXY(305, org.springframework.http.HttpStatus.Series.REDIRECTION, "Use Proxy"),
TEMPORARY_REDIRECT(307, org.springframework.http.HttpStatus.Series.REDIRECTION, "Temporary Redirect"),
PERMANENT_REDIRECT(308, org.springframework.http.HttpStatus.Series.REDIRECTION, "Permanent Redirect"),
BAD_REQUEST(400, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Bad Request"),
UNAUTHORIZED(401, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Unauthorized"),
PAYMENT_REQUIRED(402, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Payment Required"),
FORBIDDEN(403, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Forbidden"),
NOT_FOUND(404, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Not Found"),
METHOD_NOT_ALLOWED(405, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Method Not Allowed"),
NOT_ACCEPTABLE(406, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Not Acceptable"),
PROXY_AUTHENTICATION_REQUIRED(407, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Proxy Authentication Required"),
REQUEST_TIMEOUT(408, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Request Timeout"),
CONFLICT(409, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Conflict"),
GONE(410, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Gone"),
LENGTH_REQUIRED(411, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Length Required"),
PRECONDITION_FAILED(412, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Precondition Failed"),
PAYLOAD_TOO_LARGE(413, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Payload Too Large"),
/** @deprecated */
@Deprecated
REQUEST_ENTITY_TOO_LARGE(413, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Request Entity Too Large"),
URI_TOO_LONG(414, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "URI Too Long"),
/** @deprecated */
@Deprecated
REQUEST_URI_TOO_LONG(414, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Request-URI Too Long"),
UNSUPPORTED_MEDIA_TYPE(415, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Unsupported Media Type"),
REQUESTED_RANGE_NOT_SATISFIABLE(416, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Requested range not satisfiable"),
EXPECTATION_FAILED(417, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Expectation Failed"),
I_AM_A_TEAPOT(418, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "I'm a teapot"),
/** @deprecated */
@Deprecated
INSUFFICIENT_SPACE_ON_RESOURCE(419, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Insufficient Space On Resource"),
/** @deprecated */
@Deprecated
METHOD_FAILURE(420, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Method Failure"),
/** @deprecated */
@Deprecated
DESTINATION_LOCKED(421, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Destination Locked"),
UNPROCESSABLE_ENTITY(422, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Unprocessable Entity"),
LOCKED(423, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Locked"),
FAILED_DEPENDENCY(424, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Failed Dependency"),
TOO_EARLY(425, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Too Early"),
UPGRADE_REQUIRED(426, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Upgrade Required"),
PRECONDITION_REQUIRED(428, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Precondition Required"),
TOO_MANY_REQUESTS(429, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Too Many Requests"),
REQUEST_HEADER_FIELDS_TOO_LARGE(431, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Request Header Fields Too Large"),
UNAVAILABLE_FOR_LEGAL_REASONS(451, org.springframework.http.HttpStatus.Series.CLIENT_ERROR, "Unavailable For Legal Reasons"),
INTERNAL_SERVER_ERROR(500, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Internal Server Error"),
NOT_IMPLEMENTED(501, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Not Implemented"),
BAD_GATEWAY(502, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Bad Gateway"),
SERVICE_UNAVAILABLE(503, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Service Unavailable"),
GATEWAY_TIMEOUT(504, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Gateway Timeout"),
HTTP_VERSION_NOT_SUPPORTED(505, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "HTTP Version not supported"),
VARIANT_ALSO_NEGOTIATES(506, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Variant Also Negotiates"),
INSUFFICIENT_STORAGE(507, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Insufficient Storage"),
LOOP_DETECTED(508, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Loop Detected"),
BANDWIDTH_LIMIT_EXCEEDED(509, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Bandwidth Limit Exceeded"),
NOT_EXTENDED(510, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Not Extended"),
NETWORK_AUTHENTICATION_REQUIRED(511, org.springframework.http.HttpStatus.Series.SERVER_ERROR, "Network Authentication Required");
private static final HttpStatus[] VALUES = values();
private final int value;
private final org.springframework.http.HttpStatus.Series series;
private final String reasonPhrase;
private HttpStatus(int value, org.springframework.http.HttpStatus.Series series, String reasonPhrase) {
this.value = value;
this.series = series;
this.reasonPhrase = reasonPhrase;
}
public int value() {
return this.value;
}
public org.springframework.http.HttpStatus.Series series() {
return this.series;
}
public String getReasonPhrase() {
return this.reasonPhrase;
}
public boolean is1xxInformational() {
return this.series() == org.springframework.http.HttpStatus.Series.INFORMATIONAL;
}
public boolean is2xxSuccessful() {
return this.series() == org.springframework.http.HttpStatus.Series.SUCCESSFUL;
}
public boolean is3xxRedirection() {
return this.series() == org.springframework.http.HttpStatus.Series.REDIRECTION;
}
public boolean is4xxClientError() {
return this.series() == org.springframework.http.HttpStatus.Series.CLIENT_ERROR;
}
public boolean is5xxServerError() {
return this.series() == org.springframework.http.HttpStatus.Series.SERVER_ERROR;
}
public boolean isError() {
return this.is4xxClientError() || this.is5xxServerError();
}
public String toString() {
return this.value + " " + this.name();
}
}

View File

@@ -0,0 +1,36 @@
package org.nl.language;
import org.nl.language.engine.I18nManagerService;
import org.springframework.util.StringUtils;
public class LangBehavior {
public static I18nManagerService i18nManagerService;
/**
* 不带从参数
* @param keycommon.paramException
* @return
*/
public static String language(String key) {
if(StringUtils.isEmpty(key)){
return "";
}
return i18nManagerService.language(key);
}
/**
* 带参数的解析
* @param keycommon.paramException
* @param arg: 替换语言输出中的占位符:数据异常,${0}信息不存在
* @return
*/
public static String language(String key, String...arg) {
if(StringUtils.isEmpty(key)){
return "";
}
String language = i18nManagerService.language(key);
String format = String.format(language, arg);
return format;
}
}

View File

@@ -0,0 +1,85 @@
package org.nl.language.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import org.nl.language.engine.I18nManagerService;
import org.nl.common.BadLanguageException;
import org.nl.common.DataCanvers;
import org.nl.language.LangBehavior;
import org.nl.language.engine.dto.LanguageDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@RestController
@RequestMapping("/api/language")
public class langController {
@Autowired
private I18nManagerService i18nManagerService;
/**
* 查询code对应结构
* @param languageDto
* @return
*/
@PostMapping("/structure")
@SaIgnore
public ResponseEntity<Object> query(@RequestBody LanguageDto languageDto) {
JSONObject langJs = i18nManagerService.langCache.get(languageDto.getLanguage());
if (langJs ==null){
throw new BadLanguageException(LangBehavior.language("system.dataExceptionArg",languageDto.getLanguage()));
}
Set<Map.Entry<String, Object>> entries = langJs.entrySet();
Map<String, Object> map = new HashMap<>();
for (Map.Entry<String, Object> entry : entries) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String){
if (key.equals(languageDto.getCode())){
map.put(key,value);
}
}
if (value instanceof JSONObject){
keyRecursion(languageDto.getCode(),(JSONObject) value,key,map);
}
}
return new ResponseEntity<>(DataCanvers.buildJson(map), HttpStatus.OK);
}
private void keyRecursion(String target,JSONObject langJs,String pKey,Map<String, Object> keyRecursion){
Set<Map.Entry<String, Object>> entries = langJs.entrySet();
for (Map.Entry<String, Object> entry : entries) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String){
if (key.equals(target)){
keyRecursion.put(pKey+"."+entry.getKey(),value);
}
}else if (value instanceof JSONObject){
keyRecursion(target,(JSONObject) value,pKey+"."+entry.getKey(),keyRecursion);
}
}
}
/**
* 查询语言列表
* @return
*/
@PostMapping("/list")
@SaIgnore
public ResponseEntity<Object> query() {
Set<String> langs = i18nManagerService.langCache.keySet();
Map<String, String> map = new HashMap<>();
for (String lang : langs) {
JSONObject langJs = i18nManagerService.langCache.get(lang);
String language = langJs.getString("language");
map.put(lang,language);
}
return new ResponseEntity<>(DataCanvers.buildJson(map), HttpStatus.OK);
}
}

View File

@@ -0,0 +1,106 @@
package org.nl.language.engine;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.nl.language.LangBehavior;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
@Service
public class I18nManagerService implements InitializingBean, DisposableBean {
private final I18nProperties properties;
public final Map<String, JSONObject> langCache = new HashMap<>();
private final Map<String, String> filePaths = new HashMap<>();
private ScheduledExecutorService scheduler;
public I18nManagerService(I18nProperties properties) {
System.out.println("I18nManagerService开始加载"+properties.toString());
this.properties = properties;
}
@Override
public void afterPropertiesSet() throws Exception {
// 加载所有语言文件
for (String lang : properties.getSupportedLanguages()) {
loadLangFile(lang);
}
LangBehavior.i18nManagerService = this;
}
// 以下为原有方法(保持不变)
private void loadLangFile(String lang) throws IOException {
String fileName = lang + ".js";
String fullPath = properties.getLocation() + fileName;
Resource resource = getResource(fullPath);
if (!resource.exists() && properties.isFallbackToClasspath()) {
fullPath = "language/i18n/" + fileName;
resource = new ClassPathResource(fullPath);
System.out.println("文件名"+resource.getFilename());
}
if (!resource.exists()) {
throw new IOException("Language file not found: " + fullPath);
}
InputStream inputStream = resource.getInputStream();
byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
String content = new String(bytes, StandardCharsets.UTF_8);
String jsonStr = content.replace("var config = ","").trim();
JSONObject config = JSON.parseObject(jsonStr);
langCache.put(lang, config);
filePaths.put(lang, fullPath);
inputStream.close();
}
private Resource getResource(String path) {
System.out.println("文件加载路径"+path);
if (path.startsWith("file:")) {
return new FileSystemResource(path.substring("file:".length()));
} else if (path.startsWith("classpath:")) {
return new ClassPathResource(path.substring("classpath:".length()));
} else {
return new FileSystemResource(path);
}
}
public String language(String key) {
String lang = LangContextHolder.getLangOrDefault();
JSONObject config = langCache.get(lang);
if (config == null) {
return "";
}
String[] keyParts = key.split("\\.");
JSONObject current = config;
for (int i = 0; i < keyParts.length; i++) {
if (i == keyParts.length - 1) {
return StringUtils.isEmpty(current.getString(keyParts[i])) ? key : current.getString(keyParts[i]);
}
current = current.getJSONObject(keyParts[i]);
if (current == null) {
return key;
}
}
return key;
}
@Override
public void destroy() {
if (scheduler != null) {
scheduler.shutdown();
}
langCache.clear();
filePaths.clear();
}
}

View File

@@ -0,0 +1,62 @@
package org.nl.language.engine;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "i18n")
public class I18nProperties {
// 语言文件存放路径可以是外部路径或classpath
private String location = "C:\\i18n\\";
// 热更新检查间隔(秒)
private long refreshInterval = 60;
// 支持的语言列表
private List<String> supportedLanguages;
// 当外部文件不存在时是否回退到classpath中的默认文件
private boolean fallbackToClasspath = true;
// getter和setter方法
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public long getRefreshInterval() {
return refreshInterval;
}
public void setRefreshInterval(long refreshInterval) {
this.refreshInterval = refreshInterval;
}
public List<String> getSupportedLanguages() {
return supportedLanguages;
}
public void setSupportedLanguages(List<String> supportedLanguages) {
this.supportedLanguages = supportedLanguages;
}
public boolean isFallbackToClasspath() {
return fallbackToClasspath;
}
public void setFallbackToClasspath(boolean fallbackToClasspath) {
this.fallbackToClasspath = fallbackToClasspath;
}
@Override
public String toString() {
return "I18nProperties{" +
"location='" + location + '\'' +
", refreshInterval=" + refreshInterval +
", supportedLanguages=" + supportedLanguages +
", fallbackToClasspath=" + fallbackToClasspath +
'}';
}
}

View File

@@ -0,0 +1,31 @@
package org.nl.language.engine;
import org.springframework.util.StringUtils;
public class LangContextHolder {
// 线程本地变量,存储当前线程的语言标识
private static final ThreadLocal<String> LANG_HOLDER = new ThreadLocal<>();
// 设置当前线程的语言
public static void setLang(String lang) {
LANG_HOLDER.set(lang);
}
// 默认语言(从配置中获取)
public static String defaultLang = "zh";
// 获取当前线程的语言
public static String getLang() {
return LANG_HOLDER.get();
}
// 清除当前线程的语言设置(防止内存泄漏)
public static void clear() {
LANG_HOLDER.remove();
}
// 获取当前语言,如果未设置则返回默认语言
public static String getLangOrDefault() {
String lang = getLang();
return StringUtils.hasText(lang) ? lang : defaultLang;
}
}

View File

@@ -0,0 +1,51 @@
package org.nl.language.engine;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LangInterceptor implements HandlerInterceptor {
// 支持的语言列表(实际项目中可从配置获取)
private final I18nProperties properties;
public LangInterceptor(I18nProperties properties) {
this.properties = properties;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 1. 从请求参数获取语言(如 ?lang=zh
String lang = request.getParameter("lang");
// 2. 如果参数不存在可从Header获取如 Accept-Language
if (lang == null || lang.isEmpty()) {
lang = request.getHeader("Accept-Language");
// 简单处理,只取前两位(如 zh-CN -> zh
if (lang != null && lang.length() >= 2) {
lang = lang.substring(0, 2);
}
}
// 3. 验证语言是否在支持的列表中
if (lang != null && properties.getSupportedLanguages().contains(lang)) {
LangContextHolder.setLang(lang);
} else {
// 不支持的语言使用默认语言
LangContextHolder.setLang("zh");
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
// 清除线程变量,防止内存泄漏
LangContextHolder.clear();
}
}

View File

@@ -0,0 +1,21 @@
package org.nl.language.engine;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final LangInterceptor langInterceptor;
public WebConfig(LangInterceptor langInterceptor) {
this.langInterceptor = langInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 对所有请求生效
registry.addInterceptor(langInterceptor).addPathPatterns("/**");
}
}

View File

@@ -0,0 +1,24 @@
package org.nl.language.engine.dto;
public class LanguageDto {
private String code;
private String language;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
}

View File

@@ -0,0 +1,6 @@
spring.application.name=language
server.port=8081
i18n.location=F:/i18n
i18n.supported-languages=zh,en,in,jp
i18n.fallback-to-classpath=true
fallback-to-classpath: true

View File

@@ -0,0 +1,314 @@
var config = {
"language":"English",
"platform": {
"title": "NOBLELIFT Platform"
},
"system": {
"exception": "System exception, please contact administrator",
"paramException": "Parameter exception, please check input parameters",
"resultException": "Request result does not exist",
"dataException": "Data exception, data does not exist",
"dataExceptionArg": "Data exception, %s data does not exist",
"dataDuplicationArg": "Data duplication, %s already exists in system",
"dataFormat": "数据异常,数据不正确",
"activatArg": "%s is not activated in system",
"operation": "操作失败"
},
"business": {
"InvReminder": "Current allocation strategy, no available location for %s",
"loginPassword": "Login failed, incorrect username or password",
"accountUse":"Login failed, account not activated"
},
"common": {
"name": "Name",
"create_name": "Creator",
"create_time": "Create Time",
"update_name": "Modifier",
"remark": "Remark",
"is_used": "Is Enabled",
"is_delete": "Is Deleted",
"create_mode": "Generation Mode",
"input_optname": "Input Operator Name",
"input_time": "Input Time",
"update_optname": "Update Operator Name",
"update_time": "Update Time",
"dis_optname": "Assigner Name",
"dis_time": "Assignment Time",
"confirm_optname": "Confirmer Name",
"confirm_time": "Confirmation Time",
"bill_code": "Document Code",
"bill_type": "Document Type",
"biz_date": "Business Date",
"bill_status": "Document Status",
"zh_name": "Chinese Name",
"in_name": "Indonesian Name",
"en_name": "English Name",
"ext_id": "External ID"
},
"unit": {
"unit_code": "Code",
"unit_name": "Name",
"qty_precision": "Data Precision",
"qty_unit_id": "Base Unit",
"qty_unit_name": "Unit Name"
},
"storagevehicle": {
"storagevehicle_code": "Carrier Code",
"storagevehicle_name": "Carrier Name",
"vehicle_type": "Carrier Type",
"vehicle_code": "Carrier Code",
"one_code": "Barcode",
"two_code": "QR Code",
"vehicle_width": "Carrier Width",
"vehicle_long": "Carrier Length",
"vehicle_height": "Carrier Height",
"weigth": "Pallet Weight",
"overstruct_type": "Exceeds Location Size",
"occupystruct_qty": "Occupied Locations Count",
"ext_id": "External ID"
},
"point": {
"point_code": "Point Code",
"point_name": "Point Name",
"region_code": "Region Code",
"region_name": "Region Name",
"point_type": "Point Type",
"point_status": "Point Status",
"vehicle_type": "Carrier Type",
"vehicle_code": "Carrier Code",
"vehicle_qty": "Carrier Quantity",
"in_order_seq": "Inbound Sequence",
"out_order_seq": "Outbound Sequence",
"in_empty_seq": "Empty Carrier Inbound Sequence",
"out_empty_seq": "Empty Carrier Outbound Sequence",
"parent_point_code": "Parent Point Code",
"ext_point_code": "External Point Code",
"ing_task_code": "Executing Task Code",
"is_has_workder": "Has Work Order",
"workshop_code": "Workshop Code",
"is_auto": "Is Automatic"
},
"region": {
"region_code": "Region Code",
"region_name": "Region Name",
"point_type_explain": "Point Type Description",
"point_status_explain": "Point Status Description",
"is_has_workder": "Has Work Order",
"order_seq": "Sequence Number",
"workshop_code": "Workshop Code"
},
"task": {
"task_code": "Task Code",
"task_status": "Task Status",
"config_code": "Config Code",
"point_code1": "Point 1",
"point_code2": "Point 2",
"point_code3": "Point 3",
"point_code4": "Point 4",
"group_id": "Group ID",
"vehicle_type": "Carrier Type",
"vehicle_qty": "Carrier Quantity",
"vehicle_code": "Carrier Code",
"vehicle_code2": "Carrier Code 2",
"handle_status": "Handle Status",
"car_no": "Vehicle Number",
"task_group_id": "Task Group ID",
"task_group_seq": "Task Group Sequence",
"finished_type": "Task Completion Type",
"create_mode": "Generation Mode",
"request_param": "Generation Request Parameters",
"response_param": "Issue Request Parameters",
"workshop_code": "Workshop Code",
"ext_group_data": "Extra Group Data",
"priority": "ACS Priority"
},
"taskconfig": {
"config_code": "Config Code",
"config_name": "Config Name",
"route_plan_code": "Route Code",
"task_qf_type": "Task Pick/Drop Type",
"acs_task_type": "ACS Task Type",
"task_name": "Task Name",
"task_type": "Task Type",
"task_direction": "Task Direction",
"priority": "Priority",
"task_create_max_num": "Max Task Generation Count",
"task_issue_max_num": "Max Task Issue Count",
"is_auto_issue": "Auto Issue",
"start_region_str": "Start Region Config",
"next_region_str": "End Region Config",
"start_point_pre": "Start Point Prefix",
"next_region_pre": "End Point Prefix",
"is_check_workorder": "Check Work Order",
"is_check_start_lock": "Check Start Lock",
"is_immediate_create": "Immediate Create",
"is_check_next_lock": "Check End Lock",
"is_start_auto": "Start Auto",
"is_next_auto": "End Auto",
"is_lock_start": "Lock Start",
"is_lock_next": "Lock End",
"request_param": "Generation Request Parameters",
"response_param": "Issue Request Parameters",
"is_group_congrol_issue_seq": "Control Issue Sequence by Group",
"unfinish_notify_time": "Unfinished Task Notification Time",
"sql_param": "SQL Config",
"workshop_code": "Workshop Code"
},
"storattr": {
"stor_code": "Warehouse Code",
"stor_name": "Warehouse Name",
"simple_name": "Warehouse Abbreviation",
"stor_capacity": "Warehouse Capacity",
"total_area": "Total Area",
"stor_type_scode": "Warehouse Nature",
"is_virtualstore": "Is Virtual Warehouse",
"is_semi_finished": "Is Semi-finished Warehouse",
"is_materialstore": "Is Raw Material Warehouse",
"is_productstore": "Is Finished Product Warehouse",
"is_attachment": "Is Spare Parts Warehouse",
"is_reversed": "Allow Red Reversal",
"is_mvout_auto_cfm": "Auto Confirm Move Out",
"is_mvin_auto_cfm": "Auto Confirm Move In",
"area": "Area",
"storea_ddress": "Warehouse Address",
"principal": "Principal",
"office_phone": "Office Phone",
"mobile_no": "Mobile Number",
"order_index": "Display Order",
"whstate_scode": "Status",
"base_class_id": "Material Base Category",
"sysownerid": "Owner ID",
"sysdeptid": "Department ID",
"syscompanyid": "Company ID",
"ext_id": "External ID",
"depart_name": "Department Name",
"company_name": "Company Name"
},
"checkmst": {
"seq_no": "Detail Sequence",
"sect_code": "Check Area",
"struct_code": "Check Location",
"checkpoint_code": "Check Platform",
"storagevehicle_code": "Carrier Code",
"material_id": "Material ID",
"pcsn": "Batch",
"base_qty": "Stock Quantity",
"status": "Status",
"is_down": "Is Issued",
"fac_qty": "Check Quantity",
"check_result": "Check Result",
"check_optname": "Checker Name",
"check_time": "Check Time",
"remark": "Detail Remark",
"check_code": "Check Code",
"check_type": "Check Type",
"stor_name": "Warehouse Name",
"dtl_num": "Detail Count",
"create_mode": "Generation Mode"
},
"structWarning": {
"safe_qty_lower_limit": "Safe Stock Lower Limit",
"safe_qty_upper_limit": "Safe Stock Upper Limit",
"cron": "Cron Expression",
"notify_type": "Notification Type",
"overdue_days": "Overdue Days",
"safe_days": "Safe Days",
"is_read": "Is Read",
"current_qty": "Current Quantity"
},
"strategy": {
"sect_code": "Storage Area",
"strategy": "Rule",
"strategy_type": "1 Inbound Strategy 2 Outbound Strategy",
"description": "Description",
"strategy_code": "Strategy Code",
"strategy_name": "Strategy Name",
"class_type": "Class Type",
"param": "Handler Class",
"ban": "Forbid Operation",
"form_data": "Limit Parameters"
},
"code_rule": {
"current_value": "Current Value"
},
"dept": {
"dept_id": "ID",
"pid": "Parent Department",
"sub_count": "Sub Department Count",
"name": "Name",
"zh_name": "Chinese Name",
"in_name": "Indonesian Name",
"en_name": "English Name",
"dept_sort": "Sort",
"is_used": "Status",
"create_name": "Creator",
"update_name": "Updater",
"create_time": "Create Date",
"update_time": "Update Time",
"code": "Department Code",
"ext_id": "External ID"
},
"dict": {
"dict_type": "Dictionary Type",
"dict_sort": "Sort Number",
"label": "Dictionary Label",
"value": "Dictionary Value",
"para1": "Parameter 1",
"para2": "Parameter 2",
"para3": "Parameter 3"
},
"menu": {
"menu_id": "Menu ID",
"pid": "Parent Menu ID",
"sub_count": "Sub Menu Count",
"type": "Menu Type",
"system_type": "System Type",
"category": "Menu Category",
"title": "Menu Title",
"en_title": "English Title",
"in_title": "Indonesian Title",
"zh_title": "Chinese Title",
"component_name": "Component Name",
"component": "Component",
"menu_sort": "Sort",
"icon": "Icon",
"path": "Path",
"iframe": "Is Iframe",
"cache": "Is Cache",
"hidden": "Is Hidden",
"permission": "Permission",
"is_pc": "Is PC Menu"
},
"param": {
"code": "Code",
"name": "Name",
"zh_name": "Name",
"en_name": "English Name",
"in_name": "Indonesian Name",
"value": "Value"
},
"role": {
"level": "Role Level"
},
"user": {
"user_id": "User ID",
"username": "Username",
"password": "Password",
"is_admin": "Is Admin",
"person_name": "Name",
"zh_person_name": "Name (Chinese)",
"en_person_name": "Name (English)",
"in_person_name": "Indonesian Name",
"gender": "Gender",
"zh_gender": "Gender (Chinese)",
"en_gender": "Gender (English)",
"phone": "Phone",
"email": "Email",
"avatar_name": "Avatar Path",
"avatar_path": "Avatar Real Path",
"extperson_id": "External Person ID",
"extuser_id": "External User ID",
"pwd_reset_user_id": "Password Reset By",
"pwd_reset_time": "Password Reset Time"
}
}

View File

@@ -0,0 +1,342 @@
var config = {
"language":"Indonesian",
"platform": {
"title": "NOBLELIFT Platform"
},
"system": {
"exception": "Hệ thống bất thường, vui lòng liên hệ quản trị viên",
"paramException": "Tham số bất thường, vui lòng kiểm tra tham số đầu vào",
"resultException": "Kết quả yêu cầu không tồn tại",
"dataException": "Dữ liệu bất thường, dữ liệu không tồn tại",
"dataExceptionArg": "Dữ liệu bất thường, %s dữ liệu không tồn tại",
"dataDuplicationArg": "Dữ liệu trùng lặp, %s đã tồn tại trong hệ thống",
"dataFormat": "数据异常,数据不正确",
"activatArg": "%s chưa được kích hoạt trong hệ thống",
"operation": "操作失败"
},
"business": {
"InvReminder": "Chiến lược phân bổ hiện tại, %s không có vị trí khả dụng",
"loginPassword":"登入失败,账号密码不正确",
"accountUse":"登入失败,账号未启用"
},
"common": {
"name": "Tên",
"create_name": "Người tạo",
"create_time": "Thời gian tạo",
"update_name": "Người sửa đổi",
"remark": "Ghi chú",
"is_used": "Đã kích hoạt",
"is_delete": "Đã xóa",
"create_mode": "Phương thức tạo",
"input_optname": "Tên người lập đơn",
"input_time": "Thời gian lập đơn",
"update_optname": "Tên người sửa đổi",
"update_time": "Thời gian sửa đổi",
"dis_optname": "Tên người phân bổ",
"dis_time": "Thời gian phân bổ",
"confirm_optname": "Tên người xác nhận",
"confirm_time": "Thời gian xác nhận",
"bill_code": "Mã chứng từ",
"bill_type": "Loại chứng từ",
"biz_date": "Ngày nghiệp vụ",
"bill_status": "Trạng thái chứng từ",
"zh_name": "Tên tiếng Trung",
"in_name": "Tên tiếng Indonesia",
"en_name": "Tên tiếng Anh",
"ext_id": "ID bên ngoài"
},
"md_pb_measureunit": {
"unit_code": "Mã",
"unit_name": "Tên",
"qty_precision": "Độ chính xác dữ liệu",
"qty_unit_id": "Đơn vị đo lường cơ bản",
"qty_unit_name": "Tên đơn vị"
},
"md_pb_storagevehicleinfo": {
"storagevehicle_code": "Mã phương tiện",
"storagevehicle_name": "Tên phương tiện",
"one_code": "Mã vạch",
"two_code": "Mã QR",
"storagevehicle_type": "Loại phương tiện",
"vehicle_width": "Chiều rộng phương tiện",
"vehicle_long": "Chiều dài phương tiện",
"vehicle_height": "Chiều cao phương tiện",
"weigth": "Trọng lượng pallet",
"overstruct_type": "Phương tiện có vượt quá vị trí không",
"occupystruct_qty": "Số vị trí chiếm dụng",
"ext_id": "ID bên ngoài"
},
"sch_base_point": {
"point_code": "Mã điểm",
"point_name": "Tên điểm",
"region_code": "Mã khu vực",
"region_name": "Tên khu vực",
"point_type": "Loại điểm",
"point_status": "Trạng thái điểm",
"vehicle_type": "Loại phương tiện",
"vehicle_code": "Mã phương tiện",
"vehicle_qty": "Số lượng phương tiện",
"in_order_seq": "Thứ tự nhập kho",
"out_order_seq": "Thứ tự xuất kho",
"in_empty_seq": "Thứ tự nhập phương tiện rỗng",
"out_empty_seq": "Thứ tự xuất phương tiện rỗng",
"parent_point_code": "Mã điểm cha",
"ext_point_code": "Mã điểm bên ngoài",
"ing_task_code": "Mã tác vụ đang thực hiện",
"is_has_workder": "Có tạo đơn hàng không",
"workshop_code": "Mã phân xưởng",
"is_auto": "Tự động"
},
"sch_base_region": {
"region_code": "Mã khu vực",
"region_name": "Tên khu vực",
"point_type_explain": "Giải thích loại điểm",
"point_status_explain": "Giải thích trạng thái điểm",
"is_has_workder": "Có tạo đơn hàng không",
"order_seq": "Số thứ tự",
"workshop_code": "Mã phân xưởng"
},
"sch_base_task": {
"task_code": "Mã tác vụ",
"task_status": "Trạng thái tác vụ",
"config_code": "Mã cấu hình",
"point_code1": "Điểm 1",
"point_code2": "Điểm 2",
"point_code3": "Điểm 3",
"point_code4": "Điểm 4",
"group_id": "ID nhóm",
"vehicle_type": "Loại phương tiện",
"vehicle_qty": "Số lượng phương tiện",
"vehicle_code": "Mã phương tiện",
"vehicle_code2": "Mã phương tiện 2",
"handle_status": "Trạng thái xử lý",
"car_no": "Số xe",
"task_group_id": "ID nhóm tác vụ",
"task_group_seq": "Số thứ tự nhóm tác vụ",
"finished_type": "Loại hoàn thành tác vụ",
"create_mode": "Phương thức tạo",
"request_param": "Tham số yêu cầu tạo tác vụ",
"response_param": "Tham số yêu cầu phát hành tác vụ",
"workshop_code": "Mã phân xưởng",
"ext_group_data": "Thông tin nhóm bổ sung",
"priority": "Mức độ ưu tiên ACS"
},
"sch_base_taskconfig": {
"config_code": "Mã cấu hình",
"config_name": "Tên cấu hình",
"route_plan_code": "Mã định tuyến",
"task_qf_type": "Loại lấy/thả tác vụ",
"acs_task_type": "Loại tác vụ ACS",
"task_name": "Tên tác vụ",
"task_type": "Loại tác vụ",
"task_direction": "Hướng tác vụ",
"priority": "Mức độ ưu tiên",
"task_create_max_num": "Số lượng tạo tác vụ tối đa cho phép",
"task_issue_max_num": "Số lượng phát hành tác vụ tối đa cho phép",
"is_auto_issue": "Tự động phát hành",
"start_region_str": "Cấu hình khu vực bắt đầu",
"next_region_str": "Cấu hình khu vực kết thúc",
"start_point_pre": "Tiền tố điểm bắt đầu",
"next_region_pre": "Tiền tố điểm kết thúc",
"is_check_workorder": "Có kiểm tra đơn hàng không",
"is_check_start_lock": "Có đánh giá khóa điểm bắt đầu không",
"is_immediate_create": "Tạo ngay lập tức",
"is_check_next_lock": "Có đánh giá khóa điểm kết thúc không",
"is_start_auto": "Tự động tại điểm bắt đầu",
"is_next_auto": "Tự động tại điểm kết thúc",
"is_lock_start": "Khóa điểm bắt đầu",
"is_lock_next": "Khóa điểm kết thúc",
"request_param": "Tham số yêu cầu tạo tác vụ",
"response_param": "Tham số yêu cầu phát hành tác vụ",
"is_group_congrol_issue_seq": "Có kiểm soát thứ tự phát hành theo nhóm không",
"unfinish_notify_time": "Thời gian thông báo tác vụ chưa hoàn thành",
"sql_param": "Cấu hình SQL",
"workshop_code": "Mã phân xưởng"
},
"st_ivt_bsrealstorattr": {
"stor_code": "Mã kho",
"stor_name": "Tên kho",
"simple_name": "Tên viết tắt kho",
"stor_capacity": "Dung lượng kho",
"total_area": "Tổng diện tích",
"stor_type_scode": "Tính chất kho",
"is_virtualstore": "Có phải kho ảo không",
"is_semi_finished": "Có phải kho bán thành phẩm không",
"is_materialstore": "Có phải kho nguyên liệu không",
"is_productstore": "Có phải kho thành phẩm không",
"is_attachment": "Có phải kho phụ tùng không",
"is_reversed": "Có cho phép hồi tố không",
"is_mvout_auto_cfm": "Tự động xác nhận nghiệp vụ chuyển ra",
"is_mvin_auto_cfm": "Tự động xác nhận nghiệp vụ chuyển vào",
"area": "Khu vực",
"storea_ddress": "Địa chỉ kho",
"principal": "Người phụ trách",
"office_phone": "Điện thoại văn phòng",
"mobile_no": "Số điện thoại di động",
"order_index": "Thứ tự hiển thị",
"whstate_scode": "Trạng thái",
"base_class_id": "Phân loại cơ bản vật liệu",
"sysownerid": "ID chủ sở hữu",
"sysdeptid": "ID phòng ban",
"syscompanyid": "ID công ty",
"ext_id": "ID bên ngoài",
"depart_name": "Tên phòng ban",
"company_name": "Tên công ty"
},
"st_ivt_checkdtl": {
"seq_no": "Số thứ tự chi tiết",
"sect_code": "Khu vực kiểm kê",
"struct_code": "Vị trí kiểm kê",
"checkpoint_code": "Bến kiểm kê",
"storagevehicle_code": "Mã phương tiện lưu trữ",
"material_id": "ID vật liệu",
"pcsn": "Lô",
"base_qty": "Số lượng tồn kho",
"status": "Trạng thái",
"is_down": "Đã phát hành",
"fac_qty": "Số lượng kiểm kê",
"check_result": "Kết quả kiểm kê",
"check_optname": "Tên người kiểm kê",
"check_time": "Thời gian kiểm kê",
"remark": "Ghi chú chi tiết",
"check_code": "Số phiếu kiểm kê",
"check_type": "Loại phiếu kiểm kê",
"stor_name": "Tên kho",
"dtl_num": "Số lượng chi tiết",
"create_mode": "Phương thức tạo"
},
"st_ivt_iostor": {
"stor_code": "Mã kho",
"sect_date": "Ngày",
"quality_scode": "Loại chất lượng",
"start_num": "Số lượng đầu kỳ",
"in_num": "Số lượng nhập kho",
"out_num": "Số lượng xuất kho",
"total_qty": "Tổng số lượng",
"total_weight": "Tổng trọng lượng",
"io_type": "Loại nhập/xuất",
"detail_count": "Số lượng chi tiết",
"seq_no": "Số thứ tự chi tiết",
"work_status": "Trạng thái thực hiện",
"task_id": "ID tác vụ",
"storagevehicle_code": "Mã phương tiện lưu trữ",
"is_issued": "Đã phát hành",
"plan_qty": "Số lượng kế hoạch",
"real_qty": "Số lượng thực tế",
"point_code": "ID điểm nhập/xuất",
"assign_qty": "Số lượng đã phân bổ",
"unassign_qty": "Số lượng chưa phân bổ",
"mol_code": "Số phiếu hao hụt",
"mol_inv_type": "Loại phiếu hao hụt",
"mol_type": "Loại hao hụt",
"turnout_sect_code": "Mã khu vực chuyển ra",
"turnout_struct_code": "Mã vị trí chuyển ra",
"turnin_sect_code": "Mã khu vực chuyển vào",
"turnin_struct_code": "Mã vị trí chuyển vào"
},
"structWarning": {
"safe_qty_lower_limit": "Giới hạn dưới tồn kho an toàn",
"safe_qty_upper_limit": "Giới hạn trên tồn kho an toàn",
"cron": "Biểu thức",
"notify_type": "Loại thông báo",
"overdue_days": "Số ngày quá hạn",
"safe_days": "Số ngày an toàn",
"is_read": "Đã đọc",
"current_qty": "Số lượng hiện tại"
},
"strategy": {
"sect_code": "Khu vực kho",
"strategy": "Quy tắc",
"strategy_type": "1 Chiến lược nhập kho 2 Chiến lược xuất kho",
"description": "Mô tả",
"strategy_code": "Mã chiến lược",
"strategy_name": "Tên chiến lược",
"class_type": "Loại xử lý",
"param": "Lớp xử lý",
"ban": "Cấm thao tác",
"form_data": "Tham số giới hạn"
},
"code_rule": {
"current_value": "Giá trị hiện tại"
},
"dept": {
"dept_id": "ID",
"pid": "Phòng ban cấp trên",
"sub_count": "Số lượng phòng ban con",
"name": "Tên",
"zh_name": "Tên tiếng Trung",
"in_name": "Tên tiếng Indonesia",
"en_name": "Tên tiếng Anh",
"dept_sort": "Sắp xếp",
"is_used": "Trạng thái",
"create_name": "Người tạo",
"update_name": "Người cập nhật",
"create_time": "Ngày tạo",
"update_time": "Thời gian cập nhật",
"code": "Mã phòng ban",
"ext_id": "ID bên ngoài"
},
"dict": {
"dict_type": "Loại từ điển",
"dict_sort": "Số thứ tự",
"label": "Nhãn từ điển",
"value": "Giá trị từ điển",
"para1": "Tham số 1",
"para2": "Tham số 2",
"para3": "Tham số 3"
},
"menu": {
"menu_id": "ID menu",
"pid": "ID menu cấp trên",
"sub_count": "Số lượng menu con",
"type": "Loại menu",
"system_type": "Hệ thống thuộc về",
"category": "Phân loại menu",
"title": "Tiêu đề menu",
"en_title": "Tiêu đề tiếng Anh",
"in_title": "Tiêu đề tiếng Indonesia",
"zh_title": "Tiêu đề tiếng Trung",
"component_name": "Tên thành phần",
"component": "Thành phần",
"menu_sort": "Sắp xếp",
"icon": "Biểu tượng",
"path": "Đường dẫn",
"iframe": "Có phải liên kết ngoài không",
"cache": "Có lưu đệm không",
"hidden": "Có ẩn không",
"permission": "Quyền",
"is_pc": "Có phải menu PC không"
},
"param": {
"code": "Mã",
"name": "Tên",
"zh_name": "Tên",
"en_name": "Tên tiếng Anh",
"in_name": "Tên tiếng Indonesia",
"value": "Giá trị"
},
"role": {
"level": "Cấp độ vai trò"
},
"user": {
"user_id": "ID người dùng",
"username": "Tài khoản đăng nhập",
"password": "Mật khẩu",
"is_admin": "Có phải tài khoản admin không",
"person_name": "Họ tên",
"zh_person_name": "Họ (tiếng Trung)",
"en_person_name": "Họ (tiếng Anh)",
"in_person_name": "Tên tiếng Indonesia",
"gender": "Giới tính",
"zh_gender": "Giới tính (tiếng Trung)",
"en_gender": "Giới tính (tiếng Anh)",
"phone": "Điện thoại",
"email": "Email",
"avatar_name": "Đường dẫn ảnh đại diện",
"avatar_path": "Đường dẫn thực ảnh đại diện",
"extperson_id": "ID người dùng bên ngoài",
"extuser_id": "ID người dùng bên ngoài",
"pwd_reset_user_id": "Người đặt lại mật khẩu",
"pwd_reset_time": "Thời gian đặt lại mật khẩu"
}
}

View File

@@ -0,0 +1,314 @@
var config = {
"language":"にほんご",
"platform": {
"title": "NOBLELIFT プラットフォーム"
},
"system": {
"exception": "システム異常、管理者に連絡してください",
"paramException": "パラメータ異常、入力パラメータを確認してください",
"resultException": "リクエスト結果が存在しません",
"dataException": "データ異常、データが存在しません",
"dataExceptionArg": "データ異常、%sデータが存在しません",
"dataDuplicationArg": "データ重複、%sはシステム内に既に存在します",
"dataFormat": "数据异常,数据不正确",
"activatArg": "%sはシステムで有効化されていません",
"operation": "操作失败"
},
"business": {
"InvReminder": "現在の割り当て戦略、%sに利用可能なロケーションがありません",
"loginPassword":"登入失败,账号密码不正确",
"accountUse":"登入失败,账号未启用"
},
"common": {
"name": "名称",
"create_name": "作成者",
"create_time": "作成日時",
"update_name": "更新者",
"remark": "備考",
"is_used": "有効化",
"is_delete": "削除済み",
"create_mode": "生成方式",
"input_optname": "入力オペレーター名",
"input_time": "入力日時",
"update_optname": "更新オペレーター名",
"update_time": "更新日時",
"dis_optname": "割当者名",
"dis_time": "割当日時",
"confirm_optname": "確認者名",
"confirm_time": "確認日時",
"bill_code": "ドキュメントコード",
"bill_type": "ドキュメントタイプ",
"biz_date": "業務日付",
"bill_status": "ドキュメントステータス",
"zh_name": "中国語名称",
"in_name": "インドネシア語名称",
"en_name": "英語名称",
"ext_id": "外部ID"
},
"unit": {
"unit_code": "コード",
"unit_name": "名称",
"qty_precision": "データ精度",
"qty_unit_id": "基本単位",
"qty_unit_name": "単位名称"
},
"storagevehicle": {
"storagevehicle_code": "キャリアコード",
"storagevehicle_name": "キャリア名称",
"vehicle_type": "キャリアタイプ",
"vehicle_code": "キャリアコード",
"one_code": "バーコード",
"two_code": "QRコード",
"vehicle_width": "キャリア幅",
"vehicle_long": "キャリア長",
"vehicle_height": "キャリア高",
"weigth": "パレット重量",
"overstruct_type": "ロケーションサイズ超過",
"occupystruct_qty": "占有ロケーション数",
"ext_id": "外部ID"
},
"point": {
"point_code": "ポイントコード",
"point_name": "ポイント名称",
"region_code": "エリアコード",
"region_name": "エリア名称",
"point_type": "ポイントタイプ",
"point_status": "ポイントステータス",
"vehicle_type": "キャリアタイプ",
"vehicle_code": "キャリアコード",
"vehicle_qty": "キャリア数量",
"in_order_seq": "入庫順序",
"out_order_seq": "出庫順序",
"in_empty_seq": "空キャリア入庫順序",
"out_empty_seq": "空キャリア出庫順序",
"parent_point_code": "親ポイントコード",
"ext_point_code": "外部ポイントコード",
"ing_task_code": "実行中タスクコード",
"is_has_workder": "作業指示書有無",
"workshop_code": "ワークショップコード",
"is_auto": "自動化"
},
"region": {
"region_code": "エリアコード",
"region_name": "エリア名称",
"point_type_explain": "ポイントタイプ説明",
"point_status_explain": "ポイントステータス説明",
"is_has_workder": "作業指示書有無",
"order_seq": "順序番号",
"workshop_code": "ワークショップコード"
},
"task": {
"task_code": "タスクコード",
"task_status": "タスクステータス",
"config_code": "設定コード",
"point_code1": "ポイント1",
"point_code2": "ポイント2",
"point_code3": "ポイント3",
"point_code4": "ポイント4",
"group_id": "グループID",
"vehicle_type": "キャリアタイプ",
"vehicle_qty": "キャリア数量",
"vehicle_code": "キャリアコード",
"vehicle_code2": "キャリアコード2",
"handle_status": "処理ステータス",
"car_no": "車両番号",
"task_group_id": "タスクグループID",
"task_group_seq": "タスクグループ順序",
"finished_type": "タスク完了タイプ",
"create_mode": "生成方式",
"request_param": "生成リクエストパラメータ",
"response_param": "発行リクエストパラメータ",
"workshop_code": "ワークショップコード",
"ext_group_data": "追加グループ情報",
"priority": "ACS優先度"
},
"taskconfig": {
"config_code": "設定コード",
"config_name": "設定名称",
"route_plan_code": "ルートコード",
"task_qf_type": "タスクピック/ドロップタイプ",
"acs_task_type": "ACSタスクタイプ",
"task_name": "タスク名称",
"task_type": "タスクタイプ",
"task_direction": "タスク方向",
"priority": "優先度",
"task_create_max_num": "最大タスク生成数",
"task_issue_max_num": "最大タスク発行数",
"is_auto_issue": "自動発行",
"start_region_str": "開始エリア設定",
"next_region_str": "終了エリア設定",
"start_point_pre": "開始ポイント接頭辞",
"next_region_pre": "終了ポイント接頭辞",
"is_check_workorder": "作業指示書チェック",
"is_check_start_lock": "開始ロックチェック",
"is_immediate_create": "即時生成",
"is_check_next_lock": "終了ロックチェック",
"is_start_auto": "開始自動化",
"is_next_auto": "終了自動化",
"is_lock_start": "開始ロック",
"is_lock_next": "終了ロック",
"request_param": "生成リクエストパラメータ",
"response_param": "発行リクエストパラメータ",
"is_group_congrol_issue_seq": "グループ別発行順序制御",
"unfinish_notify_time": "未完了タスク通知時間",
"sql_param": "SQL設定",
"workshop_code": "ワークショップコード"
},
"storattr": {
"stor_code": "倉庫コード",
"stor_name": "倉庫名称",
"simple_name": "倉庫略称",
"stor_capacity": "倉庫容量",
"total_area": "総面積",
"stor_type_scode": "倉庫性質",
"is_virtualstore": "仮想倉庫",
"is_semi_finished": "半製品倉庫",
"is_materialstore": "原材料倉庫",
"is_productstore": "完成品倉庫",
"is_attachment": "予備品倉庫",
"is_reversed": "赤伝票許可",
"is_mvout_auto_cfm": "移動出自動確認",
"is_mvin_auto_cfm": "移動入自動確認",
"area": "地域",
"storea_ddress": "倉庫住所",
"principal": "責任者",
"office_phone": "事務所電話",
"mobile_no": "携帯番号",
"order_index": "表示順序",
"whstate_scode": "ステータス",
"base_class_id": "物料基本分類",
"sysownerid": "所有者ID",
"sysdeptid": "部門ID",
"syscompanyid": "会社ID",
"ext_id": "外部ID",
"depart_name": "部門名称",
"company_name": "会社名称"
},
"checkmst": {
"seq_no": "明細順序",
"sect_code": "棚卸エリア",
"struct_code": "棚卸ロケーション",
"checkpoint_code": "棚卸プラットフォーム",
"storagevehicle_code": "キャリアコード",
"material_id": "物料ID",
"pcsn": "バッチ",
"base_qty": "在庫数量",
"status": "ステータス",
"is_down": "発行済み",
"fac_qty": "棚卸数量",
"check_result": "棚卸結果",
"check_optname": "棚卸者名",
"check_time": "棚卸日時",
"remark": "明細備考",
"check_code": "棚卸コード",
"check_type": "棚卸タイプ",
"stor_name": "倉庫名称",
"dtl_num": "明細数",
"create_mode": "生成方式"
},
"structWarning": {
"safe_qty_lower_limit": "安全在庫下限",
"safe_qty_upper_limit": "安全在庫上限",
"cron": "Cron式",
"notify_type": "通知タイプ",
"overdue_days": "超過日数",
"safe_days": "安全日数",
"is_read": "既読",
"current_qty": "現在数量"
},
"strategy": {
"sect_code": "ストレージエリア",
"strategy": "ルール",
"strategy_type": "1 入庫戦略 2 出庫戦略",
"description": "説明",
"strategy_code": "戦略コード",
"strategy_name": "戦略名称",
"class_type": "クラスタイプ",
"param": "ハンドラークラス",
"ban": "操作禁止",
"form_data": "制限パラメータ"
},
"code_rule": {
"current_value": "現在値"
},
"dept": {
"dept_id": "ID",
"pid": "親部門",
"sub_count": "子部門数",
"name": "名称",
"zh_name": "中国語名称",
"in_name": "インドネシア語名称",
"en_name": "英語名称",
"dept_sort": "ソート",
"is_used": "ステータス",
"create_name": "作成者",
"update_name": "更新者",
"create_time": "作成日付",
"update_time": "更新日時",
"code": "部門コード",
"ext_id": "外部ID"
},
"dict": {
"dict_type": "辞書タイプ",
"dict_sort": "ソート番号",
"label": "辞書ラベル",
"value": "辞書値",
"para1": "パラメータ1",
"para2": "パラメータ2",
"para3": "パラメータ3"
},
"menu": {
"menu_id": "メニューID",
"pid": "親メニューID",
"sub_count": "子メニュー数",
"type": "メニュータイプ",
"system_type": "システムタイプ",
"category": "メニュー分類",
"title": "メニュータイトル",
"en_title": "英語タイトル",
"in_title": "インドネシア語タイトル",
"zh_title": "中国語タイトル",
"component_name": "コンポーネント名",
"component": "コンポーネント",
"menu_sort": "ソート",
"icon": "アイコン",
"path": "パス",
"iframe": "外部リンク",
"cache": "キャッシュ",
"hidden": "非表示",
"permission": "権限",
"is_pc": "PCメニュー"
},
"param": {
"code": "コード",
"name": "名称",
"zh_name": "名称",
"en_name": "英語名称",
"in_name": "インドネシア語名称",
"value": "値"
},
"role": {
"level": "ロールレベル"
},
"user": {
"user_id": "ユーザーID",
"username": "ユーザー名",
"password": "パスワード",
"is_admin": "管理者",
"person_name": "氏名",
"zh_person_name": "氏名(中国語)",
"en_person_name": "氏名(英語)",
"in_person_name": "インドネシア語名称",
"gender": "性別",
"zh_gender": "性別(中国語)",
"en_gender": "性別(英語)",
"phone": "電話",
"email": "メール",
"avatar_name": "アバター画像パス",
"avatar_path": "アバター画像実パス",
"extperson_id": "外部人物ID",
"extuser_id": "外部ユーザーID",
"pwd_reset_user_id": "パスワードリセット者",
"pwd_reset_time": "パスワードリセット日時"
}
}

View File

@@ -0,0 +1,327 @@
var config = {
"language":"简体中文",
"platform": {
"title": "NOBLELIFT Platform",
},
"system": {
"exception": "系统异常,请联系管理员查看",
"paramException": "参数异常,输入参数不正确",
"resultException": "请求结果不存在",
"dataException": "数据异常,数据不存在",
"dataExceptionArg": "数据异常,%s数据不存在",
"dataFormat": "数据异常,数据不正确",
"dataDuplicationArg": "数据重复,%s在系统中已存在",
"activatArg": "%s在系统未启用",
"operation": "操作失败"
},
"business": {
"InvReminder": "当前分配策略,%s无可用货位",
"loginPassword":"登入失败,账号密码不正确",
"accountUse":"登入失败,账号未启用"
},
"common": {
"name": "名称",
"create_name":"创建人",
"create_time":"创建时间",
"update_name":"修改人",
"remark":"备注",
"is_used":"是否启用",
"is_delete":"是否删除",
"create_mode":"生成方式",
"input_optname":"制单人姓名",
"input_time":"制单时间",
"update_optname":"修改人姓名",
"update_time":"修改时间",
"dis_optname":"分配人姓名",
"dis_time":"分配时间",
"confirm_optname":"确认人姓名",
"confirm_time":"确认时间",
"bill_code":"单据编号",
"bill_type":"单据类型",
"biz_date":"业务日期",
"bill_status":"单据状态/单据明细状态",
"zh_name":"中文名称",
"in_name":"印尼名称",
"en_name":"英文名称",
"ext_id":"外部标识"
},
"unit": {
"unit_code":"编码",
"unit_name":"名称",
"qty_precision":"数据精度",
"qty_unit_id":"基本计量单位",
"qty_unit_name":"单位名称"
},
"storagevehicle": {
"storagevehicle_code":"载具编码",
"storagevehicle_name":"载具名称",
"vehicle_type":"载具类型",
"vehicle_code":"载具编码",
"one_code":"一维码",
"two_code":"二维码",
"storagevehicle_type":"载具类型",
"vehicle_width":"载具宽度",
"vehicle_long":"载具长度",
"vehicle_height":"载具高度",
"weigth":"托盘重量",
"overstruct_type":"载具是否超仓位",
"occupystruct_qty":"占仓位数",
"ext_id":"外部标识"
},
"point": {"point_code":"点位编码",
"point_name":"点位名称",
"region_code":"区域编码",
"region_name":"区域名称",
"point_type":"点位类型",
"point_status":"点位状态",
"vehicle_type":"载具类型",
"vehicle_code":"载具编码",
"vehicle_qty":"载具数量",
"in_order_seq":"入库顺序",
"out_order_seq":"出库顺序",
"in_empty_seq":"入空载具顺序",
"out_empty_seq":"出空载具顺序",
"parent_point_code":"父点位编码",
"ext_point_code":"外部点位编码",
"ing_task_code":"在执行的任务标识",
"is_has_workder":"是否创建工单",
"workshop_code":"车间编码",
"is_auto":"是否自动"
},
"region": {"region_code":"区域编码",
"region_name":"区域名称",
"point_type_explain":"点位类型说明",
"point_status_explain":"点位状态说明",
"is_has_workder":"是否创建工单",
"order_seq":"顺序号",
"workshop_code":"车间编码"
},
"task":{
"task_code":"任务编码",
"task_status":"任务状态",
"config_code":"配置编码",
"point_code1":"点位1",
"point_code2":"点位2",
"point_code3":"点位3",
"point_code4":"点位4",
"group_id":"组盘标识",
"vehicle_type":"载具类型",
"vehicle_qty":"载具数量",
"vehicle_code":"载具编码",
"vehicle_code2":"载具编码2",
"handle_status":"处理状态",
"car_no":"车号",
"task_group_id":"任务组标识",
"task_group_seq":"任务组顺序号",
"finished_type":"任务完成类型",
"create_mode":"生成方式",
"request_param":"生成任务的请求参数",
"response_param":"下发任务的请求参数",
"workshop_code":"车间编码",
"ext_group_data":"额外组盘信息",
"priority":"acs优先级"
},
"taskconfig":{
"config_code":"配置编码",
"config_name":"配置名称",
"route_plan_code":"路由编码",
"task_qf_type":"任务取放类型",
"acs_task_type":"acs任务类型",
"task_name":"任务名字",
"task_type":"任务类型",
"task_direction":"任务去向",
"priority":"优先级",
"task_create_max_num":"允许最大任务生成数",
"task_issue_max_num":"允许最大任务下发数",
"is_auto_issue":"是否自动下发",
"start_region_str":"起点区域配置",
"next_region_str":"终点区域配置",
"start_point_pre":"起点点位前缀",
"next_region_pre":"终点点位前缀",
"is_check_workorder":"是否校验工单",
"is_check_start_lock":"是否判断起点锁定",
"is_immediate_create":"是否立即创建",
"is_check_next_lock":"是否判断终点锁定",
"is_start_auto":"是否起点自动",
"is_next_auto":"是否终点自动",
"is_lock_start":"是否锁定起点",
"is_lock_next":"是否锁定终点",
"request_param":"生成任务的请求参数",
"response_param":"下发任务的请求参数",
"is_group_congrol_issue_seq":"是否按组控制下发顺序",
"unfinish_notify_time":"任务未完成通知时间数",
"sql_param":"sql配置",
"workshop_code":"车间编码"
},
"storattr":{"stor_code":"仓库编码",
"stor_name":"仓库名称",
"simple_name":"仓库简称",
"stor_capacity":"仓库容量",
"total_area":"总面积",
"stor_type_scode":"仓库性质",
"is_virtualstore":"是否虚拟库",
"is_semi_finished":"是否半成品库",
"is_materialstore":"是否原料库",
"is_productstore":"是否成品库",
"is_attachment":"是否备件库",
"is_reversed":"是否允许红冲",
"is_mvout_auto_cfm":"是否移出业务自动确认",
"is_mvin_auto_cfm":"是否移入业务自动确认",
"area":"地区",
"storea_ddress":"仓库地址",
"principal":"负责人",
"office_phone":"办公电话",
"mobile_no":"负责人手机",
"order_index":"显示顺序",
"whstate_scode":"状态",
"base_class_id":"物料基本分类",
"sysownerid":"拥有者ID",
"sysdeptid":"部门ID",
"syscompanyid":"公司ID",
"ext_id":"外部标识",
"depart_name":"部门名称",
"company_name":"公司名称"},
"checkmst":{"seq_no":"明细序号",
"sect_code":"盘点库区",
"struct_code":"盘点货位",
"checkpoint_code":"盘点站台",
"storagevehicle_code":"存储载具编码",
"material_id":"物料标识",
"pcsn":"批次",
"base_qty":"库存数量",
"status":"状态",
"is_down":"是否已下发",
"fac_qty":"盘点数量",
"check_result":"盘点结果",
"check_optname":"盘点人姓名",
"check_time":"盘点时间",
"remark":"明细备注",
"check_code":"盘点单号",
"check_type":"盘点单类型",
"stor_name":"仓库名称",
"dtl_num":"明细数",
"create_mode":"生成方式",
},
"st_ivt_iostor": {"stor_code":"仓库编码",
"sect_date":"日期",
"quality_scode":"品质类型",
"start_num":"期初数",
"in_num":"入库数",
"out_num":"出库数",
"total_qty":"总数量",
"total_weight":"总重量",
"io_type":"出入类型",
"detail_count":"明细数",
"seq_no":"明细序号",
"work_status":"执行状态",
"task_id":"任务标识",
"storagevehicle_code":"存储载具编码",
"is_issued":"是否已下发",
"plan_qty":"计划数量",
"real_qty":"实际数量",
"point_code":"出入点位标识",
"assign_qty":"已分配数量",
"unassign_qty":"未分配数量",
"mol_code":"损溢单号",
"mol_inv_type":"损溢单类型",
"mol_type":"损溢类型",
"turnout_sect_code":"转出库区编码",
"turnout_struct_code":"转出仓位编码",
"turnin_sect_code":"转入库区编码",
"turnin_struct_code":"转入仓位编码"
},
"structWarning": {
"safe_qty_lower_limit":"安全库存数量下线",
"safe_qty_upper_limit":"安全库存数量上限",
"cron":"表达式",
"notify_type":"通知类型",
"overdue_days":"超时天数",
"safe_days":"安全天数",
"is_read":"是否已读",
"current_qty":"当前数量"
},
"strategy": {"sect_code":"库区",
"strategy":"规则",
"strategy_type":"1入库策略 2出库策略",
"description":"描述",
"strategy_code":"策略编码",
"strategy_name":"策略名称",
"class_type":"类处理类型",
"param":"处理类",
"ban":"禁止操作",
"form_data":"限定参数"},
"code_rule": {"current_value":"当前值"},
"dept": {"dept_id":"ID",
"pid":"上级部门",
"sub_count":"子部门数目",
"name":"名称",
"zh_name":"中文名称",
"in_name":"印尼名称",
"en_name":"英文名称",
"dept_sort":"排序",
"is_used":"状态",
"create_id":"",
"create_name":"创建者",
"update_id":"",
"update_name":"更新者",
"create_time":"创建日期",
"update_time":"更新时间",
"code":"部门编号",
"ext_id":""},
"dict":{"dict_type":"字典类型",
"dict_sort":"排序号",
"label":"字典标签",
"value":"字典值",
"para1":"参数1",
"para2":"参数2",
"para3":"参数3"},
"menu":{"menu_id":"菜单标识",
"pid":"上级菜单ID",
"sub_count":"子菜单数目",
"type":"菜单类型",
"system_type":"所属系统",
"category":"菜单分类",
"title":"菜单标题",
"en_title":"英语标题",
"in_title":"印尼标题",
"zh_title":"中文标题",
"component_name":"组件名称",
"component":"组件",
"menu_sort":"排序",
"icon":"图标",
"path":"链接地址",
"iframe":"是否外链",
"cache":"是否缓存",
"hidden":"是否隐藏",
"permission":"权限",
"is_pc":"是否PC菜单"},
"param":{
"code":"编码",
"name":"名称",
"zh_name":"名称",
"en_name":"英文名称",
"in_name":"印尼名称",
"value":"值"},
"role":{
"level":"角色级别"
},
"user":{"user_id":"用户标识",
"username":"登录账号",
"password":"密码",
"is_admin":"是否为admin账号",
"person_name":"姓名",
"zh_person_name":"姓(中文)",
"en_person_name":"姓(英文)",
"in_person_name":"印尼名称",
"gender":"性别",
"zh_gender":"性(中文)",
"en_gender":"性(英文)",
"phone":"电话",
"email":"电子邮箱",
"avatar_name":"头像地址",
"avatar_path":"头像真实路径",
"extperson_id":"外部人员标识",
"extuser_id":"外部用户标识",
"pwd_reset_user_id":"密码重置者",
"pwd_reset_time":"密码重置时间"}
}

View File

@@ -31,4 +31,20 @@
</dependency>
</dependencies>
<distributionManagement>
<!--正式版本-->
<repository>
<!-- maven settings.xml中<server>的id-->
<id>maven-releases</id>
<name>nexus-releases</name>
<url>http://47.111.78.178:8013/repository/maven-releases/</url>
</repository>
<!--快照-->
<snapshotRepository>
<id>maven-snapshots</id>
<name>nexus-snapshots</name>
<url>http://47.111.78.178:8013/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

View File

@@ -17,6 +17,7 @@
<modules>
<module>nl-verify-check-sdk</module>
<module>nl-verify-check-test</module>
<module>nl-i18n-sdk</module>
</modules>
<properties>