GDW пре 9 месеци
родитељ
комит
31a21afb92
21 измењених фајлова са 1068 додато и 0 уклоњено
  1. 37 0
      .gitignore
  2. 15 0
      src/main/java/cn/lttc/LttcSampleScanApplication.java
  3. 36 0
      src/main/java/cn/lttc/modules/config/SaTokenConfigure.java
  4. 50 0
      src/main/java/cn/lttc/modules/globalexception/GlobalExceptionHandler.java
  5. 75 0
      src/main/java/cn/lttc/modules/lttcsamplescan/controller/SampleScanController.java
  6. 63 0
      src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScan.java
  7. 58 0
      src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScanDetail.java
  8. 36 0
      src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScanFile.java
  9. 23 0
      src/main/java/cn/lttc/modules/lttcsamplescan/mapper/SampleScanMapper.java
  10. 95 0
      src/main/java/cn/lttc/modules/lttcsamplescan/mapper/xml/SampleScanMapper.xml
  11. 18 0
      src/main/java/cn/lttc/modules/lttcsamplescan/service/ISampleScanService.java
  12. 277 0
      src/main/java/cn/lttc/modules/lttcsamplescan/service/impl/SampleScanServiceImpl.java
  13. 81 0
      src/main/java/cn/lttc/modules/sysuser/controller/SysUser.java
  14. 17 0
      src/main/java/cn/lttc/modules/sysuser/entity/User.java
  15. 12 0
      src/main/java/cn/lttc/modules/sysuser/entity/UserDto.java
  16. 12 0
      src/main/java/cn/lttc/modules/sysuser/mapper/SysUserMapper.java
  17. 28 0
      src/main/java/cn/lttc/modules/sysuser/mapper/xml/SampleScanMapper.xml
  18. 11 0
      src/main/java/cn/lttc/modules/sysuser/service/SysUserService.java
  19. 32 0
      src/main/java/cn/lttc/modules/sysuser/service/impl/SysSysUserServiceImpl.java
  20. 51 0
      src/main/java/cn/lttc/modules/utils/HttpUtils.java
  21. 41 0
      src/main/resources/application.yml

+ 37 - 0
.gitignore

@@ -0,0 +1,37 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### file ###
+uploads/
+log/

+ 15 - 0
src/main/java/cn/lttc/LttcSampleScanApplication.java

@@ -0,0 +1,15 @@
+package cn.lttc;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan(value={"cn.lttc.modules.**.mapper*"})
+public class LttcSampleScanApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(LttcSampleScanApplication.class, args);
+    }
+
+}

+ 36 - 0
src/main/java/cn/lttc/modules/config/SaTokenConfigure.java

@@ -0,0 +1,36 @@
+package cn.lttc.modules.config;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.ArrayList;
+
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+    // 注册拦截器
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
+        ArrayList<String> list = new ArrayList<>();
+        list.add("/samplescan/user/login");
+        list.add("/samplescan/api/getimg/**");
+        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
+                .addPathPatterns("/**")
+                .excludePathPatterns(list);
+
+//        registry.addInterceptor(new SaInterceptor(handler -> {
+//            // 指定一条 match 规则
+//            SaRouter.match("/**")    // 拦截的 path 列表,可以写多个 */
+//                    .notMatch("/samplescan/user/login")
+//                    .notMatch("/samplescan/api/getimg/**")
+//                    .check(r -> StpUtil.checkLogin());
+//        })).addPathPatterns("/**");
+    }
+}

+ 50 - 0
src/main/java/cn/lttc/modules/globalexception/GlobalExceptionHandler.java

@@ -0,0 +1,50 @@
+package cn.lttc.modules.globalexception;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+
+    // 全局异常拦截(拦截项目中的NotLoginException异常)
+    @ExceptionHandler(NotLoginException.class)
+    public SaResult handlerNotLoginException(NotLoginException nle) throws Exception {
+
+        // 打印堆栈,以供调试
+        nle.printStackTrace();
+
+        // 判断场景值,定制化异常信息
+        String message = "";
+        if(nle.getType().equals(NotLoginException.NOT_TOKEN)) {
+            message = "未能读取到有效 token";
+        }
+        else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) {
+            message = "token 无效";
+        }
+        else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
+            message = "token 已过期";
+        }
+        else if(nle.getType().equals(NotLoginException.BE_REPLACED)) {
+            message = "token 已被顶下线";
+        }
+        else if(nle.getType().equals(NotLoginException.KICK_OUT)) {
+            message = "token 已被踢下线";
+        }
+        else if(nle.getType().equals(NotLoginException.TOKEN_FREEZE)) {
+            message = "token 已被冻结";
+        }
+        else if(nle.getType().equals(NotLoginException.NO_PREFIX)) {
+            message = "未按照指定前缀提交 token";
+        }
+        else {
+            message = "当前会话未登录";
+        }
+
+        // 返回给前端
+        return SaResult.error(message);
+    }
+}

+ 75 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/controller/SampleScanController.java

@@ -0,0 +1,75 @@
+package cn.lttc.modules.lttcsamplescan.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.dev33.satoken.util.SaResult;
+import cn.lttc.modules.lttcsamplescan.service.ISampleScanService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * @Description: 样品扫描网络API
+ * @Author: GDW
+ * @Date: 2024-01-24
+ * @Version: V1.0
+ */
+@RestController
+@RequestMapping("/samplescan/api")
+public class SampleScanController {
+    private final static Logger logger = LoggerFactory.getLogger(SampleScanController.class);
+    @Resource
+    ISampleScanService sampleScanService;
+
+    @GetMapping("/receive")
+    public String Receive(HttpServletRequest request) {
+        return "OK";
+    }
+
+    @PostMapping("/input")
+    @Transactional
+    public SaResult uploadProjectFile(HttpServletRequest request) {
+        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
+        commonsMultipartResolver.setDefaultEncoding("utf-8");
+        MultipartHttpServletRequest mulReq = (MultipartHttpServletRequest) request;
+        writeLog(mulReq);
+        String uid = sampleScanService.saveData(mulReq);
+        JSONObject jsonObject = JSON.parseObject("{'uid' : '" + uid + "'}");
+        return SaResult.data(jsonObject);
+    }
+
+    @GetMapping("/getimg/{year}/{month}/{filename}")
+    ResponseEntity<byte[]> getImg(@PathVariable String year, @PathVariable String month, @PathVariable String filename) {
+
+        ResponseEntity<byte[]> imgService = sampleScanService.getImgService(year, month, filename);
+
+        return imgService;
+
+    }
+
+    synchronized void writeLog(MultipartHttpServletRequest mulReq) {
+        String mainJson = mulReq.getParameter("main");
+        String detailJson = mulReq.getParameter("detail");
+        Iterator<String> fileNames = mulReq.getFileNames();
+        int num = 0;
+        while (fileNames.hasNext()) {
+            fileNames.next();
+            num++;
+        }
+        logger.info("main json: "+ mainJson);
+        logger.info("detail json: "+ detailJson);
+        logger.info("image num: " + num);
+    }
+}

+ 63 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScan.java

@@ -0,0 +1,63 @@
+package cn.lttc.modules.lttcsamplescan.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Description: lttc_info_main实体类
+ * @Author: GDW
+ * @Date:   2024-01-24
+ * @Version: V1.0
+ */
+
+@Data
+@TableName("lttc_info_main_new")
+public class SampleScan {
+
+    @TableField(value = "billNO")
+    private String billNO;
+
+    @TableField(value = "billDate")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date billDate;
+
+    @TableField(value = "exhibitionName")
+    private String exhibitionName;
+
+    @TableField(value = "receiver")
+    private String receiver;
+
+    @TableField(value = "customerName")
+    private String customerName;
+
+    @TableField(value = "exhibitionNote")
+    private String exhibitionNote;
+
+    @TableField(value = "fileSavePath")
+    private String fileSavePath;
+
+    @TableField(value = "editUser")
+    private String editUser;
+
+    @TableField(value = "editTime")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date editTime;
+
+    @TableField(value = "createTime")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @TableField(value = "ERPMarker")
+    private Byte erpMarker = 0;
+
+    @TableField(value = "uid")
+    private String uid;
+
+
+}

+ 58 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScanDetail.java

@@ -0,0 +1,58 @@
+package cn.lttc.modules.lttcsamplescan.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * @Description: lttc_info_detail实体类
+ * @Author: GDW
+ * @Date:   2024-01-24
+ * @Version: V1.0
+ */
+
+@Data
+@TableName("lttc_info_detail_new")
+public class SampleScanDetail {
+
+    @TableField(value = "uuid")
+    private String uuid;
+
+    @TableField(value = "billNO")
+    private String billNO;
+
+    @TableField(value = "barCode")
+    private String barCode;
+
+    @TableField(value = "bpQuantity")
+    private String bpQuantity;
+
+    @TableField(value = "gyQuantity")
+    private String gyQuantity;
+
+    @TableField(value = "myQuantity")
+    private String myQuantity;
+
+    @TableField(value = "note")
+    private String note;
+
+    @TableField(value = "fileSavePath")
+    private String fileSavePath;
+
+    @TableField(value = "createTime")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @TableField(value = "ERPMarker")
+    private Byte erpMarker = 0;
+
+    @TableField(value = "publicId")
+    private String publicId;
+
+    @TableField(exist = false)
+    private String id;
+
+}

+ 36 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/entity/SampleScanFile.java

@@ -0,0 +1,36 @@
+package cn.lttc.modules.lttcsamplescan.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+@TableName("lttc_file_new")
+public class SampleScanFile {
+
+    @TableField(value = "uuid")
+    private String uuid;
+
+    @TableField(value = "fileName")
+    private String fileName;
+
+    @TableField(value = "fileType")
+    private String fileType;
+
+    @TableField(value = "fileSavePath")
+    private String fileSavePath;
+
+    @TableField(value = "uploadUser")
+    private String uploadUser;
+
+    @TableField(value = "uploadTime")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date uploadTime;
+
+    @TableField(value = "createTime")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+}

+ 23 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/mapper/SampleScanMapper.java

@@ -0,0 +1,23 @@
+package cn.lttc.modules.lttcsamplescan.mapper;
+
+
+import cn.lttc.modules.lttcsamplescan.entity.SampleScan;
+import cn.lttc.modules.lttcsamplescan.entity.SampleScanDetail;
+import cn.lttc.modules.lttcsamplescan.entity.SampleScanFile;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface SampleScanMapper {
+
+    void addMainData(SampleScan sampleScan);
+
+    void addDetailData(List<SampleScanDetail> sampleScanList);
+
+    String getMaxCode();
+
+    void saveImgData(List<SampleScanFile> sampleScanFileList);
+
+}

+ 95 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/mapper/xml/SampleScanMapper.xml

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.lttc.modules.lttcsamplescan.mapper.SampleScanMapper">
+
+
+    <insert id="addMainData" parameterType="cn.lttc.modules.lttcsamplescan.entity.SampleScan">
+        insert into lttc_info_main_new
+        (billNO,
+         billDate,
+         exhibitionName,
+         receiver,
+         customerName,
+         exhibitionNote,
+         fileSavePath,
+         editUser,
+         editTime,
+         createTime,
+         ERPMarker,
+         uid)
+        values
+        (#{billNO},
+          #{billDate},
+          #{exhibitionName},
+          #{receiver},
+          #{customerName},
+          #{exhibitionNote},
+          #{fileSavePath},
+          #{editUser},
+          #{editTime},
+          #{createTime},
+          #{erpMarker},
+          #{uid})
+    </insert>
+
+    <insert id="addDetailData" parameterType="java.util.List">
+        insert into lttc_info_detail_new
+        (uuid,
+         billNO,
+         barCode,
+         bpQuantity,
+         gyQuantity,
+         myQuantity,
+         note,
+         fileSavePath,
+         createTime,
+         ERPMarker,
+         publicId)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.uuid},
+            #{item.billNO},
+            #{item.barCode},
+            #{item.bpQuantity},
+            #{item.gyQuantity},
+            #{item.myQuantity},
+            #{item.note},
+            #{item.fileSavePath},
+            #{item.createTime},
+            #{item.erpMarker},
+            #{item.publicId}
+            )
+        </foreach>
+    </insert>
+
+    <select id="getMaxCode" resultType="String">
+        SELECT MAX(billNO)
+        FROM lttc_info_main_new;
+    </select>
+
+    <insert id="saveImgData" parameterType="java.util.List">
+        insert into lttc_file_new
+        (
+            uuid,
+            fileName,
+            fileType,
+            fileSavePath,
+            uploadUser,
+            uploadTime,
+            createTime
+        )
+        values
+        <foreach collection="list" item="item" separator=",">
+        (
+            #{item.uuid},
+            #{item.fileName},
+            #{item.fileType},
+            #{item.fileSavePath},
+            #{item.uploadUser},
+            #{item.uploadTime},
+            #{item.createTime}
+        )
+        </foreach>
+    </insert>
+</mapper>

+ 18 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/service/ISampleScanService.java

@@ -0,0 +1,18 @@
+package cn.lttc.modules.lttcsamplescan.service;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ISampleScanService {
+
+    String saveData(MultipartHttpServletRequest mulReq);
+
+    ResponseEntity<byte[]> getImgService(String year, String month, String filename);
+
+
+}

+ 277 - 0
src/main/java/cn/lttc/modules/lttcsamplescan/service/impl/SampleScanServiceImpl.java

@@ -0,0 +1,277 @@
+package cn.lttc.modules.lttcsamplescan.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.lttc.modules.lttcsamplescan.entity.SampleScan;
+import cn.lttc.modules.lttcsamplescan.entity.SampleScanDetail;
+import cn.lttc.modules.lttcsamplescan.entity.SampleScanFile;
+import cn.lttc.modules.lttcsamplescan.mapper.SampleScanMapper;
+import cn.lttc.modules.lttcsamplescan.service.ISampleScanService;
+import cn.lttc.modules.utils.HttpUtils;
+import com.alibaba.fastjson.JSON;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * @Description: 保存
+ * @Author: GDW
+ * @Date:   2024-01-24
+ * @Version: V1.0
+ */
+@Service
+public class SampleScanServiceImpl implements ISampleScanService {
+
+    @Value("${file.upload-path}")
+    private String uploadDir;
+    @Resource
+    private SampleScanMapper sampleScanMapper;
+
+    @Override
+    public synchronized String saveData(MultipartHttpServletRequest mulReq) {
+        //日期处理开始
+        // 获取当前年份
+        int currentYear = LocalDate.now().getYear();
+        int currentMonth = LocalDate.now().getMonthValue();
+        int monthLength = Integer.toString(currentMonth).length();
+        //两位字符串月
+        String currentMonthStr;
+        if (monthLength == 1){
+            currentMonthStr = "0" + currentMonth;
+        } else {
+            currentMonthStr = String.valueOf(currentMonth);
+        }
+
+        int dayOfMonth = LocalDate.now().getDayOfMonth();
+        int dayLength = Integer.toString(dayOfMonth).length();
+        //两位字符串 day
+        String dayStr;
+        if (dayLength == 1){
+            dayStr = "0" + dayOfMonth;
+        } else {
+            dayStr = String.valueOf(dayOfMonth);
+        }
+        //日期处理结束
+
+        //处理主表数据与明细表数据
+        String mainJson = mulReq.getParameter("main");
+        String detailJson = mulReq.getParameter("detail");
+        //将JSON字符串转换为Java对象
+        SampleScan sampleScan = JSON.parseObject(mainJson, SampleScan.class);
+        List<SampleScanDetail> sampleScanDetails = JSON.parseArray(detailJson, SampleScanDetail.class);
+
+        //查询数据库中最大的编号
+        String maxCode = sampleScanMapper.getMaxCode();
+        if (maxCode != null && !maxCode.isEmpty()) {
+            // 截取字符串的前面部分和后四位 (前八位为 年 + 月 + 日 后四位为流水号)
+            String frontPart = maxCode.substring(0, maxCode.length() - 4);
+            String lastFourCharacters = maxCode.substring(maxCode.length() - 4);
+            //获取当前的年月日
+            String now = currentYear + currentMonthStr + dayStr;
+            //如果日期相同
+            //则流水号加一
+            if (frontPart.equals(now)) {
+                StringBuilder newCode = new StringBuilder(String.valueOf((Integer.parseInt(lastFourCharacters) + 1)));
+                for (int i = newCode.length(); i < 4; i++) {
+                    newCode.insert(0, "0");
+                }
+                sampleScan.setBillNO(now + newCode.toString());
+            } else {
+                //若不相同则将当前日期拼接上0001
+                String newCode = now + "0001";
+                sampleScan.setBillNO(newCode);
+            }
+        } else {
+            String now = currentYear + currentMonthStr + dayStr;
+            //若不相同则将当前日期拼接上0001
+            String newCode = now + "0001";
+            sampleScan.setBillNO(newCode);
+        }
+
+
+        //设置其他属性
+        sampleScan.setBillDate(new Date());
+        sampleScan.setCreateTime(new Date());
+        String loginId = StpUtil.getLoginIdAsString();
+        sampleScan.setEditTime(new Date());
+        sampleScan.setEditUser(loginId);
+
+        //图片列表
+        List<MultipartFile> imgList = new ArrayList<>();
+        //图片分类
+        ArrayList<MultipartFile> mainImgList = new ArrayList<>();
+        HashMap<String, ArrayList<MultipartFile>> detailsImgMapList = new HashMap<>();
+        // 使用 Iterator 遍历文件参数
+        Iterator<String> fileNames = mulReq.getFileNames();
+        while (fileNames.hasNext()) {
+            String paramName = fileNames.next();
+            //name是public开头的为单据头所属图片
+            if (paramName.startsWith("public")) {
+                mainImgList.add(mulReq.getFile(paramName));
+                imgList.add(mulReq.getFile(paramName));
+            } else if (paramName.startsWith("detail")) {
+                //name是detail开头的为单据详情所属图片
+                String substring = paramName.substring(7, 9);
+                if (!detailsImgMapList.containsKey(substring)) {
+                    detailsImgMapList.put(substring, new ArrayList<>());
+                }
+                detailsImgMapList.get(substring).add(mulReq.getFile(paramName));
+                imgList.add(mulReq.getFile(paramName));
+            }
+        }
+
+        //将单据头的图片链接拼接起来
+        StringBuilder mainFileList = new StringBuilder();
+        if (mainImgList.size() > 0){
+            for (int i = 0; i < mainImgList.size(); i++) {
+                String originalFilename = mainImgList.get(i).getOriginalFilename();
+                if (i == mainImgList.size() - 1){
+                    mainFileList.append("https://xyxt.lttc.cn/samplescan/api/getimg/").append(currentYear).append("/").append(currentMonthStr).append("/").append(originalFilename);
+                } else {
+                    mainFileList.append("https://xyxt.lttc.cn/samplescan/api/getimg/").append(currentYear).append("/").append(currentMonthStr).append("/").append(originalFilename).append(";");
+                }
+            }
+            sampleScan.setFileSavePath(mainFileList.toString());
+        }
+        sampleScan.setFileSavePath(mainFileList.toString());
+
+        //循环处理单据体
+        if (sampleScanDetails!= null && sampleScanDetails.size() > 0){
+            sampleScanDetails.forEach(sampleScanDetail -> {
+                sampleScanDetail.setUuid(UUID.randomUUID().toString());
+                sampleScanDetail.setBillNO(sampleScan.getBillNO());
+                //文件名列表
+                ArrayList<MultipartFile> multipartFiles = detailsImgMapList.get(sampleScanDetail.getId());
+                StringBuilder detailFileList = new StringBuilder();
+                if (multipartFiles != null && multipartFiles.size() > 0){
+                    for (int i = 0; i < multipartFiles.size(); i++) {
+                        String originalFilename = multipartFiles.get(i).getOriginalFilename();
+                        if (i == multipartFiles.size() - 1){
+                            detailFileList.append("https://xyxt.lttc.cn/samplescan/api/getimg/").append(currentYear).append("/").append(currentMonthStr).append("/").append(originalFilename);
+                        } else {
+                            detailFileList.append("https://xyxt.lttc.cn/samplescan/api/getimg/").append(currentYear).append("/").append(currentMonthStr).append("/").append(originalFilename).append(";");
+                        }
+                    }
+                    sampleScanDetail.setFileSavePath(detailFileList.toString());
+                }
+                //图片路径
+                sampleScanDetail.setFileSavePath(detailFileList.toString());
+                //创建时间
+                sampleScanDetail.setCreateTime(new Date());
+            });
+        }
+        //调用保存方法
+        saveFileAndData(sampleScan, sampleScanDetails, currentYear, currentMonthStr, imgList);
+
+        return sampleScan.getUid();
+    }
+
+
+    List<SampleScanFile> saveFile(int currentYearInt, String currentMonthStr, List<MultipartFile> resultList) {
+        // 指定目标目录
+//        String uploadDir = System.getProperty("user.dir") + "/uploads/" + currentYear + "/" + currentMonth + "/";
+        //相对路径
+        String relativePath = currentYearInt + "/" + currentMonthStr + "/";
+        //绝对路径
+        String ap = uploadDir + "/" + relativePath;
+        // 确保目录存在,如果不存在则创建
+        File directory = new File(ap);
+        if (!directory.exists()) {
+            directory.mkdirs();
+        }
+        ArrayList<SampleScanFile> sampleScanFiles = new ArrayList<>();
+        String filePath = null;
+        for (MultipartFile multipartFile : resultList) {
+            // 获取文件名
+            String fileName = multipartFile.getOriginalFilename();
+
+            //获取扩展名
+            int dotIndex = fileName.lastIndexOf('.');
+            String expandedName = (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
+            //构造sampleScanFile对象
+            SampleScanFile sampleScanFile = new SampleScanFile();
+            sampleScanFile.setFileName(fileName);
+            sampleScanFile.setFileType(expandedName);
+            sampleScanFile.setFileSavePath(currentYearInt + "\\" + currentMonthStr + "\\" + fileName);
+            sampleScanFile.setUuid(UUID.randomUUID().toString());
+            sampleScanFile.setCreateTime(new Date());
+            sampleScanFile.setUploadTime(new Date());
+            String loginId = StpUtil.getLoginIdAsString();
+            sampleScanFile.setUploadUser(loginId);
+
+            sampleScanFiles.add(sampleScanFile);
+
+            // 文件保存路径
+            filePath = ap + fileName;
+            try {
+                // 使用 FileCopyUtils 工具保存文件
+                FileCopyUtils.copy(multipartFile.getBytes(), new File(filePath));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return sampleScanFiles;
+    }
+
+    public void saveFileAndData(SampleScan sampleScan, List<SampleScanDetail> sampleScanDetails, int currentYearInt, String currentMonthStr, List<MultipartFile> resultList) {
+
+        if (resultList!= null && resultList.size() > 0) {
+            List<SampleScanFile> sampleScanFiles = saveFile(currentYearInt, currentMonthStr, resultList);
+            if (sampleScanFiles!=null && sampleScanFiles.size() > 0) {
+                sampleScanMapper.saveImgData(sampleScanFiles);
+            }
+        }
+        //储存到数据库
+        sampleScanMapper.addMainData(sampleScan);
+
+        if (sampleScanDetails !=null && sampleScanDetails.size() > 0) {
+            sampleScanMapper.addDetailData(sampleScanDetails);
+        }
+    }
+
+    @Override
+    public ResponseEntity<byte[]> getImgService(String year, String month, String filename) {
+        String filePath = uploadDir + "/" + year + "/" + month + "/" + filename;
+
+        InputStream inputStream = null;
+        try {
+            inputStream = HttpUtils.getLocalhostInputStream(filePath);
+        } catch (FileNotFoundException e) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        }
+
+        //将输入流转为byte[]
+        byte[] bytesByStream = getBytesByStream(inputStream);
+        final HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.IMAGE_PNG);
+
+        return new ResponseEntity<>(bytesByStream, headers, HttpStatus.OK);
+    }
+
+    public byte[] getBytesByStream(InputStream inputStream) {
+        byte[] bytes = new byte[1024];
+
+        int b;
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        try {
+            while ((b = inputStream.read(bytes)) != -1) {
+
+                byteArrayOutputStream.write(bytes, 0, b);
+            }
+            return byteArrayOutputStream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 81 - 0
src/main/java/cn/lttc/modules/sysuser/controller/SysUser.java

@@ -0,0 +1,81 @@
+package cn.lttc.modules.sysuser.controller;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import cn.lttc.modules.sysuser.entity.User;
+import cn.lttc.modules.sysuser.service.SysUserService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Scanner;
+
+@RestController
+@RequestMapping("/samplescan/user")
+public class SysUser {
+
+    @Resource
+    SysUserService sysUserService;
+
+    @PostMapping("/login")
+    public SaResult doLogin(@RequestBody User loginUser){
+
+        if (loginUser.getUsername().isBlank() || loginUser.getPassword().isBlank()){
+            return SaResult.error("用户名或密码为空");
+        }
+        User userById = sysUserService.getUserByUsername(loginUser.getUsername());
+        if (userById == null || !userById.getPassword().equals(loginUser.getPassword())){
+            return SaResult.error("用户名或密码错误");
+        }
+
+        StpUtil.login(loginUser.getUsername());
+        SaSession tokenSession = StpUtil.getTokenSession();
+        return new SaResult(200, "ok", tokenSession.getToken());
+
+//        String userJson = loadResource("/user.json");
+//        List<User> list = JSON.parseObject(userJson, new TypeReference<>() {});
+//
+//        for (User user : list) {
+//            if(loginUser.getUsername().equals(user.getUsername())){
+//                if (!loginUser.getPassword().equals(user.getPassword())){
+//                    return SaResult.error("登录失败");
+//                } else {
+//
+//                }
+//            }
+//        }
+//        return SaResult.error("用户名不存在");
+    }
+
+//    public static String loadResource(String resourcePath) throws IOException {
+//        try (InputStream inputStream = SysUser.class.getResourceAsStream(resourcePath); Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8)) {
+//            StringBuilder content = new StringBuilder();
+//            while (scanner.hasNextLine()) {
+//                content.append(scanner.nextLine());
+//            }
+//            return content.toString();
+//        }
+//    }
+
+    @PostMapping("/logout")
+    public SaResult logout() {
+        StpUtil.logout();
+        return SaResult.ok();
+    }
+
+    @PostMapping("/adduser")
+    public SaResult addUser(@RequestBody User user){
+        User userById = sysUserService.getUserByUsername(user.getUsername());
+        if (userById!= null){
+            return SaResult.error("用户名已存在");
+        }
+        SaResult addResult = sysUserService.add(user);
+        return addResult;
+    }
+}

+ 17 - 0
src/main/java/cn/lttc/modules/sysuser/entity/User.java

@@ -0,0 +1,17 @@
+package cn.lttc.modules.sysuser.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+@Data
+public class User {
+
+    @TableField(value = "id")
+    private String id;
+
+    @TableField(value = "username")
+    private String username;
+
+    @TableField(value = "password")
+    private String password;
+}

+ 12 - 0
src/main/java/cn/lttc/modules/sysuser/entity/UserDto.java

@@ -0,0 +1,12 @@
+package cn.lttc.modules.sysuser.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UserDto {
+
+    private List<User> userList;
+
+}

+ 12 - 0
src/main/java/cn/lttc/modules/sysuser/mapper/SysUserMapper.java

@@ -0,0 +1,12 @@
+package cn.lttc.modules.sysuser.mapper;
+
+import cn.lttc.modules.sysuser.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface SysUserMapper {
+    void addUser(User user);
+
+    User getUserByUserName(@Param("username")String username);
+}

+ 28 - 0
src/main/java/cn/lttc/modules/sysuser/mapper/xml/SampleScanMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.lttc.modules.sysuser.mapper.SysUserMapper">
+
+
+    <insert id="addUser" parameterType="cn.lttc.modules.sysuser.entity.User">
+        insert into lttc_sample_user_new
+        (id,
+         username,
+         password)
+        values
+        (#{id},
+         #{username},
+         #{password})
+    </insert>
+
+    <select id="getUserByUserName" parameterType="string" resultType="cn.lttc.modules.sysuser.entity.User">
+    select
+        username,
+        password
+    from
+        lttc_sample_user_new
+    where
+        username = #{username}
+    </select>
+
+
+</mapper>

+ 11 - 0
src/main/java/cn/lttc/modules/sysuser/service/SysUserService.java

@@ -0,0 +1,11 @@
+package cn.lttc.modules.sysuser.service;
+
+import cn.dev33.satoken.util.SaResult;
+import cn.lttc.modules.sysuser.entity.User;
+
+public interface SysUserService {
+
+    SaResult add(User user);
+
+    User getUserByUsername(String id);
+}

+ 32 - 0
src/main/java/cn/lttc/modules/sysuser/service/impl/SysSysUserServiceImpl.java

@@ -0,0 +1,32 @@
+package cn.lttc.modules.sysuser.service.impl;
+
+import cn.dev33.satoken.util.SaResult;
+import cn.lttc.modules.sysuser.entity.User;
+import cn.lttc.modules.sysuser.mapper.SysUserMapper;
+import cn.lttc.modules.sysuser.service.SysUserService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.swing.*;
+import java.rmi.server.UID;
+import java.util.UUID;
+
+@Service
+public class SysSysUserServiceImpl implements SysUserService {
+
+    @Resource
+    SysUserMapper sysUserMapper;
+
+    @Override
+    public SaResult add(User user) {
+        user.setId(UUID.randomUUID().toString());
+        sysUserMapper.addUser(user);
+        return SaResult.ok("新增成功");
+    }
+
+    @Override
+    public User getUserByUsername(String username) {
+        User userByUserName = sysUserMapper.getUserByUserName(username);
+        return userByUserName;
+    }
+}

+ 51 - 0
src/main/java/cn/lttc/modules/utils/HttpUtils.java

@@ -0,0 +1,51 @@
+package cn.lttc.modules.utils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.servlet.http.HttpServletResponse;
+
+public class HttpUtils {
+
+    public static InputStream getInputStream(String urlPath) {
+        InputStream inputStream = null;
+        HttpURLConnection httpURLConnection = null;
+        try {
+            URL url = new URL(urlPath);
+            httpURLConnection = (HttpURLConnection) url.openConnection();
+            // 设置网络连接超时时间
+            httpURLConnection.setConnectTimeout(3000);
+            // 设置应用程序要从网络连接读取数据
+            httpURLConnection.setDoInput(true);
+            httpURLConnection.setRequestMethod("GET");
+            int responseCode = httpURLConnection.getResponseCode();
+            System.out.println("responseCode is:" + responseCode);
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                // 从服务器返回一个输入流
+                inputStream = httpURLConnection.getInputStream();
+            } else {
+                inputStream = httpURLConnection.getErrorStream();
+            }
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return inputStream;
+    }
+
+    public static InputStream getLocalhostInputStream(String urlPath) throws FileNotFoundException {
+        InputStream inputStream = null;
+        File file = new File(urlPath);
+
+            inputStream = new FileInputStream(file);
+
+
+        return inputStream;
+    }
+
+}
+
+

+ 41 - 0
src/main/resources/application.yml

@@ -0,0 +1,41 @@
+server:
+  port: 8028 #端口
+
+spring:
+  # 数据源配置
+  datasource:
+    url: jdbc:sqlserver://10.200.2.165:1433;databaseName=LTTCXYXT;useSSL=false;trustServerCertificate=true;
+    username: xyuser
+    password: Luth@ixySystem.
+    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
+  # 文件上传配置
+  servlet:
+    multipart:
+      enabled: true
+      max-file-size: 100MB
+      max-request-size: 1000MB
+
+# MyBatis-Plus 配置
+mybatis-plus:
+  mapper-locations: classpath*:cn/lttc/modules/**/mapper/**/*.xml
+  type-aliases-package: cn.lttc.modules
+
+# sa-token 配置
+sa-token:
+  token-name: satoken
+  timeout: -1 # -1为永不过期
+  active-timeout: -1 # -1为永不过期
+  is-log: true
+
+# 文件保存路径
+file:
+  upload-path: D:/WWWROOT/LTTC-sample/uploads
+#  upload-path: D:\JavaProject\lttc-sample-scan\uploads
+
+logging:
+  # 日志文件保存路径
+  file:
+    path: D:\WWWROOT\LTTC-sample\log
+  # 日志级别
+  level:
+    root: info