【功能开发】程序文件管理——后端API接口(一)
需求分析
目前公司产线上的芯片制造,需要使用.NC文件。
当设计师使用软件绘制好CNC文件后,会使用U盘接入CNC设备中,进行制造。
由于没有相应的统计和管理功能,CNC制造非常混乱。
公司领导决定开发一个功能,让所有的CNC工程师将自己绘制的CNC图纸记录到系统中,而且要尽可能的简化记录的难度。
目前,CNC中最关键的信息,是物料编号,切削时间和理论加工时间。
这三个字段,可以通过解析上传的文件获得。
另外,上传文件的文件名就是程序的名称,目前CNC工程师只需要填写程序编号,然后选择所属公司和工序号,其余的字段均由后端程序进行解析获得。
后来,我提出如果上传的是A文件,后来发现A文件有缺陷,修改后再次上传,这种情况是否允许上传?
领导思考后,决定允许上传,为了避免重复,增加版本号的设置,默认为1,相同文件多次上传,版本每次+1。
后期可以让审核人员审核录入的CNC图纸,对于审核通过的图纸,使用定时任务,每隔一段时间,自动发送到CNC设备,进行制造。
建表
BU_Program_File
CREATE TABLE `BU_Program_File` (
`program_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`program_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '程序编号',
`program_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '程序名称',
`version` int DEFAULT '1' COMMENT '版本号',
`company_id` tinyint DEFAULT '1' COMMENT '所属公司ID',
`process_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '工序号',
`process_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '工序名称',
`match_time` bigint DEFAULT '0' COMMENT '理论加工时间',
`cut_time` bigint DEFAULT '0' COMMENT '切削时间',
`file_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '文件名(带格式后缀)',
`file_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '文件路径',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
`create_by` int DEFAULT NULL COMMENT '上传者',
`create_time` bigint DEFAULT NULL COMMENT '上传时间',
`update_by` int DEFAULT NULL COMMENT '更新者',
`update_time` bigint DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`program_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='程序文件表';
BU_Program_Part
CREATE TABLE `BU_Program_Part` (
`part_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`program_id` bigint DEFAULT NULL COMMENT '系统ID',
`part_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '物料编号',
`type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '订单类型(1生产订单 2制令单)',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
PRIMARY KEY (`part_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='程序物料表';
文件上传
文件上传功能是单独的一个模块,本质上是通过file.transferTo(desc)
进行上传的。
可以看到,这是一个复制方法。
目前上传成功后,会返回文件服务器上的地址,这里的文件名是个UUID,而领导要求返回上传文件的本名,和带有格式后缀的全路径名。
另外,还要解析文件中的物料编号,切削时间和理论加工时间。
为此,单独写一个接口,做到和原本的文件上传解耦。
SysFileController.java
/**
* 数字化模块文件上传,
* 获取上传文件中的切削时间,物料编号和预计加工时间
* ( NC=2.38KB**CUT TIME=0.19MIN**MACH TIME=0.54MIN )
*/
@PostMapping("uploadCnc")
public R<CncFile> uploadCnc(MultipartFile file){
try {
// 上传并返回访问地址
CncFile cncFile = sysFileService.getData(file);
String url = sysFileService.uploadCNCFile(file);
cncFile.setFileName(file.getOriginalFilename());
cncFile.setProgramName(getFileName(file.getOriginalFilename()));
cncFile.setUrl(url);
return R.ok(cncFile);
}catch (Exception e){
log.error("上传文件失败", e);
return R.fail(e.getMessage());
}
}
// 上传的文件去掉格式(如.txt .doc等)
private String getFileName(String originalFilename) {
if (StringUtils.isNotEmpty(originalFilename)) {
if(originalFilename.lastIndexOf(".") > -1){
return originalFilename.substring(0, originalFilename.lastIndexOf("."));
}
}
return originalFilename;
}
/**
* CNC文件删除
*/
@DeleteMapping("deleteCnc")
public boolean deleteCnc(String fileUrl){
return sysFileService.deleteCncFile(fileUrl);
}
LocalSysFileServiceImpl.java
/**
* 数字化模块文件上传接口
* @param file 上传的文件
* @return 访问地址
*/
@Override
public String uploadCNCFile(MultipartFile file) throws Exception{
// 数字化模块文件上传到DWWS文件夹内
String filePath = path + "/DWWS";
String name = FileUploadUtils.upload(filePath, file);
StringBuffer sb = new StringBuffer();
// 解决9304跨域跳转问题(Nginx配置/fileserver规则映射)
sb.append("/fileserver").append(prefix).append("/DWWS").append(name);
return sb.toString();
}
@Override
public boolean deleteCncFile(String fileUrl) {
fileUrl = fileUrl.replace("/fileserver/statics",path);
File file = new File(fileUrl);
if(file.isFile() && file.exists()){
Boolean result = file.delete();
if(result){
return true;
}
}
return false;
}
@Override
public CncFile getData(MultipartFile file){
CncFile cncFile = new CncFile();
// 数据初始化,如果读取不到数据,返回错误格式,前台填写
cncFile.setPartName("数据格式有误");
cncFile.setCutTime(0L);
cncFile.setMatchTime(0L);
try {
BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream(), Charset.forName("GBK")));
String read;
while((read = br.readLine()) != null){
if(read.contains("PART NAME")){
int machTimeIndex = read.indexOf("PART NAME");
int minIndex = read.indexOf(".PRT");
String s = read.substring(machTimeIndex, minIndex);
String partName = s.replace("PART NAME:", "").trim();
cncFile.setPartName(partName);
}
if(read.contains("CUT TIME")){
String s = read.substring(read.indexOf("CUT TIME"), read.indexOf("MIN"));
String str = s.replace("CUT TIME=", "").trim();
BigDecimal bigDecimal = new BigDecimal(str);
Long cutTime = bigDecimal.multiply(new BigDecimal(60*1000)).longValue();
cncFile.setCutTime(cutTime);
}
if (read.contains("MACH TIME")) {
String s = read.substring(read.lastIndexOf("MACH TIME"), read.lastIndexOf("MIN"));
String r = s.replace("MACH TIME=", "").trim();
BigDecimal bigDecimal = new BigDecimal(r);
Long matchTime = bigDecimal.multiply(new BigDecimal(60*1000)).longValue();
cncFile.setMatchTime(matchTime);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return cncFile;
}
这里提一下,CNC文件均有软件生成,格式固定,编码固定(ANSI),在后端必须用GBK编码,否则会出现乱码,说多了都是累。