Ver Fonte

第一次提交

赵冬冬 há 3 anos atrás
commit
1830c1cb09

BIN
excel/包装机数据测试表.xlsx


+ 101 - 0
pom.xml

@@ -0,0 +1,101 @@
+<?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>
+
+    <groupId>com.hw</groupId>
+    <artifactId>ycpharmacy-packer-service</artifactId>
+    <version>1.0.0</version>
+
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.6.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <name>ycpharmacy-packer-service</name>
+
+
+    <properties>
+
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>2.2.11</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.78</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+</project>

+ 1 - 0
rdme.md

@@ -0,0 +1 @@
+## 远程制药excel读取器 定时获取包装机数据

+ 19 - 0
src/main/java/com/hw/admin/PackerServiceApplication.java

@@ -0,0 +1,19 @@
+package com.hw.admin;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 系统模块
+ *
+ * @author Administrator
+ */
+
+@SpringBootApplication
+@MapperScan("com.hw.admin.**.mapper")
+public class PackerServiceApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(PackerServiceApplication.class, args);
+    }
+}

+ 76 - 0
src/main/java/com/hw/admin/model/controller/WorkPackerController.java

@@ -0,0 +1,76 @@
+package com.hw.admin.model.controller;
+
+
+import com.alibaba.excel.EasyExcel;
+import com.hw.admin.model.domain.AjaxResultVo;
+import com.hw.admin.model.domain.WorkPacker;
+import com.hw.admin.model.domain.WorkPackerExcel;
+import com.hw.admin.model.mapper.WorkPackerMapper;
+import com.hw.admin.model.service.WorkPackerService;
+import com.hw.admin.system.listener.WorkPackerListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+@RestController
+@RequestMapping("/workPacker")
+public class WorkPackerController {
+
+    @Autowired
+    private WorkPackerService workPackerService;
+
+    @Autowired
+    private WorkPackerMapper workPackerMapper;
+
+    @PostMapping
+    @ResponseBody
+    public AjaxResultVo add(@RequestBody WorkPacker workPacker) {
+        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
+        // 写法3:
+        String fileName = "D:\\project\\delivery_project\\远程制药\\后台\\ycpharmacy_excel_service\\excel\\包装机数据测试表.xlsx";
+        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
+        EasyExcel.read(fileName, WorkPackerExcel.class, new WorkPackerListener(workPackerMapper)).sheet().doRead();
+        //workPackerService.add(workPacker);
+        return AjaxResultVo.success();
+    }
+
+
+    @GetMapping("/list")
+    @ResponseBody
+    public AjaxResultVo list(WorkPacker workPacker) {
+        List<WorkPacker> list = workPackerService.list(workPacker);
+        return AjaxResultVo.success(list);
+    }
+
+    @GetMapping("/{id}")
+    @ResponseBody
+    public AjaxResultVo get(@PathVariable("id") Long id) {
+        return AjaxResultVo.success(workPackerService.get(id));
+    }
+
+    @PutMapping
+    @ResponseBody
+    public AjaxResultVo update(@RequestBody WorkPacker workPacker) {
+        return AjaxResultVo.success(workPackerService.update(workPacker));
+    }
+
+    /**
+     * 批量删除请假业务
+     */
+    @DeleteMapping("/{id}")
+    @ResponseBody
+    public AjaxResultVo delete(@PathVariable("id") Long id) {
+        return AjaxResultVo.success(workPackerService.delete(id));
+    }
+
+    /**
+     * 批量删除请假业务
+     */
+    @DeleteMapping
+    @ResponseBody
+    public AjaxResultVo deleteByIds(@RequestBody List<Long> ids) {
+        return AjaxResultVo.success(workPackerService.deleteByIds(ids));
+    }
+}

+ 239 - 0
src/main/java/com/hw/admin/model/domain/AjaxResultVo.java

@@ -0,0 +1,239 @@
+package com.hw.admin.model.domain;
+
+
+
+public class AjaxResultVo<T> {
+    /**
+     * 状态码
+     */
+    private int code;
+    /**
+     * 消息
+     */
+
+    private String msg;
+
+    /**
+     * 数据对象
+     */
+    private T data;
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResultVo 对象,使其表示一个空消息。
+     */
+    public AjaxResultVo() {
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResultVo 对象
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     */
+    public AjaxResultVo(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResultVo 对象
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     * @param data 数据对象
+     */
+    public AjaxResultVo(int code, String msg, T data) {
+        this.code = code;
+        this.msg = msg;
+        if (null != data) {
+            this.data = data;
+        }
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @return 成功消息
+     */
+    public static AjaxResultVo success() {
+        return AjaxResultVo.success("操作成功");
+    }
+
+    /**
+     * 返回成功数据
+     *
+     * @return 成功消息
+     */
+    public static <T> AjaxResultVo success(T data) {
+        return AjaxResultVo.success("操作成功", data);
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @param msg 返回内容
+     * @return 成功消息
+     */
+    public static AjaxResultVo success(String msg) {
+        return AjaxResultVo.success(msg, null);
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @param msg  返回内容
+     * @param data 数据对象
+     * @return 成功消息
+     */
+    public static <T> AjaxResultVo success(String msg, T data) {
+
+        return new AjaxResultVo(HttpStatus.SUCCESS, msg, data);
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @return
+     */
+    public static AjaxResultVo error() {
+        return AjaxResultVo.error("操作失败");
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param msg 返回内容
+     * @return 警告消息
+     */
+    public static AjaxResultVo error(String msg) {
+        return AjaxResultVo.error(msg, null);
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param msg  返回内容
+     * @param data 数据对象
+     * @return 警告消息
+     */
+    public static AjaxResultVo error(String msg, Object data) {
+        return new AjaxResultVo(HttpStatus.ERROR, msg, data);
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     * @return 警告消息
+     */
+    public static AjaxResultVo error(int code, String msg) {
+        return new AjaxResultVo(code, msg, null);
+    }
+}
+
+class HttpStatus {
+    /**
+     * 操作成功
+     */
+    public static final int SUCCESS = 200;
+
+    /**
+     * 对象创建成功
+     */
+    public static final int CREATED = 201;
+
+    /**
+     * 请求已经被接受
+     */
+    public static final int ACCEPTED = 202;
+
+    /**
+     * 操作已经执行成功,但是没有返回数据
+     */
+    public static final int NO_CONTENT = 204;
+
+    /**
+     * 资源已被移除
+     */
+    public static final int MOVED_PERM = 301;
+
+    /**
+     * 重定向
+     */
+    public static final int SEE_OTHER = 303;
+
+    /**
+     * 资源没有被修改
+     */
+    public static final int NOT_MODIFIED = 304;
+
+    /**
+     * 参数列表错误(缺少,格式不匹配)
+     */
+    public static final int BAD_REQUEST = 400;
+
+    /**
+     * 未授权
+     */
+    public static final int UNAUTHORIZED = 401;
+
+    /**
+     * 访问受限,授权过期
+     */
+    public static final int FORBIDDEN = 403;
+
+    /**
+     * 资源,服务未找到
+     */
+    public static final int NOT_FOUND = 404;
+
+    /**
+     * 不允许的http方法
+     */
+    public static final int BAD_METHOD = 405;
+
+    /**
+     * 资源冲突,或者资源被锁
+     */
+    public static final int CONFLICT = 409;
+
+    /**
+     * 不支持的数据,媒体类型
+     */
+    public static final int UNSUPPORTED_TYPE = 415;
+
+    /**
+     * 系统内部错误
+     */
+    public static final int ERROR = 500;
+
+    /**
+     * 接口未实现
+     */
+    public static final int NOT_IMPLEMENTED = 501;
+}

+ 290 - 0
src/main/java/com/hw/admin/model/domain/WorkPacker.java

@@ -0,0 +1,290 @@
+package com.hw.admin.model.domain;
+
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@ToString(callSuper = true)
+@Accessors(chain = true)
+@TableName("work_packer")
+public class WorkPacker {
+    /**
+     * id
+     * 列名:id 类型:BIGINT(19) 允许空:false 缺省值:null
+     */
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * 药品名称
+     * 列名:drug_name 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String drugName;
+
+    /**
+     * 条码
+     * 列名:bar_code 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String barCode;
+
+    /**
+     * 包装规格
+     * 列名:pack_spec 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String packSpec;
+
+    /**
+     * 批次
+     * 列名:batch 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String batch;
+
+    /**
+     * 生产日期
+     * 列名:manu_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    private Date manuTime;
+
+    /**
+     * 药品数量
+     * 列名:qua_drugs 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String quaDrugs;
+
+    /**
+     * 药品规格
+     * 列名:drug_spec 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String drugSpec;
+
+    /**
+     * 包装时间
+     * 列名:pack_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    private Date packTime;
+
+    /**
+     * 操作人
+     * 列名:operator 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    private String operator;
+
+    /**
+     * 插入时间
+     */
+    private String insertTime;
+
+    /**
+     * 备注
+     * 列名:remark 类型:VARCHAR(500) 允许空:true 缺省值:null
+     */
+    private String remark;
+
+    /**
+     * 创建者
+     * 列名:create_by 类型:VARCHAR(64) 允许空:true 缺省值:null
+     */
+    private String createBy;
+
+    /**
+     * 创建者id
+     * 列名:create_user_id 类型:BIGINT(19) 允许空:true 缺省值:null
+     */
+    private Long createUserId;
+
+    /**
+     * 创建时间
+     * 列名:create_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    private Date createTime;
+
+    /**
+     * 更新者
+     * 列名:update_by 类型:VARCHAR(64) 允许空:true 缺省值:null
+     */
+    private String updateBy;
+
+    /**
+     * 更新者id
+     * 列名:update_user_id 类型:BIGINT(19) 允许空:true 缺省值:null
+     */
+    private Long updateUserId;
+
+    /**
+     * 更新时间
+     * 列名:update_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    private Date updateTime;
+
+    /**
+     * 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
+     * 列名:data_scope 类型:CHAR(1) 允许空:true 缺省值:1
+     */
+    private String dataScope;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     * 列名:del_flag 类型:CHAR(1) 允许空:true 缺省值:0
+     */
+    private String delFlag;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getDrugName() {
+        return drugName;
+    }
+
+    public void setDrugName(String drugName) {
+        this.drugName = drugName == null ? null : drugName.trim();
+    }
+
+    public String getBarCode() {
+        return barCode;
+    }
+
+    public void setBarCode(String barCode) {
+        this.barCode = barCode == null ? null : barCode.trim();
+    }
+
+    public String getPackSpec() {
+        return packSpec;
+    }
+
+    public void setPackSpec(String packSpec) {
+        this.packSpec = packSpec == null ? null : packSpec.trim();
+    }
+
+    public String getBatch() {
+        return batch;
+    }
+
+    public void setBatch(String batch) {
+        this.batch = batch == null ? null : batch.trim();
+    }
+
+    public Date getManuTime() {
+        return manuTime;
+    }
+
+    public void setManuTime(Date manuTime) {
+        this.manuTime = manuTime;
+    }
+
+    public String getQuaDrugs() {
+        return quaDrugs;
+    }
+
+    public void setQuaDrugs(String quaDrugs) {
+        this.quaDrugs = quaDrugs == null ? null : quaDrugs.trim();
+    }
+
+    public String getDrugSpec() {
+        return drugSpec;
+    }
+
+    public void setDrugSpec(String drugSpec) {
+        this.drugSpec = drugSpec == null ? null : drugSpec.trim();
+    }
+
+    public Date getPackTime() {
+        return packTime;
+    }
+
+    public void setPackTime(Date packTime) {
+        this.packTime = packTime;
+    }
+
+    public String getOperator() {
+        return operator;
+    }
+
+    public void setOperator(String operator) {
+        this.operator = operator == null ? null : operator.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getCreateBy() {
+        return createBy;
+    }
+
+    public void setCreateBy(String createBy) {
+        this.createBy = createBy == null ? null : createBy.trim();
+    }
+
+    public Long getCreateUserId() {
+        return createUserId;
+    }
+
+    public void setCreateUserId(Long createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getUpdateBy() {
+        return updateBy;
+    }
+
+    public void setUpdateBy(String updateBy) {
+        this.updateBy = updateBy == null ? null : updateBy.trim();
+    }
+
+    public Long getUpdateUserId() {
+        return updateUserId;
+    }
+
+    public void setUpdateUserId(Long updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public String getDataScope() {
+        return dataScope;
+    }
+
+    public void setDataScope(String dataScope) {
+        this.dataScope = dataScope == null ? null : dataScope.trim();
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag == null ? null : delFlag.trim();
+    }
+}

+ 76 - 0
src/main/java/com/hw/admin/model/domain/WorkPackerExcel.java

@@ -0,0 +1,76 @@
+package com.hw.admin.model.domain;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class WorkPackerExcel {
+
+
+    /**
+     * 药品名称
+     * 列名:drug_name 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("药品名称")
+    private String drugName;
+
+    /**
+     * 条码
+     * 列名:bar_code 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("条码")
+    private String barCode;
+
+    /**
+     * 包装规格
+     * 列名:pack_spec 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("包装规格")
+    private String packSpec;
+
+    /**
+     * 批次
+     * 列名:batch 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("批次")
+    private String batch;
+
+    /**
+     * 生产日期
+     * 列名:manu_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("生产日期")
+    private String manuTime;
+
+    /**
+     * 药品数量
+     * 列名:qua_drugs 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("药品数量")
+    private String quaDrugs;
+
+    /**
+     * 药品规格
+     * 列名:drug_spec 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("药品规格")
+    private String drugSpec;
+
+    /**
+     * 包装时间
+     * 列名:pack_time 类型:TIMESTAMP(19) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("包装时间")
+    private String packTime;
+
+    /**
+     * 操作人
+     * 列名:operator 类型:VARCHAR(100) 允许空:true 缺省值:null
+     */
+    @ExcelProperty("操作人")
+    private String operator;
+}

+ 13 - 0
src/main/java/com/hw/admin/model/mapper/WorkPackerMapper.java

@@ -0,0 +1,13 @@
+package com.hw.admin.model.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.hw.admin.model.domain.WorkPacker;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface WorkPackerMapper extends BaseMapper<WorkPacker> {
+
+    int inserList(@Param("data") List<WorkPacker> workPacker);
+}

+ 23 - 0
src/main/java/com/hw/admin/model/service/WorkPackerService.java

@@ -0,0 +1,23 @@
+package com.hw.admin.model.service;
+
+import com.hw.admin.model.domain.WorkPacker;
+
+import java.util.List;
+
+public interface WorkPackerService {
+
+    public int add(WorkPacker workPacker);
+
+    public List<WorkPacker> list(WorkPacker workPacker);
+
+    public WorkPacker get(Long id);
+
+    public int update(WorkPacker workPacker);
+
+    public int delete(Long id);
+
+    public int deleteByIds(List<Long> ids);
+
+    public int inserList(List<WorkPacker> workPacker);
+
+}

+ 90 - 0
src/main/java/com/hw/admin/model/service/impl/WorkPackerServiceImpl.java

@@ -0,0 +1,90 @@
+package com.hw.admin.model.service.impl;
+
+import com.alibaba.excel.EasyExcel;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.hw.admin.model.domain.WorkPacker;
+import com.hw.admin.model.mapper.WorkPackerMapper;
+import com.hw.admin.model.service.WorkPackerService;
+import com.hw.admin.system.utils.Sequence;
+import javafx.scene.input.InputMethodTextRun;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class WorkPackerServiceImpl implements WorkPackerService {
+
+    @Autowired
+    private WorkPackerMapper workPackerMapper;
+
+    @Override
+    public int add(WorkPacker workPacker) {
+
+        List<WorkPacker> list = new ArrayList();
+        Sequence sequence = new Sequence(2, 3);
+        WorkPacker workPacker1=new WorkPacker();
+        WorkPacker workPacker2=new WorkPacker();
+        BeanUtils.copyProperties(workPacker,workPacker1);
+        BeanUtils.copyProperties(workPacker,workPacker2);
+        workPacker1.setId(sequence.nextId());
+        list.add(workPacker1);
+        workPacker2.setId(sequence.nextId());
+        list.add(workPacker2);
+        return workPackerMapper.inserList(list);
+    }
+
+    @Override
+    public List<WorkPacker> list(WorkPacker workPacker) {
+        QueryWrapper<WorkPacker> queryWrapper = new QueryWrapper<WorkPacker>();
+        queryWrapper.eq("del_flag", 0);
+        queryWrapper.orderByDesc("create_time");
+        return workPackerMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public WorkPacker get(Long id) {
+        checkData(id);
+        return workPackerMapper.selectById(id);
+    }
+
+    @Override
+    public int update(WorkPacker workPacker) {
+        checkData(workPacker.getId());
+        return workPackerMapper.updateById(workPacker);
+    }
+
+    @Override
+    public int delete(Long id) {
+        checkData(id);
+        WorkPacker workPacker = new WorkPacker();
+        workPacker.setId(id);
+        workPacker.setDelFlag("1");
+        return workPackerMapper.updateById(workPacker);
+    }
+
+    @Override
+    public int deleteByIds(List<Long> ids) {
+        return workPackerMapper.deleteBatchIds(ids);
+    }
+
+    @Override
+    public int inserList(List<WorkPacker> workPacker) {
+
+        return workPackerMapper.inserList(workPacker);
+    }
+
+    private WorkPacker checkData(Long id) {
+        WorkPacker workPacker = workPackerMapper.selectById(id);
+        if (StringUtils.isEmpty(workPacker)) {
+            throw new RuntimeException("数据不存在");
+        }
+        if ("1".equals(workPacker.getDelFlag())) {
+            throw new RuntimeException("数据不存在");
+        }
+        return workPacker;
+    }
+}

+ 33 - 0
src/main/java/com/hw/admin/system/config/DefaultIdentifierGenerator.java

@@ -0,0 +1,33 @@
+package com.hw.admin.system.config;
+
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.hw.admin.system.utils.Sequence;
+import org.springframework.stereotype.Component;
+
+import java.net.InetAddress;
+@Component
+public class DefaultIdentifierGenerator implements IdentifierGenerator {
+    private final Sequence sequence;
+
+    public DefaultIdentifierGenerator() {
+        this.sequence = new Sequence(null);
+    }
+
+    public DefaultIdentifierGenerator(InetAddress inetAddress) {
+        this.sequence = new Sequence(inetAddress);
+    }
+
+    public DefaultIdentifierGenerator(long workerId, long dataCenterId) {
+        this.sequence = new Sequence(workerId, dataCenterId);
+    }
+
+    public DefaultIdentifierGenerator(Sequence sequence) {
+        this.sequence = sequence;
+    }
+
+    // 生成主键
+    @Override
+    public Long nextId(Object entity) {
+        return sequence.nextId();
+    }
+}

+ 86 - 0
src/main/java/com/hw/admin/system/listener/WorkPackerListener.java

@@ -0,0 +1,86 @@
+package com.hw.admin.system.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.fastjson.JSON;
+import com.hw.admin.model.domain.WorkPacker;
+import com.hw.admin.model.domain.WorkPackerExcel;
+import com.hw.admin.model.mapper.WorkPackerMapper;
+import com.hw.admin.system.utils.DateExUtils;
+import com.hw.admin.system.utils.Sequence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
+public class WorkPackerListener extends AnalysisEventListener<WorkPackerExcel> {
+    private static final Logger LOGGER = LoggerFactory.getLogger(WorkPackerListener.class);
+    /**
+     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
+     */
+    private static final int BATCH_COUNT = 3000;
+    /**
+     * 缓存的数据
+     */
+    private List<WorkPacker> list = new ArrayList<>(BATCH_COUNT);
+    /**
+     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
+     */
+    private WorkPackerMapper workPackerMapper;
+
+    /**
+     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
+     */
+    public WorkPackerListener(WorkPackerMapper workPackerMapper) {
+        this.workPackerMapper = workPackerMapper;
+    }
+
+    /**
+     * 这个每一条数据解析都会来调用
+     *
+     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
+     * @param context
+     */
+    Sequence sequence = new Sequence(2, 3);
+
+    @Override
+    public void invoke(WorkPackerExcel data, AnalysisContext context) {
+        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
+        WorkPacker workPacker = new WorkPacker();
+        BeanUtils.copyProperties(data, workPacker);
+        workPacker.setId(sequence.nextId());
+        String s = DateExUtils.commonDatePathStr();
+        workPacker.setInsertTime(s);
+        list.add(workPacker);
+        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if (list.size() >= BATCH_COUNT) {
+            saveData();
+            // 存储完成清理 list
+            list = new ArrayList<>(BATCH_COUNT);
+        }
+    }
+
+    /**
+     * 所有数据解析完成了 都会来调用
+     *
+     * @param context
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
+        saveData();
+        LOGGER.info("所有数据解析完成!");
+    }
+
+    /**
+     * 加上存储数据库
+     */
+    private void saveData() {
+        LOGGER.info("{}条数据,开始存储数据库!", list.size());
+        workPackerMapper.inserList(list);
+        LOGGER.info("存储数据库成功!");
+    }
+}

+ 44 - 0
src/main/java/com/hw/admin/system/utils/DateExUtils.java

@@ -0,0 +1,44 @@
+package com.hw.admin.system.utils;
+
+import java.util.Calendar;
+
+public class DateExUtils {
+    /**
+     * 获取时间路径按yyyy/MM/hh
+     *
+     * @return
+     */
+    public static String commonDatePath() {
+        //使用默认时区和语言环境获得一个日历。
+        Calendar rightNow = Calendar.getInstance();
+        //用Calendar的get(int field)方法返回给定日历字段的值。
+        //HOUR 用于 12 小时制时钟 (0 - 11),HOUR_OF_DAY 用于 24 小时制时钟
+        Integer year = rightNow.get(Calendar.YEAR);
+        //第一个月从0开始,所以得到月份+1
+        Integer month = rightNow.get(Calendar.MONTH) + 1;
+        Integer day = rightNow.get(Calendar.DAY_OF_MONTH);
+        String yyMMhh = "/" + year + "/" + month + "/" + day + "/";
+        return yyMMhh;
+    }
+
+    /**
+     * 获取时间路径按yyyy/MM/hh
+     *
+     * @return
+     */
+    public static String commonDatePathStr() {
+        StringBuffer stringBuffer = new StringBuffer();
+        //使用默认时区和语言环境获得一个日历。
+        Calendar rightNow = Calendar.getInstance();
+        //用Calendar的get(int field)方法返回给定日历字段的值。
+        //HOUR 用于 12 小时制时钟 (0 - 11),HOUR_OF_DAY 用于 24 小时制时钟
+        Integer year = rightNow.get(Calendar.YEAR);
+        //第一个月从0开始,所以得到月份+1
+        Integer month = rightNow.get(Calendar.MONTH) + 1;
+        Integer day = rightNow.get(Calendar.DAY_OF_MONTH);
+        String yyMMhh = stringBuffer.append(year).append(month).append(day).toString();
+        return yyMMhh;
+    }
+
+
+}

+ 193 - 0
src/main/java/com/hw/admin/system/utils/Sequence.java

@@ -0,0 +1,193 @@
+package com.hw.admin.system.utils;
+
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.SystemClock;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * 分布式高效有序 ID 生产黑科技(sequence)
+ *
+ * <p>优化开源项目:https://gitee.com/yu120/sequence</p>
+ *
+ * @author hubin
+ * @since 2016-08-18
+ */
+public class Sequence {
+
+    private static final Log logger = LogFactory.getLog(Sequence.class);
+    /**
+     * 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
+     */
+    private final long twepoch = 1288834974657L;
+    /**
+     * 机器标识位数
+     */
+    private final long workerIdBits = 5L;
+    private final long datacenterIdBits = 5L;
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+    /**
+     * 毫秒内自增位
+     */
+    private final long sequenceBits = 12L;
+    private final long workerIdShift = sequenceBits;
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+    /**
+     * 时间戳左移动位
+     */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    private final long workerId;
+
+    /**
+     * 数据标识 ID 部分
+     */
+    private final long datacenterId;
+    /**
+     * 并发控制
+     */
+    private long sequence = 0L;
+    /**
+     * 上次生产 ID 时间戳
+     */
+    private long lastTimestamp = -1L;
+    /**
+     * IP 地址
+     */
+    private InetAddress inetAddress;
+
+    public Sequence(InetAddress inetAddress) {
+        this.inetAddress = inetAddress;
+        this.datacenterId = getDatacenterId(maxDatacenterId);
+        this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
+    }
+
+    /**
+     * 有参构造器
+     *
+     * @param workerId     工作机器 ID
+     * @param datacenterId 序列号
+     */
+    public Sequence(long workerId, long datacenterId) {
+        Assert.isFalse(workerId > maxWorkerId || workerId < 0,
+                String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        Assert.isFalse(datacenterId > maxDatacenterId || datacenterId < 0,
+                String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+
+
+    /**
+     * 获取 maxWorkerId
+     */
+    protected long getMaxWorkerId(long datacenterId, long maxWorkerId) {
+        StringBuilder mpid = new StringBuilder();
+        mpid.append(datacenterId);
+        String name = ManagementFactory.getRuntimeMXBean().getName();
+        if (StringUtils.isNotBlank(name)) {
+            /*
+             * GET jvmPid
+             */
+            mpid.append(name.split(StringPool.AT)[0]);
+        }
+        /*
+         * MAC + PID 的 hashcode 获取16个低位
+         */
+        return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
+    }
+
+    /**
+     * 数据标识id部分
+     */
+    protected long getDatacenterId(long maxDatacenterId) {
+        long id = 0L;
+        try {
+            if (null == this.inetAddress) {
+                this.inetAddress = InetAddress.getLocalHost();
+            }
+            NetworkInterface network = NetworkInterface.getByInetAddress(this.inetAddress);
+            if (null == network) {
+                id = 1L;
+            } else {
+                byte[] mac = network.getHardwareAddress();
+                if (null != mac) {
+                    id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
+                    id = id % (maxDatacenterId + 1);
+                }
+            }
+        } catch (Exception e) {
+            logger.warn(" getDatacenterId: " + e.getMessage());
+        }
+        return id;
+    }
+
+    /**
+     * 获取下一个 ID
+     *
+     * @return 下一个 ID
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+        //闰秒
+        if (timestamp < lastTimestamp) {
+            long offset = lastTimestamp - timestamp;
+            if (offset <= 5) {
+                try {
+                    wait(offset << 1);
+                    timestamp = timeGen();
+                    if (timestamp < lastTimestamp) {
+                        throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", offset));
+                    }
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            } else {
+                throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", offset));
+            }
+        }
+
+        if (lastTimestamp == timestamp) {
+            // 相同毫秒内,序列号自增
+            sequence = (sequence + 1) & sequenceMask;
+            if (sequence == 0) {
+                // 同一毫秒的序列数已经达到最大
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        } else {
+            // 不同毫秒内,序列号置为 1 - 3 随机数
+            sequence = ThreadLocalRandom.current().nextLong(1, 3);
+        }
+
+        lastTimestamp = timestamp;
+
+        // 时间戳部分 | 数据中心部分 | 机器标识部分 | 序列号部分
+        return ((timestamp - twepoch) << timestampLeftShift)
+                | (datacenterId << datacenterIdShift)
+                | (workerId << workerIdShift)
+                | sequence;
+    }
+
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    protected long timeGen() {
+        return SystemClock.now();
+    }
+
+}

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

@@ -0,0 +1,39 @@
+server:
+  port: 8080
+mybatis-plus:
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+# MyBatis配置
+mybatis:
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath:mapper/**/*.xml
+  configuration:
+    map-underscore-to-camel-case: true
+    call-setters-on-nulls: false #返回null字段
+spring:
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://172.16.90.201:3306/ycpharmacy_db?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&tinyInt1isBit=false
+    username: root
+    password: 123456
+  druid:
+    initial-size: 5
+    min-idle: 5
+    maxActive: 20
+    maxWait: 60000
+    timeBetweenEvictionRunsMillis: 60000
+    minEvictableIdleTimeMillis: 300000
+    validationQuery: SELECT 1 FROM DUAL
+    testWhileIdle: true
+    testOnBorrow: false
+    testOnReturn: false
+    poolPreparedStatements: true
+    maxPoolPreparedStatementPerConnectionSize: 20
+    connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+    filters: stat,slf4j
+
+
+

+ 178 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/base.xml"/>
+    <jmxConfigurator/>
+    <contextName>car_pay_center</contextName>
+    <property name="LOG_PATH" value="./logs"/>
+    <!--设置系统日志目录-->
+    <property name="APPDIR" value="ycpharmacy-excel-service"/>
+
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex"
+                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx"
+                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!-- 日志记录器,日期滚动记录 -->
+    <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/${APPDIR}/log_error.log</file>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
+            <fileNamePattern>${LOG_PATH}/${APPDIR}/error/%d{yyyyMMdd}/%d{HH:mm:ss}.%i.log</fileNamePattern>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
+            命名日志文件,例如log-error-2013-12-21.0.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>2MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <!-- 追加方式记录日志 -->
+        <append>true</append>
+        <!-- 日志文件的格式 -->
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L [%thread] - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>error</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 日志记录器,日期滚动记录 -->
+    <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
+            <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/%d{yyyyMMdd}/%d{HH:mm:ss}.%i.log</fileNamePattern>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
+            命名日志文件,例如log-error-2013-12-21.0.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>2MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <!-- 追加方式记录日志 -->
+        <append>true</append>
+        <!-- 日志文件的格式 -->
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L [%thread] - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>warn</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 日志记录器,日期滚动记录 -->
+    <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/${APPDIR}/log_info.log</file>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+            而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
+            <fileNamePattern>${LOG_PATH}/${APPDIR}/info/%d{yyyyMMdd}/%d{HH:mm:ss}.%i.log</fileNamePattern>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始,
+            命名日志文件,例如log-error-2013-12-21.0.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>20MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <!-- 追加方式记录日志 -->
+        <append>true</append>
+        <!-- 日志文件的格式 -->
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger [%thread] - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>info</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <!--encoder 默认配置为PatternLayoutEncoder-->
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>debug</level>
+        </filter>
+    </appender>
+
+    <!--myibatis log configure-->
+    <logger name="com.apache.ibatis" level="TRACE"/>
+    <logger name="java.sql.Connection" level="DEBUG"/>
+    <logger name="java.sql.Statement" level="DEBUG"/>
+    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
+
+
+    <!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 -->
+    <!--
+      <springProfile name="dev">
+      </springProfile>
+      可以使用这个标签实现不同环境不同日志级别
+        <springProfile name="test">
+            <root level="INFO">
+                <appender-ref ref="FILE"/>
+                <appender-ref ref="STDOUT"/>
+            </root>
+        </springProfile>
+     -->
+
+    <!-- 异步输出 -->
+    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
+        <queueSize>256</queueSize>
+        <!-- 添加附加的appender,最多只能添加一个 -->
+        <appender-ref ref="FILEINFO"/>
+    </appender>
+
+
+    <!--
+    springProperty 可以读取配置文件中的属性 <file>logs/${logName}.log</file>    使用方法
+    <springProperty scope="context" name="logName"
+    source="spring.application.name" defaultValue="localhost"/>
+    -->
+
+    <springProfile name="dev">
+        <root level="INFO">
+            <appender-ref ref="FILEERROR" />
+            <appender-ref ref="FILEWARN" />
+            <appender-ref ref="ASYNC" />
+            <!-- 生产环境将请stdout,testfile去掉 -->
+            <!-- <appender-ref ref="STDOUT"/>-->
+        </root>
+    </springProfile>
+    <springProfile name="pro">
+        <root level="INFO">
+            <appender-ref ref="FILEERROR" />
+            <appender-ref ref="FILEWARN" />
+            <appender-ref ref="ASYNC" />
+            <!-- 生产环境将请stdout,testfile去掉 -->
+            <!-- <appender-ref ref="STDOUT"/>-->
+        </root>
+    </springProfile>
+</configuration>

+ 55 - 0
src/main/resources/mapper/WorkPackerMapper.xml

@@ -0,0 +1,55 @@
+<?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="com.hw.admin.model.mapper.WorkPackerMapper">
+
+    <insert id="inserList">
+        INSERT INTO work_packer (
+        id,
+        drug_name,
+        bar_code,
+        pack_spec,
+        batch,
+        manu_time,
+        qua_drugs,
+        drug_spec,
+        pack_time,
+        operator,
+        remark,
+        insert_time,
+        create_by,
+        create_user_id,
+        create_time,
+        update_by,
+        update_user_id,
+        update_time,
+        data_scope,
+        del_flag
+        )
+        VALUES
+        <foreach collection="data" item="item" separator=",">
+            (
+            #{item.id},
+            #{item.drugName},
+            #{item.barCode},
+            #{item.packSpec},
+            #{item.batch},
+            #{item.manuTime},
+            #{item.quaDrugs},
+            #{item.drugSpec},
+            #{item.packTime},
+            #{item.operator},
+            #{item.remark},
+            #{item.insertTime},
+            #{item.createBy},
+            #{item.createUserId},
+            #{item.createTime},
+            #{item.updateBy},
+            #{item.updateUserId},
+            #{item.updateTime},
+            #{item.dataScope},
+            #{item.delFlag}
+            )
+        </foreach>
+
+    </insert>
+</mapper>