Commit 30b99676 authored by 李驰骋's avatar 李驰骋

token添加国际化字段

parent 5c32c654
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ResourceBundleManager">
<file url="file://$PROJECT_DIR$/src/main/resources/i18n/messages.properties" />
<file url="file://$PROJECT_DIR$/src/main/resources/i18n/messages_th.properties" />
<file url="file://$PROJECT_DIR$/src/main/resources/i18n/messages_zh_CN.properties" />
<custom-resource-bundle>
<file value="file://$PROJECT_DIR$/src/main/resources/i18n/messages.properties" />
<file value="file://$PROJECT_DIR$/src/main/resources/i18n/messages_en.properties" />
<file value="file://$PROJECT_DIR$/src/main/resources/i18n/messages_th.properties" />
<file value="file://$PROJECT_DIR$/src/main/resources/i18n/messages_zh_CN.properties" />
<base-name>messages</base-name>
</custom-resource-bundle>
</component>
</project>
\ No newline at end of file
...@@ -105,6 +105,10 @@ public class Constants { ...@@ -105,6 +105,10 @@ public class Constants {
* 用户名称 * 用户名称
*/ */
public static final String JWT_USERNAME = Claims.SUBJECT; public static final String JWT_USERNAME = Claims.SUBJECT;
/**
* 用户多语言
*/
public static final String JWT_LOCAL = "local";
/** /**
* 用户头像 * 用户头像
......
...@@ -18,7 +18,6 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; ...@@ -18,7 +18,6 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
* @version V1.0 * @version V1.0
* @date 2021/10/19 * @date 2021/10/19
*/ */
@EnableWebMvc
@Configuration @Configuration
public class UnifiedReturnConfig { public class UnifiedReturnConfig {
@RestControllerAdvice("com.topsunit") @RestControllerAdvice("com.topsunit")
......
package com.topsunit.scanservice.ximai.common; package com.topsunit.scanservice.ximai.common;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
XimaiLocaleResolver resolver;
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") registry.addMapping("/**")
...@@ -15,4 +20,8 @@ public class WebMvcConfig implements WebMvcConfigurer { ...@@ -15,4 +20,8 @@ public class WebMvcConfig implements WebMvcConfigurer {
.allowedMethods("GET", "POST", "PUT", "DELETE") .allowedMethods("GET", "POST", "PUT", "DELETE")
.maxAge(3600); .maxAge(3600);
} }
@Bean
public LocaleResolver localeResolver(){
return resolver;
}
} }
package com.topsunit.scanservice.ximai.common;
import com.topsunit.scanservice.ximai.dto.LoginResult;
import com.topsunit.scanservice.ximai.security.TokenAudience;
import com.topsunit.scanservice.ximai.security.TokenManger;
import com.topsunit.scanservice.ximai.security.TokenService;
import com.topsunit.scanservice.ximai.security.impl.TokenMangerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
@Component
public class XimaiLocaleResolver implements LocaleResolver {
@Autowired
TokenManger tokenManger;
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
@Override
public Locale resolveLocale(HttpServletRequest request) {
TokenAudience tokenAudience = tokenManger.getTokenAudience(request.getHeader("Authorization"));
if(StringUtil.isNullOrEmpty(tokenAudience.getLocal())){
return Locale.getDefault();
}else{
String locale = tokenAudience.getLocal();
String[] localeArr = locale.split("-");
if(localeArr.length==1){
return new Locale(locale, "");
}else{
return new Locale(localeArr[0], localeArr[1]);
}
}
}
}
package com.topsunit.scanservice.ximai.dto; package com.topsunit.scanservice.ximai.dto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
/** /**
...@@ -28,4 +30,7 @@ public class LoginResult { ...@@ -28,4 +30,7 @@ public class LoginResult {
* token * token
*/ */
private String token; private String token;
@ApiModelProperty("多语言")
private String local;
} }
package com.topsunit.scanservice.ximai.security; package com.topsunit.scanservice.ximai.security;
import lombok.Data;
/** /**
* <p>Title: TokenAudience</p> * <p>Title: TokenAudience</p>
* <p>Description: TokenAudience</p> * <p>Description: TokenAudience</p>
...@@ -8,35 +10,22 @@ package com.topsunit.scanservice.ximai.security; ...@@ -8,35 +10,22 @@ package com.topsunit.scanservice.ximai.security;
* @version V1.0 * @version V1.0
* @date 2021/11/4 * @date 2021/11/4
*/ */
@Data
public class TokenAudience { public class TokenAudience {
public TokenAudience() { public TokenAudience() {
} }
public TokenAudience(String actorId, String company) { public TokenAudience(String actorId, String local,String company) {
this.actorId = actorId; this.actorId = actorId;
this.local=local;
this.company = company; this.company = company;
} }
private String actorId; private String actorId;
private String local;
private String company; private String company;
public String getActorId() { public static TokenAudience of(String actorId, String local, String company){
return actorId; return new TokenAudience(actorId, local, company);
}
public void setActorId(String actorId) {
this.actorId = actorId;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public static TokenAudience of(String actorId, String company){
return new TokenAudience(actorId, company);
} }
} }
...@@ -10,7 +10,7 @@ package com.topsunit.scanservice.ximai.security; ...@@ -10,7 +10,7 @@ package com.topsunit.scanservice.ximai.security;
*/ */
public interface TokenManger { public interface TokenManger {
String generate(String id, String company); String generate(String id, String local, String company);
TokenAudience getTokenAudience(String token); TokenAudience getTokenAudience(String token);
} }
...@@ -81,6 +81,11 @@ public class TokenService ...@@ -81,6 +81,11 @@ public class TokenService
return token; return token;
} }
public LoginResult getUserByToken(HttpServletRequest request){
String token = this.getToken(request);
return this.getUserByToken(token);
}
private String getTokenKey(String uuid) private String getTokenKey(String uuid)
{ {
return Constants.LOGIN_TOKEN_KEY + uuid; return Constants.LOGIN_TOKEN_KEY + uuid;
...@@ -102,10 +107,12 @@ public class TokenService ...@@ -102,10 +107,12 @@ public class TokenService
// 解析对应的权限以及用户信息 // 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userName = (String) claims.get(Constants.JWT_USERNAME); String userName = (String) claims.get(Constants.JWT_USERNAME);
String local = (String) claims.get(Constants.JWT_LOCAL);
String userKey = getTokenKey(uuid); String userKey = getTokenKey(uuid);
rst.setMv001(userName); rst.setMv001(userName);
rst.setMv002(userName); rst.setMv002(userName);
rst.setToken(token); rst.setToken(token);
rst.setLocal(local);
return rst; return rst;
} }
catch (Exception e) catch (Exception e)
......
...@@ -31,10 +31,10 @@ public class TokenMangerImpl implements TokenManger { ...@@ -31,10 +31,10 @@ public class TokenMangerImpl implements TokenManger {
} }
@Override @Override
public String generate(String id, String company) { public String generate(String id, String local, String company) {
Date expiresAt = new Date(System.currentTimeMillis() + appConfig.getTokenExpires()); Date expiresAt = new Date(System.currentTimeMillis() + appConfig.getTokenExpires());
return JWT.create() return JWT.create()
.withAudience(id, company) .withAudience(id, local, company)
.withExpiresAt(expiresAt) .withExpiresAt(expiresAt)
.sign(Algorithm.HMAC256((id).toString())); .sign(Algorithm.HMAC256((id).toString()));
} }
...@@ -45,11 +45,13 @@ public class TokenMangerImpl implements TokenManger { ...@@ -45,11 +45,13 @@ public class TokenMangerImpl implements TokenManger {
throw new TokenInvalidException(); throw new TokenInvalidException();
} }
String actorId; String actorId;
String local;
String company; String company;
try { try {
DecodedJWT decode = JWT.decode(token); DecodedJWT decode = JWT.decode(token);
actorId = decode.getAudience().get(0); actorId = decode.getAudience().get(0);
company = decode.getAudience().get(1); local = decode.getAudience().get(1);
company = decode.getAudience().get(2);
} }
catch(JWTDecodeException e) { catch(JWTDecodeException e) {
throw new TokenInvalidException(); throw new TokenInvalidException();
...@@ -68,6 +70,6 @@ public class TokenMangerImpl implements TokenManger { ...@@ -68,6 +70,6 @@ public class TokenMangerImpl implements TokenManger {
catch(JWTVerificationException e) { catch(JWTVerificationException e) {
throw new TokenInvalidException(e); throw new TokenInvalidException(e);
} }
return TokenAudience.of(actorId, company); return TokenAudience.of(actorId, local, company);
} }
} }
...@@ -20,6 +20,8 @@ import org.springframework.context.ApplicationContext; ...@@ -20,6 +20,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Locale;
/** /**
* <p>Title: CmsmvService</p> * <p>Title: CmsmvService</p>
* <p>Description: 员工基本信息档</p> * <p>Description: 员工基本信息档</p>
...@@ -70,7 +72,7 @@ public class CmsmvService { ...@@ -70,7 +72,7 @@ public class CmsmvService {
}) })
.map(loginMapper::toLoginResult) .map(loginMapper::toLoginResult)
.map(i -> { .map(i -> {
i.setToken(tokenManger.generate(i.getMv001(), loginParams.getCompany())); i.setToken(tokenManger.generate(i.getMv001(), Locale.getDefault().toString(),loginParams.getCompany()));
return i; return i;
}) })
.orElseThrow(() -> new TopsunitException("用户名或密码错误。")); .orElseThrow(() -> new TopsunitException("用户名或密码错误。"));
...@@ -83,9 +85,9 @@ public class CmsmvService { ...@@ -83,9 +85,9 @@ public class CmsmvService {
if(loginResult2.getCode()==500){ if(loginResult2.getCode()==500){
throw new TopsunitException(loginResult2.getMsg()); throw new TopsunitException(loginResult2.getMsg());
} }
//生成扫码自生token
String newToken = tokenManger.generate(loginParams.getUsername(), exAccountInfo.getAccountCode());
LoginResult loginResult = tokenService.getUserByToken(loginResult2.getToken()); LoginResult loginResult = tokenService.getUserByToken(loginResult2.getToken());
//生成扫码自生token
String newToken = tokenManger.generate(loginParams.getUsername(), loginResult.getLocal(),exAccountInfo.getAccountCode());
loginResult.setToken(newToken); loginResult.setToken(newToken);
return loginResult; return loginResult;
} }
......
...@@ -2,6 +2,7 @@ package com.topsunit.scanservice.ximai.service; ...@@ -2,6 +2,7 @@ package com.topsunit.scanservice.ximai.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.topsunit.scanservice.ximai.common.DateUtil; import com.topsunit.scanservice.ximai.common.DateUtil;
import com.topsunit.scanservice.ximai.common.TopsunitException;
import com.topsunit.scanservice.ximai.dao.CoptgDao; import com.topsunit.scanservice.ximai.dao.CoptgDao;
import com.topsunit.scanservice.ximai.dao.CopthDao; import com.topsunit.scanservice.ximai.dao.CopthDao;
import com.topsunit.scanservice.ximai.dao.CoptnDao; import com.topsunit.scanservice.ximai.dao.CoptnDao;
...@@ -35,7 +36,7 @@ public class CopthService { ...@@ -35,7 +36,7 @@ public class CopthService {
@Transactional @Transactional
public void create(StockSaleOutParams params){ public void create(StockSaleOutParams params){
Coptn coptn = coptnDao.findFirstByTn001AndTn002("251", params.getApplyNo()) Coptn coptn = coptnDao.findFirstByTn001AndTn002("251", params.getApplyNo())
.orElseThrow(()->new ServiceException("未找到出货通知单:"+params.getApplyNo())); .orElseThrow(()->new TopsunitException("未找到出货通知单:"+params.getApplyNo()));
BigDecimal total = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO;
Calendar curr = Calendar.getInstance(); Calendar curr = Calendar.getInstance();
String currStr = cn.hutool.core.date.DateUtil.format(curr.getTime(), "yyyyMMdd"); String currStr = cn.hutool.core.date.DateUtil.format(curr.getTime(), "yyyyMMdd");
...@@ -52,7 +53,7 @@ public class CopthService { ...@@ -52,7 +53,7 @@ public class CopthService {
for(StockSaleOutParams.StockSaleOutDetail s : params.getData()){ for(StockSaleOutParams.StockSaleOutDetail s : params.getData()){
//查询出货通知单明细 //查询出货通知单明细
Copto copto = coptoDao.findFirstByTo001AndTo002AndTo007("251", params.getApplyNo(), s.getMaterialNo()) Copto copto = coptoDao.findFirstByTo001AndTo002AndTo007("251", params.getApplyNo(), s.getMaterialNo())
.orElseThrow(()->new ServiceException(String.format("未找到出货通知单明细:%s,%s", params.getApplyNo(), s.getMaterialNo()))); .orElseThrow(()->new TopsunitException(String.format("未找到出货通知单明细:%s,%s", params.getApplyNo(), s.getMaterialNo())));
CopthCreateParams copthCreateParams = new CopthCreateParams(); CopthCreateParams copthCreateParams = new CopthCreateParams();
Copth copth = BeanUtil.copyProperties(copthCreateParams, Copth.class); Copth copth = BeanUtil.copyProperties(copthCreateParams, Copth.class);
copth.setTh001(coptg.getTg001()); copth.setTh001(coptg.getTg001());
......
...@@ -10,6 +10,7 @@ import com.topsunit.scanservice.ximai.entity.Invma; ...@@ -10,6 +10,7 @@ import com.topsunit.scanservice.ximai.entity.Invma;
import com.topsunit.scanservice.ximai.entity.Invmb; import com.topsunit.scanservice.ximai.entity.Invmb;
import com.topsunit.scanservice.ximai.entity.Invmc; import com.topsunit.scanservice.ximai.entity.Invmc;
import com.topsunit.scanservice.ximai.entity.Invml; import com.topsunit.scanservice.ximai.entity.Invml;
import com.topsunit.scanservice.ximai.utils.MessageUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -73,7 +74,7 @@ public class InvmcService { ...@@ -73,7 +74,7 @@ public class InvmcService {
} }
public List<InvmlDto> getInvmlList2(InvmlCriteria criteria) { public List<InvmlDto> getInvmlList2(InvmlCriteria criteria) {
invmbDao.findById(criteria.getMl001()).orElseThrow(()->new TopsunitException(String.format("未找到物料:%s",criteria.getMl001()))); invmbDao.findById(criteria.getMl001()).orElseThrow(()->new TopsunitException(MessageUtils.getMessage("未找到物料:")+criteria.getMl001()));
List<IInvmlDto> data = invmlDao.findJoinInvmb(criteria.getMl001(), criteria.getMl002(), criteria.getGtStock()); List<IInvmlDto> data = invmlDao.findJoinInvmb(criteria.getMl001(), criteria.getMl002(), criteria.getGtStock());
return data.stream().map(s->{ return data.stream().map(s->{
......
...@@ -353,6 +353,7 @@ public class SfctbService { ...@@ -353,6 +353,7 @@ public class SfctbService {
*/ */
@Transactional @Transactional
public void check(SfctcCheckParams params) { public void check(SfctcCheckParams params) {
Sfctc sfctc = sfctcDao.findById(new SfctcId(params.getTc001(), params.getTc002(), params.getTc003())) Sfctc sfctc = sfctcDao.findById(new SfctcId(params.getTc001(), params.getTc002(), params.getTc003()))
//.filter(i->i.getCompany().trim().equals(currentActor.getCompany().trim())) //.filter(i->i.getCompany().trim().equals(currentActor.getCompany().trim()))
.filter(i -> i.getTc022().trim().equals("N")) .filter(i -> i.getTc022().trim().equals("N"))
......
package com.topsunit.scanservice.ximai.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MessageUtils {
private static MessageSource messageSource;
@Autowired
private MessageSource messageSourceCopy;
@PostConstruct
private void init() {
setMessageSource(messageSourceCopy);
}
private static synchronized void setMessageSource(MessageSource ms) {
messageSource = ms;
}
public static String getMessage(String code, Object ... arg) {
Object[] args = arg.clone();
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}
}
未找到工单=未找到工单
未找到品号=未找到品号
未找到移出工艺=未找到移出工艺
未找到移入工艺=未找到移入工艺
未设置共享参数设置挡=未设置共享参数设置挡
转移数量不能超过在制量=转移数量不能超过在制量
仓库不存在=仓库不存在
库位不存在=库位不存在
此条码已审核,无法检验=此条码已审核,无法检验
计价数量不能大于验收数量=计价数量不能大于验收数量
验收数量+验退数量+报废数量不能大于转移数量=验收数量+验退数量+报废数量不能大于转移数量
用户名或密码错误。=用户名或密码错误。
未找到登录账套=未找到登录账套
用户不存在=用户不存在
原密码输入有误=原密码输入有误
未找到出货通知单:=未找到出货通知单:
调拨库位与当前一致=调拨库位与当前一致
工单已领料完成。=工单已领料完成。
没有任何领料数量。=没有任何领料数量。
工单不存在=工单不存在
工单已领料完成=工单已领料完成
委外进货单不存在或已审核=委外进货单不存在或已审核
超出进货数量。=超出进货数量。
到货单不存在或已检验。=到货单不存在或已检验。
未找到物料:=未找到物料:
到货单不存在或未检验=到货单不存在或未检验
超出到货单验收数量=超出到货单验收数量
\ No newline at end of file
未找到工单=job not found.
未找到品号=no product number found.
未找到移出工艺=no removal process was found.
未找到移入工艺=move-in process not found
未设置共享参数设置挡=the shared parameter setting block is not set.
转移数量不能超过在制量=the transferred quantity cannot exceed the quantity in process.
仓库不存在=warehouse does not exist
库位不存在=location does not exist
此条码已审核,无法检验=this barcode has been approved and cannot be inspected.
计价数量不能大于验收数量=pricing quantity cannot be greater than acceptance quantity.
验收数量+验退数量+报废数量不能大于转移数量=accepted quantity+returned quantity+scrapped quantity cannot be greater than transferred quantity.
用户名或密码错误。=user name or password is wrong.
未找到登录账套=login sob not found.
用户不存在=user does not exist
原密码输入有误=the original password was entered incorrectly.
未找到出货通知单:=shipment notice not found:
调拨库位与当前一致=the transfer location is consistent with the current one.
工单已领料完成。=the work order has been picked.
没有任何领料数量。=there is no picking quantity.
工单不存在=work order does not exist
工单已领料完成=the work order has been picked.
委外进货单不存在或已审核=subcontract purchase order does not exist or has been approved.
超出进货数量。=exceeding the purchase quantity.
到货单不存在或已检验。=the arrival document does not exist or has been inspected.
未找到物料:=item not found:
到货单不存在或未检验=the arrival document does not exist or has not been inspected.
超出到货单验收数量=exceeding the acceptance quantity of arrival document
\ No newline at end of file
未找到工单=ไม่พบรายการงาน
未找到品号=ไม่พบหมายเลขผลิตภัณฑ์
未找到移出工艺=ไม่พบกระบวนการถอดออก
未找到移入工艺=ไม พบกระบวนการย ายเข
未设置共享参数设置挡=ไม ได ตั งค าตั งค าพารามิเตอร์ใช วม
转移数量不能超过在制量=จํานวนการโอนไม่สามารถเกินมาตรฐานได้
仓库不存在=โกดังไม่มีอยู่
库位不存在=ไม มีช องเก
此条码已审核,无法检验=บาร์โค้ดนี้ได้รับการตรวจสอบแล้วและไม่สามารถตรวจสอบได้
计价数量不能大于验收数量=ปริมาณการเรียกเก็บเงินไม่สามารถเกินจํานวนที่ยอมรับได้
验收数量+验退数量+报废数量不能大于转移数量=จํานวนการยอมรับ+จํานวนการตรวจสอบคืน+จํานวนการทิ้งต้องไม่เกินจํานวนการโอน
用户名或密码错误。=ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง
未找到登录账套=ไม พบกระเป๋าคุมข อมูลเข าระบบ
用户不存在=ผู้ใช้ไม่มีอยู่
原密码输入有误=ป้อนรหัสผ่านเดิมไม่ถูกต้อง
未找到出货通知单:=ไม่พบใบแจ้งเตือนการจัดส่ง:
调拨库位与当前一致=การโอนตําแหน่งห้องสมุดสอดคล้องกับปัจจุบัน
工单已领料完成。=ตารางงานเสร็จสมบูรณ์แล้ว
没有任何领料数量。=ไม่มีปริมาณอาหาร
工单不存在=ตารางงานไม่มีอยู่
工单已领料完成=ตารางงานเสร็จสมบูรณ์แล้ว
委外进货单不存在或已审核=ใบเสร็จรับเงินจากภายนอกไม่มีอยู่หรือได้รับการตรวจสอบแล้ว
超出进货数量。=เกินจํานวนที่เข้ามา
到货单不存在或已检验。=ใบเสร็จรับเงินไม่มีอยู่หรือได้รับการตรวจสอบแล้ว
未找到物料:=ไม่พบวัสดุ:
到货单不存在或未检验=ใบเสร็จรับเงินไม่มีอยู่หรือไม่ได้รับการตรวจสอบ
超出到货单验收数量=เกินจํานวนการยอมรับใบเสร็จรับเงิน
\ No newline at end of file
未找到工单=未找到工单
未找到品号=未找到品号
未找到移出工艺=未找到移出工艺
未找到移入工艺=未找到移入工艺
未设置共享参数设置挡=未设置共享参数设置挡
转移数量不能超过在制量=转移数量不能超过在制量
仓库不存在=仓库不存在
库位不存在=库位不存在
此条码已审核,无法检验=此条码已审核,无法检验
计价数量不能大于验收数量=计价数量不能大于验收数量
验收数量+验退数量+报废数量不能大于转移数量=验收数量+验退数量+报废数量不能大于转移数量
用户名或密码错误。=用户名或密码错误。
未找到登录账套=未找到登录账套
用户不存在=用户不存在
原密码输入有误=原密码输入有误
未找到出货通知单:=未找到出货通知单:
调拨库位与当前一致=调拨库位与当前一致
工单已领料完成。=工单已领料完成。
没有任何领料数量。=没有任何领料数量。
工单不存在=工单不存在
工单已领料完成=工单已领料完成
委外进货单不存在或已审核=委外进货单不存在或已审核
超出进货数量。=超出进货数量。
到货单不存在或已检验。=到货单不存在或已检验。
未找到物料:=未找到物料:
到货单不存在或未检验=到货单不存在或未检验
超出到货单验收数量=超出到货单验收数量
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment