whyclxw
2025-03-06 57f30accf6dd61c0d0db4fab8e4b6f24e4f85c22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
package com.whyc.service;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whyc.constant.UserOperation;
import com.whyc.dto.FileDirPath;
import com.whyc.dto.Response;
import com.whyc.dto.SoftDto;
import com.whyc.mapper.SoftcodeMapper;
import com.whyc.mapper.SoftwareMapper;
import com.whyc.pojo.Softcode;
import com.whyc.pojo.Software;
import com.whyc.util.ActionUtil;
import com.whyc.util.CommonUtil;
import com.whyc.util.DateUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
 
@Service
public class SoftwareService {
    @Autowired(required = false)
    private SoftwareMapper mapper;
 
    @Autowired(required = false)
    private SoftcodeMapper codeMapper;
 
    @Autowired
    private DocLogService logService;
 
    public Response<Object> excelParse(InputStream inputStream) throws IOException, InvalidFormatException, ParseException {
        List<Software> softwareList = new LinkedList<>();
 
        Workbook workbook = null;
        workbook = WorkbookFactory.create(inputStream);
        inputStream.close();
        //取第一个sheet表
        Sheet sheet = workbook.getSheetAt(0);
        int lastRowNum = sheet.getLastRowNum();
        //校准lastRowNum
        for (int i = 8; i <= lastRowNum; i++) {
            if(sheet.getRow(i).getCell(1).getStringCellValue().equals("发布说明")){
                lastRowNum = i;
                break;
            }
        }
        //固定5列
        short cellNum = 5;
        //取固定部分值
        Software common = new Software();
        common.setFileName(sheet.getRow(2).getCell(2).getStringCellValue());
        Cell cellBoardNumber = sheet.getRow(3).getCell(2);
        if(cellBoardNumber != null){
            common.setBoardNumber(cellBoardNumber.getStringCellValue());
        }
        String typeStr = sheet.getRow(4).getCell(2).getStringCellValue();
        String[] typeArr = typeStr.split(" ");
        for (int i = 0; i < typeArr.length; i++) {
            //excel单元格中的✔对应字符
            if(typeArr[i].contains("þ")){
                common.setType(typeArr[i].replace("þ","").trim());
                break;
            }
        }
        //检验
        if(!common.getType().equals("应用软件")){
            if(common.getBoardNumber() == null){
                return new Response().set(1,false,"当是BootLoader 软件、操作系统软件(核心板)软件时,需填写PCB的规格型号");
            }
        }
        common.setVersion(sheet.getRow(5).getCell(2).getStringCellValue());
        common.setBasedVersion(sheet.getRow(5).getCell(4).getStringCellValue());
 
        common.setOwner(sheet.getRow(6).getCell(2).getStringCellValue());
        Cell cellFilingDate = sheet.getRow(6).getCell(4);
        if(cellFilingDate.getCellType() == Cell.CELL_TYPE_NUMERIC){
            Date dateCellValue = cellFilingDate.getDateCellValue();
            common.setFilingDate(DateUtil.YYYY_MM_DD.format(dateCellValue));
            System.out.println(dateCellValue);
        }else {
            cellFilingDate.setCellType(Cell.CELL_TYPE_STRING);
            common.setFilingDate(cellFilingDate.getStringCellValue());
        }
        //最后一行,取发布说明
        common.setReleaseNotes(sheet.getRow(lastRowNum).getCell(2).getStringCellValue());
 
        //第9行开始,倒数第2行截止
        int applyModelNum = lastRowNum + 1 - 9;
        for (int i = 0; i < applyModelNum; i++) {
            Software software = new Software();
            BeanUtils.copyProperties(common,software);
            //取第3列,第5列
            Cell cell = sheet.getRow(8 + i).getCell(2);
            cell.setCellType(Cell.CELL_TYPE_STRING);
            String stringCellValue = cell.getStringCellValue();
            if(!stringCellValue.equals("")) {
                int length = stringCellValue.length();
                if (length == 9) {
                    stringCellValue = "0" + stringCellValue;
                } else if (length < 9) {
                    int centerZeroNum = 10 - length - 1;
                    StringBuilder centerZeroStr = new StringBuilder();
                    for (int j = 0; j < centerZeroNum; j++) {
                        centerZeroStr.append("0");
                    }
                    String strFront = stringCellValue.substring(0, 3);
                    String strBehind = stringCellValue.substring(3);
                    stringCellValue = "0" + strFront + centerZeroStr + strBehind;
                }
            }
            software.setApplyMaterialCode(stringCellValue);
            software.setApplyModel(sheet.getRow(8+i).getCell(4).getStringCellValue());
 
            softwareList.add(software);
        }
 
        softwareList = softwareList.stream().filter(software -> !software.getApplyMaterialCode().equals("")).collect(Collectors.toList());
 
        return new Response().setII(1,true,softwareList,"文件解析成功");
 
    }
    //查询软件列表的信息
    public Response getAllSoftware(Integer lockFlag, String fileName, String applyMaterialCode, String applyModel, String owner, String boardNumber
            ,String version, int pageCurr, int pageSize) {
        PageHelper.startPage(pageCurr,pageSize);
        List<SoftDto> list=mapper.getFileUrl(lockFlag,fileName,applyMaterialCode,applyModel,owner,boardNumber,version);
        //根据软件名称查询是否存在源码(0:否,1:存在)
        for (SoftDto dto:list) {
            QueryWrapper wrapper=new QueryWrapper();
            wrapper.eq("file_name",dto.getFileName());
            wrapper.last("limit 1");
            Softcode code=codeMapper.selectOne(wrapper);
            if(code!=null){
                dto.setCodeFlag(1);
                dto.setCodeName(code.getCodeName());
            }else{
                dto.setCodeFlag(0);
                dto.setCodeName("");
            }
        }
        PageInfo pageInfo=new PageInfo(list);
        return new Response().setII(1,list.size()>0,pageInfo,"软件信息返回");
    }
    //根据subcode查询软件列表
    public Response getSoftBySubCode(String subCode) {
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("apply_material_code",subCode);
        wrapper.orderByAsc("version");
        List list=mapper.selectList(wrapper);
        return new Response().setII(1,list.size()>0,list,"软件信息返回");
    }
 
    
    //根据软件名称实现软件下载
    public void downLoadSoftware(HttpServletRequest req, HttpServletResponse resp, int id) {
        String fileDirName = FileDirPath.getFileDirName();
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("id",id);
        wrapper.last("limit 1");
        Software software=mapper.selectOne(wrapper);
 
        String filename=software.getFileUrl().substring(software.getFileUrl().lastIndexOf("\\")+1);
        try {
            // 转码防止乱码
            //resp.addHeader("Content-Disposition", "attachment;filename=" + new String(softwareName.getBytes("UTF-8"), "ISO8859-1"));
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode (filename, "utf-8"));
            OutputStream out = resp.getOutputStream();
            FileInputStream in = new FileInputStream(fileDirName+File.separator+software.getFileUrl());
            int len=0;
            byte[] buffer =new byte[1024];
            //7. 将缓冲区中的数据输出
            while ((len=in.read(buffer))>0){
                out.write(buffer,0,len);
            }
            in.close();
            out.close();
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //记录日志
        logService.recordOperationLogDownLoad(ActionUtil.getUser().getId(),ActionUtil.getUser().getName(), UserOperation.TYPE_DOWNLOAD_SOFWARE.getType(),new Date(),req.getRemoteAddr()
                ,filename,fileDirName+File.separator+software.getFileUrl(),"",String.valueOf(id),software.getVersion());
 
    }
 
    @Transactional
    public Response upload(MultipartFile file1, MultipartFile file2, String fontUpdateTime, List<Software> softwareList) throws IOException {
        String userName = ActionUtil.getUser().getName();
        String file1Name = file1.getOriginalFilename();
        String file2Name = file2.getOriginalFilename();
        Software software = softwareList.get(0);
        if(!software.getFileName().equals(file1Name.substring(0,file1Name.lastIndexOf(".")))){
            return new Response().set(1,false,"附件的文件名与软件发布记录excel内的文件名称不一致");
        }
        Software softExists = getByFilename(software.getFileName());
        if(softExists != null){ //文件名:规格型号_软件版本,已存在,不能重复上传;这种情况属于追加机型,别处更新
            return new Response().set(1,false,"文件名称("+softExists.getFileName()+")已存在,不能重复上传");
        }
        Date date = new Date();
        String dateUnion = DateUtil.YYYY_MM_DD_HH_MM_SS_UNION.format(date);
        //文件重命名(严格遵守名称规则的情况下不会重名)
        file1Name = file1Name.substring(0,file1Name.lastIndexOf(".")) + "_" + dateUnion +file1Name.substring(file1Name.lastIndexOf("."));
        file2Name = file2Name.substring(0,file2Name.lastIndexOf(".")) + "_" + dateUnion +file2Name.substring(file2Name.lastIndexOf("."));
        //存储路径
        String rootFile = CommonUtil.getRootFile();
        String softwareDir = rootFile + "software" + File.separator + software.getOwner()+ File.separator + software.getFileName();
        String softwareHttpUrl = softwareDir.substring(softwareDir.lastIndexOf("doc_file"+ File.separator + "software"));
        File softwareDirFile = new File(softwareDir);
        if(!softwareDirFile.exists()){
            softwareDirFile.mkdirs();
        }
        file1.transferTo(new File(softwareDir+File.separator+file1Name));
        file2.transferTo(new File(softwareDir+File.separator+file2Name));
        //设置路径
        for (Software software1:softwareList){
            software1.setFontUpdateTime(fontUpdateTime);
            software1.setFileUrl(softwareHttpUrl+File.separator+file1Name);
            software1.setExcelUrl(softwareHttpUrl+File.separator+file2Name);
            software1.setCreateTime(date);
            software1.setUploadUser(userName);
            //锁定-专供测试人员才能解锁
            software1.setLockFlag(-1);
        }
        /* 取消自动锁定原来版本,因为新版本需要进行测试才能使用
        //锁定原来的所有版本:根据版号和软件类型
        List<String> materialCodeList = softwareList.stream().map(Software::getApplyMaterialCode).collect(Collectors.toList());
        lockByBoardNumberAndTypeAndMaterialCode(software.getBoardNumber(),software.getType(),materialCodeList);*/
        //写入数据库
        insertBatch(softwareList);
        return new Response().set(1,true,"上传完成");
    }
 
    private void lockByBoardNumberAndTypeAndMaterialCode(String boardNumber, String type, List<String> materialCodeList) {
        UpdateWrapper<Software> update = Wrappers.update();
        update.set("lock_flag",1)
                .set("local_reason","软件版本升级")
                .eq("board_number",boardNumber)
                .eq("type",type)
                .ne("lock_flag",-1)
                .in("apply_material_code",materialCodeList);
        mapper.update(null,update);
    }
 
    private Software getByFilename(String fileName) {
        QueryWrapper<Software> query = Wrappers.query();
        query.eq("file_name",fileName).last(" limit 1");
        return mapper.selectOne(query);
    }
 
    private void insertBatch(List<Software> softwareList){
        mapper.insertBatchSomeColumn(softwareList);
    }
 
    @Transactional
    public Response updateApplyModel(MultipartFile multipartFile, List<Software> softwareList) throws IOException {
        String originalFilename = multipartFile.getOriginalFilename();
        Software software = softwareList.get(0);
        QueryWrapper<Software> query = Wrappers.query();
        query.eq("file_name", software.getFileName()).last(" limit 1");
        Software softwareDB = mapper.selectOne(query);
        if(softwareDB == null){
            return new Response().set(1,false,"对应的软件并未上传过,无法更新适用机型");
        }else{
            //写入新增的软件发布记录excel
            String rootFile = CommonUtil.getRootFile();
            String softwareDir = rootFile + "software" + File.separator + software.getOwner()+ File.separator + software.getFileName();
            String softwareHttpUrl = softwareDir.substring(softwareDir.lastIndexOf("doc_file"+ File.separator + "software"));
            multipartFile.transferTo(new File(softwareDir + File.separator + originalFilename));
            //先删除对应的适用机型,再新增适用机型记录
            UpdateWrapper<Software> update = Wrappers.update();
            update.eq("file_name",softwareDB.getFileName());
            mapper.delete(update);
            String fontUpdateTime = softwareDB.getFontUpdateTime();
            softwareList.forEach(software2 -> {
                software2.setFileUrl(softwareDB.getFileUrl());
                software2.setExcelUrl(softwareHttpUrl + File.separator + originalFilename);
                software2.setCreateTime(new Date());
                software2.setLockFlag(-1);
                software2.setFontUpdateTime(fontUpdateTime);
            });
            mapper.insertBatchSomeColumn(softwareList);
 
            return new Response().set(1,true,"更新完成");
        }
    }
 
    /**
     * 根据软件唯一值字段修改软件锁定状态,这里选取fileUrl
     *
     * @param fileUrl
     * @param lockFlagNow
     * @param lockFlag
     * @param localReason
     * @return
     */
    public Response updateSoftwareLock(String fileUrl, int lockFlagNow, int lockFlag, String localReason) {
        String userName = ActionUtil.getUser().getName();
        if(lockFlag ==0){
            //只有李桂华才能解锁 待测试锁定的软件
            QueryWrapper<Software> query = Wrappers.query();
            query.eq("file_url",fileUrl);
            List<Software> softwareListInDB = mapper.selectList(query);
            Software softwareInDB = softwareListInDB.get(0);
            if(softwareInDB.getLockFlag() == -1){
                //if(!userName.equals("李桂华")){
                //    return new Response().set(1,false,"无权限解锁 待测试的软件");
                //}else{
                    //锁定原来的所有版本:根据版号和软件类型,排除待测试版本
                    List<String> materialCodeList = softwareListInDB.stream().map(Software::getApplyMaterialCode).collect(Collectors.toList());
                    lockByBoardNumberAndTypeAndMaterialCode(softwareInDB.getBoardNumber(),softwareInDB.getType(),materialCodeList);
 
                //}
            }
        }
        UpdateWrapper uwrapper=new UpdateWrapper();
        uwrapper.set("lock_flag",lockFlag);
        uwrapper.set("local_reason",localReason);
        uwrapper.eq("file_url",fileUrl);
        uwrapper.eq("lock_flag",lockFlagNow);
        int flag=mapper.update(null,uwrapper);
        return new Response().set(1,flag>0,"锁定/解锁成功");
    }
    //根据软件名称实现软件删除
    public Response deleteSoftware(String fileName,String version) {
        UpdateWrapper wrapper=new UpdateWrapper();
        wrapper.eq("file_name",fileName);
        wrapper.eq("version",version);
        int flag=mapper.delete(wrapper);
        return new Response().set(1,flag>0,"件id实现软件删除");
    }
 
    //查询日期三天内的所有上传软件
    public Response getFileNameByCreateTime(String createTime) {
        //获取endtime的三天前的时间
        LocalDate createDay= LocalDate.parse(createTime);
        LocalDateTime end = createDay.atTime(LocalTime.MAX);
        Date endtime=Date.from(end.atZone(ZoneId.systemDefault()).toInstant());
        //获取createTime的三天前的时间
        LocalDate threeDaysAgo = createDay.minusDays(3);
        LocalDateTime startOfDay = threeDaysAgo.atStartOfDay();
        Date starttime=Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
 
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.select("distinct *");
        wrapper.ge("create_time",starttime);
        wrapper.le("create_time",endtime);
        List<Software> list=mapper.selectList(wrapper);
        //获取list中fileName的集合
        //List<String> nameList = list.stream().map(Software::getFileName).collect(Collectors.toList());
        return new Response().setII(1,list!=null,list,"查询日期三天内的所有上传软件");
    }
}