diff --git a/ant-design-vue-jeecg/src/api/api.js b/ant-design-vue-jeecg/src/api/api.js
index d38eb66..04ac0f0 100644
--- a/ant-design-vue-jeecg/src/api/api.js
+++ b/ant-design-vue-jeecg/src/api/api.js
@@ -260,6 +260,17 @@ export const callShipmentBox = (params) => postAction('/shipment/shipmentHeader/
 export const listReceiveByReceiveId = (params) => postAction('/receipt/receiveHeader/listReceiveByReceiveId', params);
 //收货
 export const receive = (params) => postAction('/receipt/receiveHeader/receive', params);
+//全部收货
+export const receiveHeader = (params) => postAction('/receipt/receiveHeader/receiveHeader?id=' + params, params);
+//越库
+export const crossDocking = (params) => postAction('/receipt/receiptHeader/crossDocking?id=' + params, params);
+//收货详情转质检
+export const receiveDetailToQuality = (params) => postAction('/receipt/receiveHeader/receiveDetailToQuality?id=' + params, params);
+//质检
+export const qualityTesting = (params) => postAction('/receipt/qualityHeader/qualityTesting', params);
+//全部转质检
+export const receiveHeaderToQuality = (params) => postAction('/receipt/receiveHeader/receiveHeaderToQuality?id=' + params, params);
+
 // 中转HTTP请求
 export const transitRESTful = {
   get: (url, parameter) => getAction(getTransitURL(url), parameter),
diff --git a/ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue b/ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue
index 20b8514..5e407ad 100644
--- a/ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue
+++ b/ant-design-vue-jeecg/src/views/system/inventory/InventoryHeaderList.vue
@@ -206,6 +206,11 @@ export default {
           dataIndex: 'containerCode'
         },
         {
+          title: '物料编码',
+          align: "center",
+          dataIndex: 'materialCode'
+        },
+        {
           title: '容器状态',
           align: "center",
           dataIndex: 'containerStatus_dictText',
@@ -430,6 +435,7 @@ export default {
       fieldList.push({type: 'string', value: 'containerCode', text: '容器编码', dictCode: ''})
       fieldList.push({type: 'string', value: 'containerStatus', text: '容器状态', dictCode: 'container_status'})
       fieldList.push({type: 'string', value: 'locationCode', text: '库位编码', dictCode: ''})
+      fieldList.push({type: 'string', value: 'materialCode', text: '物料编码', dictCode: ''})
       fieldList.push({type: 'BigDecimal', value: 'totalQty', text: '总数量', dictCode: ''})
       fieldList.push({type: 'int', value: 'totalLines', text: '总行量', dictCode: ''})
       fieldList.push({type: 'string', value: 'createBy', text: '创建人', dictCode: ''})
diff --git a/ant-design-vue-jeecg/src/views/system/inventory/InventoryLevelAlarmList.vue b/ant-design-vue-jeecg/src/views/system/inventory/InventoryLevelAlarmList.vue
new file mode 100644
index 0000000..043726e
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/inventory/InventoryLevelAlarmList.vue
@@ -0,0 +1,327 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="物料编码">
+              <a-input placeholder="请输入物料编码" v-model="queryParam.materialCode"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="物料名称">
+              <a-input placeholder="请输入物料名称" v-model="queryParam.materialName"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl='6' :lg='7' :md='8' :sm='24'>
+            <a-form-item label='预警状态'>
+              <a-select show-search placeholder='请选择预警状态' option-filter-prop='children' v-model='queryParam.alarmStatus'>
+                <a-select-option v-for='item in alarmStatusList' :key='item.name' :value='item.code'>
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button id="search" type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator" style="display: none">
+      <a-button type="primary" icon="download" @click="handleExportXls('inventory_level_alarm')">导出</a-button>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a
+        style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <span slot="min" slot-scope="text, record">
+          <a-tag :key="record" :color="minColor(record)">
+            {{ minStatus(record) }}
+          </a-tag>
+        </span>
+
+        <span slot="max" slot-scope="text, record">
+          <a-tag :key="record" :color="maxColor(record)">
+            {{ maxStatus(record) }}
+          </a-tag>
+        </span>
+
+        <span slot="qtySum" slot-scope="text, record">
+          <a-tag :key="record" :color="qtySumColor(record)" style="font-size: 14px;font-weight: normal">
+            {{ qtySumStatus(record) }}
+          </a-tag>
+        </span>
+
+        <span slot="upper" slot-scope="text, record">
+          <a-tag :key="record" :color="upperColor(record)">
+            {{ record.upper }}
+          </a-tag>
+        </span>
+
+        <span slot="lower" slot-scope="text, record">
+          <a-tag :key="record" :color="lowerColor(record)">
+            {{ record.lower }}
+          </a-tag>
+        </span>
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" height="25px" alt=""
+               style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+      </a-table>
+    </div>
+  </a-card>
+</template>
+
+<script>
+
+import '@/assets/less/TableExpand.less'
+import {mixinDevice} from '@/utils/mixin'
+import {JeecgListMixin} from '@/mixins/JeecgListMixin'
+
+export default {
+  name: 'InventoryLevelAlarmList',
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {},
+  queryParam: {
+    materialName2:""
+  },
+  data() {
+    return {
+      description: '库存水位预警',
+      // alarmStatusList:['所有', '无预警', '有预警', '上限预警', '下限预警'],
+      alarmStatusList:[
+        {'name':'所有', 'code':'all'},
+        {'name':'无预警', 'code':'noAlarm'},
+        {'name':'有预警', 'code':'isAlarm'},
+        {'name':'上限预警', 'code':'upperAlarm'},
+        {'name':'下限预警', 'code':'lowerAlarm'}],
+      // 表头
+      columns: [
+        {
+          title: '#',
+          dataIndex: '',
+          key: 'rowIndex',
+          width: 60,
+          align: "center",
+          customRender: function (t, r, index) {
+            return parseInt(index) + 1;
+          }
+        },
+        {
+          title: '物料编码',
+          align: "center",
+          dataIndex: 'materialCode'
+        },
+        {
+          title: '物料名称',
+          align: "center",
+          dataIndex: 'materialName'
+        },
+        {
+          title: '最小值',
+          align: "center",
+          dataIndex: 'min',
+          scopedSlots: {customRender: 'min'}
+        },
+        {
+          title: '下限预警值',
+          align: "center",
+          dataIndex: 'lower',
+          scopedSlots: {customRender: 'lower'}
+        },
+        {
+          title: '库存数量',
+          align: "center",
+          dataIndex: 'qtySum',
+          scopedSlots: {customRender: 'qtySum'}
+        },
+        {
+          title: '上限预警值',
+          align: "center",
+          dataIndex: 'upper',
+          scopedSlots: {customRender: 'upper'}
+        },
+        {
+          title: '最大值',
+          align: "center",
+          dataIndex: 'max',
+          scopedSlots: {customRender: 'max'}
+        },
+        {
+          title: '物料规格',
+          align: "center",
+          dataIndex: 'materialSpec'
+        },
+        {
+          title: '物料单位',
+          align: "center",
+          dataIndex: 'materialUnit'
+        },
+        {
+          title: '仓库编码',
+          align: "center",
+          dataIndex: 'warehouseCode'
+        },
+        {
+          title: '货主编码',
+          align: "center",
+          dataIndex: 'companyCode'
+        },
+        {
+          title: '备注',
+          align: "center",
+          dataIndex: 'remark'
+        },
+      ],
+      url: {
+        list: "/inventory/inventoryLevel/list",
+        exportXlsUrl: "/inventory/inventoryLevel/exportXls",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    }
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    initDictConfig() {
+    },
+    qtySumStatus(record) {
+      if(record.qtySum <= record.lower){
+        return record.qtySum + " 🠋"
+      }
+      if(record.qtySum >= record.upper){
+        return record.qtySum + " 🠉"
+      }
+      return record.qtySum;
+    },
+    qtySumColor(record) {
+      if(record.qtySum >= record.upper || record.qtySum <= record.lower){
+        return 'red';
+      }
+      return '';
+    },
+
+    lowerColor(record) {
+      if(record.qtySum <= record.lower){
+        return 'blue';
+      }
+      return '';
+    },
+
+    upperColor(record) {
+      if(record.qtySum >= record.upper){
+        return 'blue';
+      }
+      return '';
+    },
+
+    maxColor(record) {
+      if(record.qtySum >= record.max){
+        return 'blue';
+      }
+      return '';
+    },
+
+    minColor(record) {
+      if(record.qtySum <= record.min){
+        return 'blue';
+      }
+      return '';
+    },
+
+    minStatus(record) {
+      if(record.min <= 0){
+        return ''
+      }
+      return record.min;
+    },
+
+    maxStatus(record) {
+      if(record.max <= 0){
+        return '';
+      }
+      return record.max;
+    },
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({type: 'string', value: 'alarmType', text: '预警类别代码'})
+      fieldList.push({type: 'string', value: 'warehouseCode', text: '仓库编码'})
+      fieldList.push({type: 'string', value: 'companyCode', text: '货主编码'})
+      fieldList.push({type: 'string', value: 'materialCode', text: '物料编码'})
+      fieldList.push({type: 'string', value: 'materialName', text: '物料名称'})
+      fieldList.push({type: 'string', value: 'materialSpec', text: '物料规格'})
+      fieldList.push({type: 'string', value: 'materialUnit', text: '物料单位'})
+      fieldList.push({type: 'int', value: 'qtysum', text: 'qtysum'})
+      fieldList.push({type: 'int', value: 'inlower', text: 'inlower'})
+      fieldList.push({type: 'int', value: 'inupper', text: 'inupper'})
+      fieldList.push({type: 'int', value: 'inmin', text: 'inmin'})
+      fieldList.push({type: 'int', value: 'inmax', text: 'inmax'})
+      fieldList.push({type: 'int', value: 'needalarm', text: 'needalarm'})
+      fieldList.push({type: 'int', value: 'max', text: '最大'})
+      fieldList.push({type: 'int', value: 'min', text: '最小'})
+      fieldList.push({type: 'int', value: 'upper', text: '上限预警值'})
+      fieldList.push({type: 'int', value: 'lower', text: '下限预警值'})
+      fieldList.push({type: 'string', value: 'remark', text: '备注'})
+      fieldList.push({type: 'string', value: 'userdef1', text: '备用字段1'})
+      fieldList.push({type: 'string', value: 'userdef2', text: '备用字段2'})
+      fieldList.push({type: 'string', value: 'userdef3', text: '备用字段3'})
+      this.superFieldList = fieldList
+    }
+  }
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>
\ No newline at end of file
diff --git a/ant-design-vue-jeecg/src/views/system/inventory/InventoryTransactionList.vue b/ant-design-vue-jeecg/src/views/system/inventory/InventoryTransactionList.vue
index b93a253..3395550 100644
--- a/ant-design-vue-jeecg/src/views/system/inventory/InventoryTransactionList.vue
+++ b/ant-design-vue-jeecg/src/views/system/inventory/InventoryTransactionList.vue
@@ -307,6 +307,11 @@ export default {
           scopedSlots: {customRender: 'inventoryStatus_dictText'}
         },
         {
+          title: '数量',
+          align: "center",
+          dataIndex: 'qty'
+        },
+        {
           title: '入库数量',
           align: "center",
           dataIndex: 'receiptQty'
diff --git a/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue b/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue
index e9b328c..73d1f11 100644
--- a/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue
+++ b/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue
@@ -618,7 +618,7 @@ export default {
         },
         success: function (response) {
           if (response.code == 200) {
-            $("#zone").val("库位总数:" + response.result.location + ", 空闲库位:" + response.result.emptyLocation +
+            $("#zone").val("库位总数:" + response.result.location + ", 空库位:" + response.result.emptyLocation +
               ", 空托盘库位:" + response.result.haveContainLocation + ", 有货库位:" + response.result.haveInventoryLocation)
           } else {
             alert(response.message)
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/QualityDetailList.vue b/ant-design-vue-jeecg/src/views/system/receipt/QualityDetailList.vue
new file mode 100644
index 0000000..e24e371
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/QualityDetailList.vue
@@ -0,0 +1,261 @@
+<template>
+  <a-card :bordered="false" :class="'cust-erp-sub-tab'">
+    <!-- 操作按钮区域 -->
+    <div class="table-operator" v-if="mainId">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button type="primary" icon="download" @click="handleExportXls('质检单详情')">导出</a-button>
+      <a-upload
+        name="file"
+        :showUploadList="false"
+        :multiple="false"
+        :headers="tokenHeader"
+        :action="importExcelUrl"
+        @change="handleImportExcel">
+          <a-button type="primary" icon="import">导入</a-button>
+      </a-upload>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        @change="handleTableChange">
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a v-has="'qualityDetail:edit'" @click="handleEdit(record)">编辑</a>
+          <a-divider type="vertical" />
+          <a v-has="'qualityDetail:quality'" v-if="(record.status != 200)" @click="qualityTesting(record)">质检</a>
+          <a-divider type="vertical" />
+          <a-popconfirm v-has="'qualityDetail:remove'" title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+
+      </a-table>
+    </div>
+
+    <qualityDetail-modal ref="modalForm" @ok="modalFormOk" :mainId="mainId"></qualityDetail-modal>
+    <quality-testing-modal ref="qualityTesting" @ok="modalFormOk" :mainId="mainId"></quality-testing-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import QualityDetailModal from './modules/QualityDetailModal'
+  import {receiveDetailToQuality, qualityTesting} from "@api/api";
+  import QualityTestingModal from "@views/system/receipt/modules/QualityTestingModal";
+
+  export default {
+    name: "QualityDetailList",
+    mixins:[JeecgListMixin],
+    components: {QualityTestingModal, QualityDetailModal },
+    props:{
+      mainId:{
+        type:String,
+        default:'',
+        required:false
+      }
+    },
+    watch:{
+      mainId:{
+        immediate: true,
+        handler(val) {
+          if(!this.mainId){
+            this.clearList()
+          }else{
+            this.queryParam['qualityId'] = val
+            this.loadData(1);
+          }
+        }
+      }
+    },
+    data () {
+      return {
+        description: '质检表单头管理页面',
+        disableMixinCreated:true,
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'物料编码',
+            align:"center",
+            dataIndex: 'materialCode'
+          },
+          {
+            title:'物料名称',
+            align:"center",
+            dataIndex: 'materialName'
+          },
+          {
+            title:'物料规格',
+            align:"center",
+            dataIndex: 'materialSpec'
+          },
+          {
+            title:'物料单位',
+            align:"center",
+            dataIndex: 'materialUnit'
+          },
+          {
+            title:'单据数量',
+            align:"center",
+            dataIndex: 'qty'
+          },
+          {
+            title:'合格数量',
+            align:"center",
+            dataIndex: 'qualityfiedQty'
+          },
+          {
+            title:'不合格数量',
+            align:"center",
+            dataIndex: 'unqualityfiedQty'
+          },
+          {
+            title:'不合格原因',
+            align:"center",
+            dataIndex: 'remark'
+          },
+          {
+            title:'批次',
+            align:"center",
+            dataIndex: 'batch'
+          },
+          {
+            title:'批号',
+            align:"center",
+            dataIndex: 'lot'
+          },
+          {
+            title:'项目号',
+            align:"center",
+            dataIndex: 'project'
+          },
+          {
+            title:'单据状态',
+            align:"center",
+            dataIndex: 'status_dictText'
+          },
+          // {
+          //   title:'上游单号',
+          //   align:"center",
+          //   dataIndex: 'referCode'
+          // },
+          // {
+          //   title:'上游行号',
+          //   align:"center",
+          //   dataIndex: 'referLineNum'
+          // },
+          {
+            title:'创建人',
+            align:"center",
+            dataIndex: 'createBy'
+          },
+          {
+            title:'创建日期',
+            align:"center",
+            dataIndex: 'createTime'
+          },
+          {
+            title:'更新人',
+            align:"center",
+            dataIndex: 'updateBy'
+          },
+          {
+            title:'更新日期',
+            align:"center",
+            dataIndex: 'updateTime'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+        url: {
+          list: "/receipt/qualityHeader/listQualityDetailByMainId",
+          delete: "/receipt/qualityHeader/deleteQualityDetail",
+          deleteBatch: "/receipt/qualityHeader/deleteBatchQualityDetail",
+          exportXlsUrl: "/receipt/qualityHeader/exportQualityDetail",
+          importUrl: "/receipt/qualityHeader/importQualityDetail",
+        },
+        dictOptions:{
+        }
+      }
+    },
+    created() {
+    },
+    computed: {
+      importExcelUrl(){
+        return `${window._CONFIG['domianURL']}/${this.url.importUrl}/${this.mainId}`;
+      }
+    },
+    methods: {
+      clearList(){
+        this.dataSource=[]
+        this.selectedRowKeys=[]
+        this.ipagination.current = 1
+      },
+      qualityTesting(record) {
+        this.$refs.qualityTesting.edit(record);
+        this.$refs.qualityTesting.title = "质检";
+      },
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less'
+</style>
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/QualityHeaderList.vue b/ant-design-vue-jeecg/src/views/system/receipt/QualityHeaderList.vue
new file mode 100644
index 0000000..597f7be
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/QualityHeaderList.vue
@@ -0,0 +1,448 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="编码">
+              <a-input placeholder="请输入编码" v-model="queryParam.code"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="类型">
+              <a-input placeholder="请输入类型" v-model="queryParam.type"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="货主">
+              <a-select
+                show-search
+                placeholder="请选择货主"
+                option-filter-prop="children"
+                v-model="queryParam.companyCode">
+                <a-select-option v-for="item in companyList" :key="item.name" :value="item.code">{{
+                    item.name
+                  }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="头状态">
+                <a-input placeholder="请输入头状态" v-model="queryParam.firstStatus"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="尾状态">
+                <a-input placeholder="请输入尾状态" v-model="queryParam.lastStatus"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="上游单号">
+                <a-input placeholder="请输入上游单号" v-model="queryParam.referCode"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="供应商">
+                <a-select
+                  show-search
+                  placeholder="请选择供应商"
+                  option-filter-prop="children"
+                  v-model="queryParam.supplierCode">
+                  <a-select-option v-for="item in supplierList" :key="item.name" :value="item.code">{{
+                      item.name
+                    }}
+                  </a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="备注">
+                <a-input placeholder="请输入备注" v-model="queryParam.remark"></a-input>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button v-has="'qualityHeader:add'" @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button v-has="'qualityHeader:export'" type="primary" icon="download" @click="handleExportXls('质检表单头')">导出</a-button>
+      <a-upload v-has="'qualityHeader:import'" name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload>
+      <!-- 高级查询区域 -->
+      <j-super-query v-has="'qualityHeader:superQuery'" :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        class="j-table-force-nowrap"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
+        :customRow="clickThenSelect"
+        @change="handleTableChange">
+
+        <span slot="companyCode" slot-scope="companyCode">
+          <a-tag :key="companyCode" color=blue>
+            {{ solutionCompany(companyCode) }}
+          </a-tag>
+        </span>
+
+        <span slot="firstStatus_dictText" slot-scope="firstStatus_dictText">
+            <a-tag :key="firstStatus_dictText" :color="getStatusColor(firstStatus_dictText)">
+              {{ firstStatus_dictText }}
+            </a-tag>
+        </span>
+
+        <span slot="lastStatus_dictText" slot-scope="lastStatus_dictText">
+            <a-tag :key="lastStatus_dictText" :color="getStatusColor(lastStatus_dictText)">
+              {{ lastStatus_dictText }}
+            </a-tag>
+        </span>
+
+        <span slot="supplierCode" slot-scope="supplierCode">
+          <a-tag :key="supplierCode" color=pink>
+            {{ solutionSupplier(supplierCode) }}
+          </a-tag>
+        </span>
+
+
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a  v-has="'qualityHeader:edit'" v-if="(record.firstStatus == 0)" @click="handleEdit(record)">
+            <a-button  type="primary">编辑</a-button><a-divider type="vertical"/>
+          </a>
+
+          <a-popconfirm v-has="'qualityHeader:remove'" v-if="(record.firstStatus == 0)" title="确定删除吗?" @confirm="() => handleDelete(record.id)" >
+            <a><a-button type="primary">删除</a-button></a>
+            <a-divider type="vertical"/>
+          </a-popconfirm>
+<!--          <a-dropdown>-->
+<!--            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>-->
+<!--            <a-menu slot="overlay">-->
+<!--              <a-menu-item>-->
+<!--                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">-->
+<!--                  <a>删除</a>-->
+<!--                </a-popconfirm>-->
+<!--              </a-menu-item>-->
+<!--            </a-menu>-->
+<!--          </a-dropdown>-->
+        </span>
+
+      </a-table>
+    </div>
+
+    <a-tabs defaultActiveKey="1">
+      <a-tab-pane tab="质检单详情" key="1" >
+        <QualityDetailList :mainId="selectedMainId" />
+      </a-tab-pane>
+    </a-tabs>
+
+    <qualityHeader-modal ref="modalForm" @ok="modalFormOk"></qualityHeader-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import QualityHeaderModal from './modules/QualityHeaderModal'
+  import { getAction } from '@/api/manage'
+  import QualityDetailList from './QualityDetailList'
+  import '@/assets/less/TableExpand.less'
+  import {getCompanyList, getSupplierList} from "@api/api";
+
+  export default {
+    name: "QualityHeaderList",
+    mixins:[JeecgListMixin],
+    components: {
+      QualityDetailList,
+      QualityHeaderModal
+    },
+    data () {
+      return {
+        description: '质检表单头管理页面',
+        companyList: [],
+        supplierList: [],
+        // 表头
+        columns: [
+          {
+            title:'编码',
+            align:"center",
+            dataIndex: 'code'
+          },
+          {
+            title:'类型',
+            align:"center",
+            dataIndex: 'type_dictText',
+          },
+          {
+            title: '货主',
+            align: "center",
+            dataIndex: 'companyCode',
+            key: 'companyCode',
+            scopedSlots: {customRender: 'companyCode'}
+          },
+          {
+            title:'头状态',
+            align:"center",
+            dataIndex: 'firstStatus_dictText',
+            key: 'firstStatus_dictText',
+            scopedSlots: {customRender: 'firstStatus_dictText'}
+          },
+          {
+            title:'尾状态',
+            align:"center",
+            dataIndex: 'lastStatus_dictText',
+            key: 'lastStatus_dictText',
+            scopedSlots: {customRender: 'lastStatus_dictText'}
+          },
+          {
+            title:'上游单号',
+            align:"center",
+            dataIndex: 'referCode'
+          },
+          {
+            title: '供应商',
+            align: "center",
+            dataIndex: 'supplierCode',
+            key: 'supplierCode',
+            scopedSlots: {customRender: 'supplierCode'}
+          },
+          {
+            title:'总数量',
+            align:"center",
+            dataIndex: 'totalQty'
+          },
+          {
+            title:'总行数',
+            align:"center",
+            dataIndex: 'totalLines'
+          },
+          {
+            title:'备注',
+            align:"center",
+            dataIndex: 'remark'
+          },
+          {
+            title:'创建人',
+            align:"center",
+            dataIndex: 'createBy'
+          },
+          {
+            title:'创建日期',
+            align:"center",
+            dataIndex: 'createTime'
+          },
+          {
+            title:'更新人',
+            align:"center",
+            dataIndex: 'updateBy'
+          },
+          {
+            title:'更新日期',
+            align:"center",
+            dataIndex: 'updateTime'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+        url: {
+          list: "/receipt/qualityHeader/list",
+          delete: "/receipt/qualityHeader/delete",
+          deleteBatch: "/receipt/qualityHeader/deleteBatch",
+          exportXlsUrl: "/receipt/qualityHeader/exportXls",
+          importExcelUrl: "receipt/qualityHeader/importExcel",
+        },
+        dictOptions:{
+        },
+        /* 分页参数 */
+        ipagination:{
+          current: 1,
+          pageSize: 5,
+          pageSizeOptions: ['5', '10', '50'],
+          showTotal: (total, range) => {
+            return range[0] + "-" + range[1] + " 共" + total + "条"
+          },
+          showQuickJumper: true,
+          showSizeChanger: true,
+          total: 0
+        },
+        selectedMainId:'',
+        superFieldList:[],
+      }
+    },
+    created() {
+      this.getSuperFieldList();
+      this.loadFrom();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      }
+    },
+    methods: {
+      initDictConfig(){
+      },
+      clickThenSelect(record) {
+        return {
+          on: {
+            click: () => {
+              this.onSelectChange(record.id.split(","), [record]);
+            }
+          }
+        }
+      },
+      onClearSelected() {
+        this.selectedRowKeys = [];
+        this.selectionRows = [];
+        this.selectedMainId=''
+      },
+      onSelectChange(selectedRowKeys, selectionRows) {
+        this.selectedMainId=selectedRowKeys[0]
+        this.selectedRowKeys = selectedRowKeys;
+        this.selectionRows = selectionRows;
+      },
+      getStatusColor(status) {
+        const colors = {
+          '新建': 'green',
+          '部分质检': 'Skyblue',
+          '质检完成': 'blue',
+          default: 'blue'
+        };
+        return colors[status] || colors.default;
+      },
+      loadFrom() {
+        getCompanyList().then((res) => {
+          if (res.success) {
+            this.companyList = res.result
+          }
+        });
+        getSupplierList().then((res) => {
+          if (res.success) {
+            this.supplierList = res.result
+          }
+        });
+      },
+      solutionCompany(value) {
+        var actions = []
+        Object.keys(this.companyList).some((key) => {
+          if (this.companyList[key].code == ('' + value)) {
+            actions.push(this.companyList[key].name)
+            return true
+          }
+        })
+        return actions.join('')
+      },
+      solutionSupplier(value) {
+        var actions = []
+        Object.keys(this.supplierList).some((key) => {
+          if (this.supplierList[key].code == ('' + value)) {
+            actions.push(this.supplierList[key].name)
+            return true
+          }
+        })
+        return actions.join('')
+      },
+      loadData(arg) {
+        if(!this.url.list){
+          this.$message.error("请设置url.list属性!")
+          return
+        }
+        //加载数据 若传入参数1则加载第一页的内容
+        if (arg === 1) {
+          this.ipagination.current = 1;
+        }
+        this.onClearSelected()
+        var params = this.getQueryParams();//查询条件
+        this.loading = true;
+        getAction(this.url.list, params).then((res) => {
+          if (res.success) {
+            this.dataSource = res.result.records;
+            this.ipagination.total = res.result.total;
+          }
+          if(res.code===510){
+            this.$message.warning(res.message)
+          }
+          this.loading = false;
+        })
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'code',text:'编码',dictCode:''})
+        fieldList.push({type:'string',value:'type',text:'类型',dictCode:''})
+        fieldList.push({type:'string',value:'companyCode',text:'货主编码',dictCode:''})
+        fieldList.push({type:'int',value:'firstStatus',text:'头状态',dictCode:''})
+        fieldList.push({type:'int',value:'lastStatus',text:'尾状态',dictCode:''})
+        fieldList.push({type:'string',value:'referCode',text:'上游单号',dictCode:''})
+        fieldList.push({type:'string',value:'supplierCode',text:'供应商编码',dictCode:''})
+        fieldList.push({type:'BigDecimal',value:'totalQty',text:'总数量',dictCode:''})
+        fieldList.push({type:'int',value:'totalLines',text:'总行数',dictCode:''})
+        fieldList.push({type:'string',value:'remark',text:'备注',dictCode:''})
+        fieldList.push({type:'string',value:'createBy',text:'创建人',dictCode:''})
+        fieldList.push({type:'datetime',value:'createTime',text:'创建日期'})
+        fieldList.push({type:'string',value:'updateBy',text:'更新人',dictCode:''})
+        fieldList.push({type:'datetime',value:'updateTime',text:'更新日期'})
+        this.superFieldList = fieldList
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less'
+</style>
\ No newline at end of file
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue b/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
index 065876b..2afa07a 100644
--- a/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
+++ b/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
@@ -178,6 +178,11 @@
         <span slot="action" slot-scope="text, record">
           <a-popconfirm v-has="'receiptHeader:back'" v-if="record.lastStatus == 800" title="确定回传吗?" @confirm="() => hanleBack(record)">
           	<a><a-button type="default">回传</a-button></a>
+            <a-divider type="vertical"/>
+          </a-popconfirm>
+          <a-popconfirm v-has="'receiptHeader:crossDocking'" v-if="record.lastStatus == 0" title="确定越库吗?" @confirm="() => hanleCross(record)">
+          	<a><a-button type="primary">越库</a-button></a>
+            <a-divider type="vertical"/>
           </a-popconfirm>
           <a v-if="(record.lastStatus < 800 && record.firstStatus >= 15 && record.firstStatus != '20') || (flowOff == '0' && record.lastStatus < 800) " @click="receive(record)" v-has="'receiptHeader:receive'">
             <a-button type="primary">组盘</a-button>
@@ -230,7 +235,7 @@ import {initDictOptions, filterMultiDictText} from '@/components/dict/JDictSelec
 import '@/assets/less/TableExpand.less'
 import {getCompanyList} from '@/api/api'
 import {getReceiptTypeList} from '@/api/api'
-import {getSupplierList, backErpReceipt,createReceiptAuditFlow,getDocumentAduitFlow} from '@/api/api'
+import {getSupplierList, backErpReceipt,createReceiptAuditFlow,getDocumentAduitFlow, crossDocking} from '@/api/api'
 import ReceiptModal from "./modules/ReceiptModal";
 import { notification } from 'ant-design-vue';
 import FlowProcess from "../flow/FlowProcess";
@@ -537,6 +542,16 @@ export default {
         this.searchQuery();
       });
     },
+    hanleCross(record) {
+      crossDocking(record.id).then((res) => {
+        if (res.success) {
+          this.$message.success(res.message);
+        } else {
+          this.$message.warning(res.message);
+        }
+        this.searchQuery();
+      });
+    },
     loadFrom() {
       getCompanyList().then((res) => {
         if (res.success) {
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/ReceiveDetailList.vue b/ant-design-vue-jeecg/src/views/system/receipt/ReceiveDetailList.vue
index 0984995..94c7d4a 100644
--- a/ant-design-vue-jeecg/src/views/system/receipt/ReceiveDetailList.vue
+++ b/ant-design-vue-jeecg/src/views/system/receipt/ReceiveDetailList.vue
@@ -80,9 +80,11 @@
         </template>
 
         <span slot="action" slot-scope="text, record">
-          <a @click="handleEdit(record)">编辑</a>
+          <a v-has="'receiveDetail:edit'" @click="handleEdit(record)">编辑</a>
           <a-divider type="vertical" />
-          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+          <a v-has="'receiveDetail:quality'" v-if="(record.status == 200)" @click="receiveDetailToQuality(record.id)">质检</a>
+          <a-divider type="vertical" />
+          <a-popconfirm v-has="'receiveDetail:remove'" title="确定删除吗?" @confirm="() => handleDelete(record.id)">
             <a>删除</a>
           </a-popconfirm>
         </span>
@@ -98,7 +100,7 @@
 
   import { JeecgListMixin } from '@/mixins/JeecgListMixin'
   import ReceiveDetailModal from './modules/ReceiveDetailModal'
-  import {getCompanyList, getSupplierList} from "@api/api";
+  import {getCompanyList, getSupplierList, receiveHeader, receiveDetailToQuality} from "@api/api";
 
   export default {
     name: "ReceiveDetailList",
@@ -175,6 +177,11 @@
             dataIndex: 'taskQty'
           },
           {
+            title:'质检数量',
+            align:"center",
+            dataIndex: 'qualityQty'
+          },
+          {
             title: '库存状态',
             align: "center",
             dataIndex: 'inventoryStatus_dictText',
@@ -262,6 +269,16 @@
           }
         });
       },
+      receiveDetailToQuality(record) {
+        receiveDetailToQuality(record).then((res) => {
+          if (res.success) {
+            this.$message.success(res.message)
+          } else {
+            this.$message.warning(res.message)
+          }
+          this.searchQuery();
+        });
+      },
       getStatusColor(status) {
         const colors = {
           '良品': 'green',
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/ReceiveHeaderList.vue b/ant-design-vue-jeecg/src/views/system/receipt/ReceiveHeaderList.vue
index 0600714..e7abd50 100644
--- a/ant-design-vue-jeecg/src/views/system/receipt/ReceiveHeaderList.vue
+++ b/ant-design-vue-jeecg/src/views/system/receipt/ReceiveHeaderList.vue
@@ -80,14 +80,14 @@
 
     <!-- 操作按钮区域 -->
     <div class="table-operator">
-      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
-      <a-button  type="primary" icon="download" @click="handleExportXls('收货单表头')">导出</a-button>
-      <a-upload  name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+      <a-button v-has="'receiveHeader:add'" @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button  v-has="'receiveHeader:export'" type="primary" icon="download" @click="handleExportXls('收货单表头')">导出</a-button>
+      <a-upload  v-has="'receiveHeader:import'"  name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
         <a-button type="primary" icon="import">导入</a-button>
-        <a-button v-has="'receiveHeader:print'" @click="batchPrint()" type="primary">打印</a-button>
       </a-upload>
+      <a-button v-has="'receiveHeader:print'" @click="batchPrint()" type="primary">打印</a-button>
       <!-- 高级查询区域 -->
-<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+      <j-super-query v-has="'receiveHeader:superQuery'" :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
     </div>
 
     <!-- table区域-begin -->
@@ -118,6 +118,12 @@
           </a-tag>
         </span>
 
+        <span slot="type" slot-scope="type">
+          <a-tag :key="type" color=pink>
+            {{ solutionType(type) }}
+          </a-tag>
+        </span>
+
         <span slot="firstStatus_dictText" slot-scope="firstStatus_dictText">
             <a-tag :key="firstStatus_dictText" :color="getStatusColor(firstStatus_dictText)">
               {{ firstStatus_dictText }}
@@ -157,22 +163,32 @@
         </template>
 
         <span slot="action" slot-scope="text, record">
-          <a  @click="receive(record)">
-            <a-button v-if="(record.lastStatus < 200)"  type="primary">收货</a-button><a-divider type="vertical"/>
+          <a  v-has="'receiveHeader:receive'" v-if="(record.lastStatus < 200)"  @click="receive(record)">
+            <a-button  type="primary">收货</a-button><a-divider type="vertical"/>
           </a>
-          <a  @click="handleEdit(record)">
-            <a-button type="primary">编辑</a-button><a-divider type="vertical"/>
+          <a v-has="'receiveHeader:receive'" v-if="(record.lastStatus < 200)" @click="receiveHeader(record.id)">
+            <a-button  type="primary">全部收货</a-button><a-divider type="vertical"/>
           </a>
-          <a-dropdown>
-            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
-            <a-menu slot="overlay">
-              <a-menu-item>
-                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
-                  <a>删除</a>
-                </a-popconfirm>
-              </a-menu-item>
-            </a-menu>
-          </a-dropdown>
+          <a v-has="'receiveHeader:quality'" v-if="(record.lastStatus == 200)" @click="receiveHeaderToQuality(record.id)">
+            <a-button  type="primary">全部质检</a-button><a-divider type="vertical"/>
+          </a>
+          <a  v-has="'receiveHeader:edit'" v-if="(record.firstStatus == 0)" @click="handleEdit(record)">
+            <a-button  type="primary">编辑</a-button><a-divider type="vertical"/>
+          </a>
+          <a-popconfirm v-has="'receiveHeader:remove'" v-if="(record.firstStatus == 0)" title="确定删除吗?" @confirm="() => handleDelete(record.id)" >
+            <a><a-button type="primary">删除</a-button></a>
+            <a-divider type="vertical"/>
+          </a-popconfirm>
+<!--          <a-dropdown>-->
+<!--            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>-->
+<!--            <a-menu slot="overlay">-->
+<!--              <a-menu-item>-->
+<!--                <a-popconfirm v-has="'receiveHeader:remove'" title="确定删除吗?" @confirm="() => handleDelete(record.id)">-->
+<!--                  <a>删除</a>-->
+<!--                </a-popconfirm>-->
+<!--              </a-menu-item>-->
+<!--            </a-menu>-->
+<!--          </a-dropdown>-->
         </span>
 
       </a-table>
@@ -196,7 +212,7 @@
   import { getAction } from '@/api/manage'
   import ReceiveDetailList from './ReceiveDetailList'
   import '@/assets/less/TableExpand.less'
-  import {getCompanyList, getSupplierList} from "@api/api";
+  import {getCompanyList, getSupplierList, receiveHeader, receiveHeaderToQuality} from "@api/api";
   import ReceiveModal from "@views/system/receipt/modules/ReceiveModal";
 
   export default {
@@ -382,6 +398,26 @@
         this.$refs.modalForm2.edit(record);
         this.$refs.modalForm2.title = "收货";
       },
+      receiveHeader(record) {
+        receiveHeader(record).then((res) => {
+          if (res.success) {
+            this.$message.success(res.message)
+          } else {
+            this.$message.warning(res.message)
+          }
+          this.searchQuery();
+        });
+      },
+      receiveHeaderToQuality(record) {
+        receiveHeaderToQuality(record).then((res) => {
+          if (res.success) {
+            this.$message.success(res.message)
+          } else {
+            this.$message.warning(res.message)
+          }
+          this.searchQuery();
+        });
+      },
       loadFrom() {
         getCompanyList().then((res) => {
           if (res.success) {
@@ -394,6 +430,16 @@
           }
         });
       },
+      solutionType(value) {
+        var actions = []
+        Object.keys(this.receiptTypeList).some((key) => {
+          if (this.receiptTypeList[key].code == ('' + value)) {
+            actions.push(this.receiptTypeList[key].name)
+            return true
+          }
+        })
+        return actions.join('')
+      },
       solutionCompany(value) {
         var actions = []
         Object.keys(this.companyList).some((key) => {
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityDetailModal.vue b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityDetailModal.vue
new file mode 100644
index 0000000..903177a
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityDetailModal.vue
@@ -0,0 +1,169 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <a-spin :spinning="confirmLoading">
+      <a-form-model ref="form" :model="model" :rules="validatorRules">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="物料编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialCode">
+              <a-input v-model="model.materialCode"placeholder="请输入物料编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialName">
+              <a-input v-model="model.materialName"placeholder="请输入物料名称" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料规格" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialSpec">
+              <a-input v-model="model.materialSpec"placeholder="请输入物料规格" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料单位" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialUnit">
+              <a-input v-model="model.materialUnit"placeholder="请输入物料单位" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="单据数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty">
+              <a-input-number v-model="model.qty"placeholder="请输入单据数量" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="库存状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inventoryStatus">
+              <a-input v-model="model.inventoryStatus"placeholder="请输入库存状态" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="批次" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="batch">
+              <a-input v-model="model.batch"placeholder="请输入批次" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="批号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="lot">
+              <a-input v-model="model.lot"placeholder="请输入批号" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="项目号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="project">
+              <a-input v-model="model.project"placeholder="请输入项目号" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="单据状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
+              <a-input-number v-model="model.status"placeholder="请输入单据状态" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+  import { httpAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+  import {receiveHeader} from "@api/api";
+
+  export default {
+    name: "QualityDetailModal",
+    components: {
+    },
+    props:{
+      mainId:{
+        type:String,
+        required:false,
+        default:''
+      }
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        model:{
+        },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+
+        confirmLoading: false,
+validatorRules: {
+},
+        url: {
+          add: "/receipt/qualityHeader/addQualityDetail",
+          edit: "/receipt/qualityHeader/editQualityDetail",
+        }
+
+      }
+    },
+    created () {
+    //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+        this.$refs.form.clearValidate();
+      },
+      handleOk () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            this.model['qualityId'] = this.mainId
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+          }else{
+             return false
+          }
+        })
+      },
+      handleCancel () {
+        this.close()
+      },
+
+
+    }
+  }
+</script>
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderForm.vue b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderForm.vue
new file mode 100644
index 0000000..f143ca0
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderForm.vue
@@ -0,0 +1,260 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <!-- 主表单区域 -->
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24" >
+            <a-form-model-item label="编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="code">
+              <a-input v-model="model.code" placeholder="请输入编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" >
+            <a-form-model-item label="类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="type">
+              <a-input v-model="model.type" placeholder="请输入类型" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" >
+            <a-form-model-item label="货主编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="companyCode">
+              <a-input v-model="model.companyCode" placeholder="请输入货主编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" >
+            <a-form-model-item label="上游单号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="referCode">
+              <a-input v-model="model.referCode" placeholder="请输入上游单号" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" >
+            <a-form-model-item label="供应商编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="supplierCode">
+              <a-input v-model="model.supplierCode" placeholder="请输入供应商编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" >
+            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-input v-model="model.remark" placeholder="请输入备注" ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+      <!-- 子表单区域 -->
+    <a-tabs v-model="activeKey" @change="handleChangeTabs">
+      <a-tab-pane tab="质检单详情" :key="refKeys[0]" :forceRender="true">
+        <j-vxe-table
+          keep-source
+          :ref="refKeys[0]"
+          :loading="qualityDetailTable.loading"
+          :columns="qualityDetailTable.columns"
+          :dataSource="qualityDetailTable.dataSource"
+          :maxHeight="300"
+          :disabled="formDisabled"
+          :rowNumber="true"
+          :rowSelection="true"
+          :toolbar="true"
+          />
+      </a-tab-pane>
+    </a-tabs>
+  </a-spin>
+</template>
+
+<script>
+
+  import { getAction } from '@/api/manage'
+  import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
+  import { JVXETypes } from '@/components/jeecg/JVxeTable'
+  import { getRefPromise,VALIDATE_FAILED} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
+  import { validateDuplicateValue } from '@/utils/util'
+  import JFormContainer from '@/components/jeecg/JFormContainer'
+
+  export default {
+    name: 'QualityHeaderForm',
+    mixins: [JVxeTableModelMixin],
+    components: {
+      JFormContainer,
+    },
+    data() {
+      return {
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        model:{
+         },
+        // 新增时子表默认添加几行空数据
+        addDefaultRowNum: 1,
+validatorRules: {
+        code: [
+            { required: true, message: '请输入编码!'},
+        ],
+},
+        refKeys: ['qualityDetail', ],
+        tableKeys:['qualityDetail', ],
+        activeKey: 'qualityDetail',
+        // 质检单详情
+        qualityDetailTable: {
+          loading: false,
+          dataSource: [],
+          columns: [
+            {
+              title: '物料编码',
+              key: 'materialCode',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '物料名称',
+              key: 'materialName',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '物料规格',
+              key: 'materialSpec',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '物料单位',
+              key: 'materialUnit',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '单据数量',
+              key: 'qty',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '库存状态',
+              key: 'inventoryStatus',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '批次',
+              key: 'batch',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '批号',
+              key: 'lot',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '项目号',
+              key: 'project',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+            {
+              title: '单据状态',
+              key: 'status',
+               type: JVXETypes.input,
+              width:"200px",
+              placeholder: '请输入${title}',
+              defaultValue:'',
+            },
+          ]
+        },
+        url: {
+          add: "/receipt/qualityHeader/add",
+          edit: "/receipt/qualityHeader/edit",
+          queryById: "/receipt/qualityHeader/queryById",
+          qualityDetail: {
+            list: '/receipt/qualityHeader/queryQualityDetailByMainId'
+          },
+        }
+      }
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+    },
+    methods: {
+      addBefore(){
+        this.qualityDetailTable.dataSource=[]
+      },
+      getAllTable() {
+        let values = this.tableKeys.map(key => getRefPromise(this, key))
+        return Promise.all(values)
+      },
+      /** 调用完edit()方法之后会自动调用此方法 */
+      editAfter() {
+        this.$nextTick(() => {
+        })
+        // 加载子表数据
+        if (this.model.id) {
+          let params = { id: this.model.id }
+          this.requestSubTableData(this.url.qualityDetail.list, params, this.qualityDetailTable)
+        }
+      },
+      //校验所有一对一子表表单
+        validateSubForm(allValues){
+            return new Promise((resolve,reject)=>{
+              Promise.all([
+              ]).then(() => {
+                resolve(allValues)
+              }).catch(e => {
+                if (e.error === VALIDATE_FAILED) {
+                  // 如果有未通过表单验证的子表,就自动跳转到它所在的tab
+                  this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
+                } else {
+                  console.error(e)
+                }
+              })
+            })
+        },
+      /** 整理成formData */
+      classifyIntoFormData(allValues) {
+        let main = Object.assign(this.model, allValues.formValue)
+        return {
+          ...main, // 展开
+          qualityDetailList: allValues.tablesValue[0].tableData,
+        }
+      },
+      validateError(msg){
+        this.$message.error(msg)
+      },
+
+    }
+  }
+</script>
+
+<style scoped>
+</style>
\ No newline at end of file
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderModal.vue b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderModal.vue
new file mode 100644
index 0000000..c339e7c
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityHeaderModal.vue
@@ -0,0 +1,143 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <a-spin :spinning="confirmLoading">
+      <a-form-model ref="form" :model="model" :rules="validatorRules">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="code">
+              <a-input v-model="model.code" placeholder="请输入编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="type">
+              <a-input v-model="model.type" placeholder="请输入类型" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="货主编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="companyCode">
+              <a-input v-model="model.companyCode" placeholder="请输入货主编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="上游单号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="referCode">
+              <a-input v-model="model.referCode" placeholder="请输入上游单号" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="供应商编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="supplierCode">
+              <a-input v-model="model.supplierCode" placeholder="请输入供应商编码" ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-input v-model="model.remark" placeholder="请输入备注" ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+  import { httpAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: "QualityHeaderModal",
+    components: { 
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        model:{
+        },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+
+        confirmLoading: false,
+validatorRules: {
+        code: [
+            { required: true, message: '请输入编码!'},
+        ],
+},
+        url: {
+          add: "/receipt/qualityHeader/add",
+          edit: "/receipt/qualityHeader/edit",
+        }
+     
+      }
+    },
+    created () {
+    //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+        this.$refs.form.clearValidate();
+      },
+      handleOk () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+          }else{
+             return false
+          }
+        })
+      },
+      handleCancel () {
+        this.close()
+      },
+
+      
+    }
+  }
+</script>
\ No newline at end of file
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityTestingModal.vue b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityTestingModal.vue
new file mode 100644
index 0000000..1cd22e7
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/receipt/modules/QualityTestingModal.vue
@@ -0,0 +1,160 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <a-spin :spinning="confirmLoading">
+      <a-form-model ref="form" :model="model" :rules="validatorRules">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="物料编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialCode">
+              <a-input v-model="model.materialCode"placeholder="请输入物料编码" disabled="true"/></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialName">
+              <a-input v-model="model.materialName"placeholder="请输入物料名称" disabled="true"></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料规格" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialSpec">
+              <a-input v-model="model.materialSpec"placeholder="请输入物料规格" disabled="true"></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="物料单位" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialUnit">
+              <a-input v-model="model.materialUnit"placeholder="请输入物料单位" disabled="true"></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="单据数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty">
+              <a-input-number v-model="model.qty"placeholder="请输入单据数量" style="width: 100%" disabled="true"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="合格数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty">
+              <a-input-number v-model="model.qualityfiedQty"placeholder="请输入合格数量" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="不合格数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty">
+              <a-input-number v-model="model.unqualityfiedQty"placeholder="请输入不合格数量" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="不合格原因" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-input v-model="model.remark"placeholder="请输入不合格原因"  />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+  import { httpAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+  import {receiveHeader, qualityTesting} from "@api/api";
+
+  export default {
+    name: "QualityTestingModal",
+    components: {
+    },
+    props:{
+      mainId:{
+        type:String,
+        required:false,
+        default:''
+      }
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        model:{
+        },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+
+        confirmLoading: false,
+        validatorRules: {
+        },
+        url: {
+          add: "/receipt/qualityHeader/addQualityDetail",
+          edit: "/receipt/qualityHeader/editQualityDetail",
+        }
+
+      }
+    },
+    created () {
+    //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+        this.$refs.form.clearValidate();
+      },
+
+      handleOk () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            this.model['qualityId'] = this.mainId
+            qualityTesting(this.model).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+          }else{
+             return false
+          }
+        })
+      },
+      handleCancel () {
+        this.close()
+      },
+
+
+    }
+  }
+</script>
diff --git a/ant-design-vue-jeecg/src/views/system/receipt/modules/ReceiveDetailModal.vue b/ant-design-vue-jeecg/src/views/system/receipt/modules/ReceiveDetailModal.vue
index 4b27227..3d7b8df 100644
--- a/ant-design-vue-jeecg/src/views/system/receipt/modules/ReceiveDetailModal.vue
+++ b/ant-design-vue-jeecg/src/views/system/receipt/modules/ReceiveDetailModal.vue
@@ -80,6 +80,15 @@
 
         confirmLoading: false,
         validatorRules: {
+          materialCode: [
+            {required: true, message: '请输入物料编码!'},
+          ],
+          qty: [
+            {required: true, message: '请输入单据数量!'},
+          ],
+          inventoryStatus: [
+            {required: true, message: '请输入库存状态!'},
+          ],
         },
         url: {
           add: "/receipt/receiveHeader/addReceiveDetail",
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java
index 5a46aff..ec89e6a 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java
@@ -326,7 +326,7 @@ public class WcsServiceImpl implements WcsService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "#taskHeader == null ? '' : #taskHeader.getId()", bizType = "'任务追踪'", tag = "'任务下发'", extra = "''",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
         recordReturnValue = true)
     public Result wcsTaskAssign(TaskHeader taskHeader) {
         if (taskHeader == null) {
@@ -567,7 +567,7 @@ public class WcsServiceImpl implements WcsService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "#taskHeader == null ? '' : #taskHeader.getId()", bizType = "'任务追踪'", tag = "'空出处理'", extra = "''",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
         recordReturnValue = true)
     public Result emptyOutHandle(String taskNo) {
         if (StringUtils.isEmpty(taskNo)) {
@@ -601,7 +601,7 @@ public class WcsServiceImpl implements WcsService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "#taskHeader == null ? '' : #taskHeader.getId()", bizType = "'任务追踪'", tag = "'重入处理'", extra = "''",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
         recordReturnValue = true)
     public Result reentryHandle(String taskNo) {
         // 1、判断非空字段
@@ -708,7 +708,7 @@ public class WcsServiceImpl implements WcsService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "#taskHeader == null ? '' : #taskHeader.getId()", bizType = "'任务追踪'", tag = "'取货错处理'", extra = "''",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
         recordReturnValue = true)
     public Result pickupErrorHandle(String taskNo) {
         // 1、判断非空字段
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/locationMonitor/controller/LocationMonitorController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/locationMonitor/controller/LocationMonitorController.java
index d78ac45..9b4a7d1 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/locationMonitor/controller/LocationMonitorController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/locationMonitor/controller/LocationMonitorController.java
@@ -69,6 +69,7 @@ public class LocationMonitorController {
         // 换stream进行数据拣选速度更快
         List<Location> emptyLocationList =
             locationList.stream().filter(t -> QuantityConstant.STATUS_LOCATION_EMPTY.equals(t.getStatus())).collect(Collectors.toList());
+        emptyLocationList = emptyLocationList.stream().filter(t -> t.getContainerCode().isEmpty()).collect(Collectors.toList());
         map.put("emptyLocation", emptyLocationList.size());
         // 查询库位上的托盘信息
         LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
@@ -110,8 +111,7 @@ public class LocationMonitorController {
 
         /* 查询库存明细 */
         LambdaQueryWrapper<InventoryDetail> inventoryDetailLambda = Wrappers.lambdaQuery();
-        inventoryDetailLambda.eq(StringUtils.isEmpty(zoneCode),InventoryDetail::getZoneCode,zoneCode)
-                             .isNotNull(InventoryDetail::getLocationCode);
+        inventoryDetailLambda.eq(StringUtils.isEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode).isNotNull(InventoryDetail::getLocationCode);
         HuahengJwtUtil.setWarehouseCode(inventoryDetailLambda, InventoryDetail.class, req);
         List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambda);
 
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/IMaterialWarningService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/IMaterialWarningService.java
index 21bef47..f9470a7 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/IMaterialWarningService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/IMaterialWarningService.java
@@ -1,11 +1,8 @@
 package org.jeecg.modules.wms.config.materialWarning.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import org.jeecg.modules.wms.config.materialWarning.entity.MaterialLevelAlarm;
 import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
 
-import java.util.List;
-
 /**
  * @Description: 物料预警
  * @Author:      jeecg-boot
@@ -14,5 +11,4 @@ import java.util.List;
  */
 public interface IMaterialWarningService extends IService<MaterialWarning> {
 
-    List<MaterialLevelAlarm> getLevelAlarm(String materialCode);
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/impl/MaterialWarningServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/impl/MaterialWarningServiceImpl.java
index 0d11055..e80884a 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/impl/MaterialWarningServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/service/impl/MaterialWarningServiceImpl.java
@@ -1,24 +1,11 @@
 package org.jeecg.modules.wms.config.materialWarning.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import org.jeecg.modules.wms.config.materialWarning.entity.MaterialLevelAlarm;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
 import org.jeecg.modules.wms.config.materialWarning.mapper.MaterialWarningMapper;
 import org.jeecg.modules.wms.config.materialWarning.service.IMaterialWarningService;
-import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
-import org.jeecg.modules.wms.inventory.inventoryHeader.service.impl.InventoryDetailServiceImpl;
-import org.jeecg.utils.StringUtils;
-import org.jeecg.utils.constant.QuantityConstant;
 import org.springframework.stereotype.Service;
 
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-
-import javax.annotation.Resource;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
 /**
  * @Description: 物料预警
  * @Author: jeecg-boot
@@ -28,26 +15,4 @@ import java.util.stream.Collectors;
 @Service
 public class MaterialWarningServiceImpl extends ServiceImpl<MaterialWarningMapper, MaterialWarning> implements IMaterialWarningService {
 
-    @Resource
-    InventoryDetailServiceImpl inventoryDetailService;
-
-    @Override
-    public List<MaterialLevelAlarm> getLevelAlarm(String materialCode) {
-        LambdaQueryWrapper<MaterialWarning> query = new LambdaQueryWrapper<>();
-        query.eq(StringUtils.isNotEmpty(materialCode), MaterialWarning::getMaterialCode, materialCode);
-        List<MaterialWarning> warningList = list(query);
-
-        List<MaterialLevelAlarm> alarmList = new ArrayList<>();
-        warningList.forEach(w -> {
-            InventoryDetail d = new InventoryDetail();
-            d.setMaterialCode(w.getMaterialCode());
-            d.setCompanyCode(w.getCompanyCode());
-            d.setWarehouseCode(w.getWarehouseCode());
-            d.setInventoryStatus(QuantityConstant.QUALITY_GOOD);
-            BigDecimal sum = inventoryDetailService.getInventorySumQty(d);
-            alarmList.add(new MaterialLevelAlarm(w, sum));
-        });
-
-        return alarmList.stream().filter(MaterialLevelAlarm::needAlarm).collect(Collectors.toList());
-    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryDetail/controller/InventoryDetailController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryDetail/controller/InventoryDetailController.java
index b7b92e7..f2cfdb4 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryDetail/controller/InventoryDetailController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryDetail/controller/InventoryDetailController.java
@@ -7,18 +7,14 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
-import org.jeecg.modules.wms.config.container.entity.Container;
 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
 import org.jeecg.utils.HuahengJwtUtil;
 import org.jeecg.utils.StringUtils;
-import org.jeecg.utils.constant.QuantityConstant;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
@@ -67,7 +63,7 @@ public class InventoryDetailController extends JeecgController<InventoryDetail, 
         QueryWrapper<InventoryDetail> queryWrapper = QueryGenerator.initQueryWrapper(inventoryDetail, req.getParameterMap());
         queryWrapper.lt(inventoryAge != null, "create_time", inventoryAge);
         Page<InventoryDetail> page = new Page<InventoryDetail>(pageNo, pageSize);
-        IPage<InventoryDetail> pageList = inventoryDetailService.page(page, queryWrapper);
+        IPage<InventoryDetail> pageList = inventoryDetailService.queryPage(page, queryWrapper);
         inventoryDetailService.calculateInventoryAge(pageList.getRecords());// 计算库龄
         return Result.OK(pageList);
     }
@@ -75,17 +71,17 @@ public class InventoryDetailController extends JeecgController<InventoryDetail, 
     @ApiOperation(value = "库存详情-分页列表查询", notes = "库存详情-分页列表查询")
     @GetMapping(value = "/selectContainerlist")
     public Result<IPage<InventoryDetail>> selectContainerlist(InventoryDetail inventoryDetail, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
-                                                        @RequestParam(name = "pageSize", defaultValue = "5") Integer pageSize, HttpServletRequest req) {
-        IPage<InventoryDetail> pageList=new Page<>();
-        //由于前端页面嵌套,进页面就会加载此接口,加个判断避免不必要的查询
-        if (StringUtils.isNotEmpty(inventoryDetail.getMaterialCode())){
+        @RequestParam(name = "pageSize", defaultValue = "5") Integer pageSize, HttpServletRequest req) {
+        IPage<InventoryDetail> pageList = new Page<>();
+        // 由于前端页面嵌套,进页面就会加载此接口,加个判断避免不必要的查询
+        if (StringUtils.isNotEmpty(inventoryDetail.getMaterialCode())) {
             String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
-            //查询出符合条件的托盘
-            List<String> containerCodeList=inventoryDetailService.containerCodeList(warehouseCode,inventoryDetail.getMaterialCode());
+            // 查询出符合条件的托盘
+            List<String> containerCodeList = inventoryDetailService.containerCodeList(warehouseCode, inventoryDetail.getMaterialCode());
             QueryWrapper<InventoryDetail> queryWrapper = QueryGenerator.initQueryWrapper(inventoryDetail, req.getParameterMap());
             Page<InventoryDetail> page = new Page<InventoryDetail>(pageNo, pageSize);
-            if (containerCodeList.size()>0){
-                queryWrapper.in("container_code",containerCodeList);
+            if (containerCodeList.size() > 0) {
+                queryWrapper.in("container_code", containerCodeList);
             }
             pageList = inventoryDetailService.page(page, queryWrapper);
         }
@@ -180,7 +176,7 @@ public class InventoryDetailController extends JeecgController<InventoryDetail, 
     public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
         return super.importExcel(request, response, InventoryDetail.class);
     }
-    
+
     /**
      * 根据多个库存头id分页列表查询
      */
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/controller/InventoryLevelAlarmController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/controller/InventoryLevelAlarmController.java
new file mode 100644
index 0000000..f0c5fb5
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/controller/InventoryLevelAlarmController.java
@@ -0,0 +1,97 @@
+package org.jeecg.modules.wms.inventory.inventoryLevel.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.oss.entity.OSSFile;
+import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
+import org.jeecg.modules.wms.config.materialWarning.service.IMaterialWarningService;
+import org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm;
+import org.jeecg.modules.wms.inventory.inventoryLevel.service.IInventoryLevelAlarmService;
+import org.jeecg.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: inventory_level_alarm
+ * @Author: jeecg-boot
+ * @Date:   2023-10-30
+ * @Version: V1.0
+ */
+@Api(tags="inventory_level_alarm")
+@RestController
+@RequestMapping("/inventory/inventoryLevel")
+@Slf4j
+public class InventoryLevelAlarmController extends JeecgController<InventoryLevelAlarm, IInventoryLevelAlarmService> {
+	@Autowired
+	private IInventoryLevelAlarmService iInventoryLevelAlarmService;
+
+	@Autowired
+	private IMaterialWarningService iMaterialWarningService;
+	
+	/**
+	 * 分页列表查询
+	 *
+	 * @param inventoryLevelAlarm
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	//@AutoLog(value = "inventory_level_alarm-分页列表查询")
+	@ApiOperation(value="inventory_level_alarm-分页列表查询", notes="inventory_level_alarm-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<InventoryLevelAlarm>> queryPageList(String materialCode, String materialName, String alarmStatus,
+															@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+															@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+															HttpServletRequest req) {
+
+		Page<InventoryLevelAlarm> page = new Page<>(pageNo, pageSize);
+		IPage<InventoryLevelAlarm> pageList = iInventoryLevelAlarmService.queryLevelAlarm(page, materialCode, materialName, alarmStatus);
+		//对list分页处理
+		return Result.OK(pageList);
+	}
+
+
+	/**
+	 * 通过id查询
+	 *
+	 * @param id
+	 * @return
+	 */
+	//@AutoLog(value = "inventory_level_alarm-通过id查询")
+	@ApiOperation(value="inventory_level_alarm-通过id查询", notes="inventory_level_alarm-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<InventoryLevelAlarm> queryById(@RequestParam(name="id",required=true) String id) {
+		InventoryLevelAlarm inventoryLevelAlarm = iInventoryLevelAlarmService.getById(id);
+		if(inventoryLevelAlarm ==null) {
+			return Result.error("未找到对应数据");
+		}
+		return Result.OK(inventoryLevelAlarm);
+	}
+
+    /**
+    * 导出excel
+    *
+    * @param request
+    * @param inventoryLevelAlarm
+    */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, InventoryLevelAlarm inventoryLevelAlarm) {
+        return super.exportXls(request, inventoryLevelAlarm, InventoryLevelAlarm.class, "inventory_level_alarm");
+    }
+
+
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/entity/MaterialLevelAlarm.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/entity/InventoryLevelAlarm.java
index a22ae14..3304b98 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/materialWarning/entity/MaterialLevelAlarm.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/entity/InventoryLevelAlarm.java
@@ -1,61 +1,59 @@
-package org.jeecg.modules.wms.config.materialWarning.entity;
+package org.jeecg.modules.wms.inventory.inventoryLevel.entity;
 
 import lombok.Data;
+import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
 
 import java.math.BigDecimal;
 
 @Data
-public class MaterialLevelAlarm extends MaterialWarning {
+public class InventoryLevelAlarm extends MaterialWarning {
     private int qtySum;
-    //小于等于下线预警
-    private boolean inLower;
-    //小于等于上线预警
-    private boolean inUpper;
 
-    //小于等于最小值
-    private boolean inMin;
-    //大于等于最大值
-    private boolean inMax;
+    public InventoryLevelAlarm(){
+
+    }
 
     /**
-     * 构造预警数据
+     * 判断是否低于下限
      **/
-    public MaterialLevelAlarm(MaterialWarning warning, BigDecimal qtySum) {
-        org.springframework.beans.BeanUtils.copyProperties(warning, this);
-        this.qtySum = qtySum.intValue();
-        if (getLower() > 0) {
-            inLower = this.qtySum <= getLower();
-        }
-        if (getUpper() > 0) {
-            inUpper = this.qtySum >= getUpper();
-        }
+    public boolean inLower() {
+        return this.qtySum <= getLower();
+    }
 
-        if (getMin() > 0) {
-            inMin = this.qtySum <= getMin();
-        }
+    /**
+     * 判断是否高于上限
+     **/
+    public boolean inUpper(){
+        return this.qtySum >= getUpper();
+    }
 
-        if (getMax() > 0) {
-            inMax = this.qtySum >= getMax();
-        }
+    /** 判断是否低于最小值 **/
+    public boolean inMin(){
+        return this.qtySum <= getMin();
+    }
+
+    /** 判断是否高于最大值 **/
+    public boolean inMax(){
+        return this.qtySum >= getMax();
     }
 
     /**
      * 判断是否有预警
      **/
     public Boolean needAlarm() {
-        return inLower || inUpper || inMin || inMax;
+        return inLower() || inUpper() || inMin() || inMax();
     }
 
     @Override
     public String toString() {
         String str = "<ul>";
-        if (inLower) {
+        if (inLower()) {
             str = str +  "<li><b>" + getMaterialName() + "</b> &nbsp;&nbsp;" + getMaterialCode() + " 库存数 <b>" + getQtySum() + "</b>&nbsp;&nbsp;低于下限预警值<b> " + getLower() + "</b></li>";
-        } else if (inUpper) {
+        } else if (inUpper()) {
             str = str +  "<li><b>" + getMaterialName() + "</b> &nbsp;&nbsp;" + getMaterialCode() + " 库存数 <b>" + getQtySum() + "</b>&nbsp;&nbsp;高于上限预警值<b> " + getUpper() + "</b></li>";
-        } else if (inMin) {
+        } else if (inMin()) {
             str = str +  "<li><b>" + getMaterialName() + "</b> &nbsp;&nbsp;" + getMaterialCode() + " 库存数 <b>" + getQtySum() + "</b>&nbsp;&nbsp;低于最低值<b> " + getMin() + "</b></li>";
-        } else if (inMax) {
+        } else if (inMax()) {
             str = str +  "<li><b>" + getMaterialName() + "</b> &nbsp;&nbsp;" + getMaterialCode() + " 库存数 <b>" + getQtySum() + "</b>&nbsp;&nbsp;超过最高值<b> " + getMax() + "</b></li>";
         }
         return str + "</ul>";
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/InventoryLevelAlarmMapper.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/InventoryLevelAlarmMapper.java
new file mode 100644
index 0000000..d0feada
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/InventoryLevelAlarmMapper.java
@@ -0,0 +1,25 @@
+package org.jeecg.modules.wms.inventory.inventoryLevel.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm;
+
+import java.util.List;
+
+/**
+ * @Description: material_level_alarm
+ * @Author: jeecg-boot
+ * @Date:   2023-10-30
+ * @Version: V1.0
+ */
+public interface InventoryLevelAlarmMapper extends BaseMapper<InventoryLevelAlarm> {
+    IPage<InventoryLevelAlarm> queryLevelAlarm(IPage<InventoryLevelAlarm> page,
+                                              @Param("materialCode") String materialCode,
+                                              @Param("materialName") String materialName,
+                                              @Param("alarmStatus") String alarmStatus);
+
+    List<InventoryLevelAlarm> queryLevelAlarm(@Param("materialCode") String materialCode,
+                                              @Param("materialName") String materialName,
+                                              @Param("alarmStatus") String alarmStatus);
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/xml/InventoryLevelAlarmMapper.xml b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/xml/InventoryLevelAlarmMapper.xml
new file mode 100644
index 0000000..090dec6
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/mapper/xml/InventoryLevelAlarmMapper.xml
@@ -0,0 +1,34 @@
+<?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="org.jeecg.modules.wms.inventory.inventoryLevel.mapper.InventoryLevelAlarmMapper">
+
+    <select id="queryLevelAlarm"
+            resultType="org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm">
+        select w.*, i.qtySum from (
+        SELECT material_code, sum(qty) as qtySum FROM inventory_detail
+        WHERE inventory_status='good' and material_code IN ( SELECT material_code FROM material_warning)
+        group by material_code
+        ) i right join material_warning w on i.material_code = w.material_code
+        <where>
+            <if test="materialCode != null and materialCode != ''">
+                and w.material_code = #{materialCode}
+            </if>
+            <if test="materialName != null and materialName != ''">
+                <bind name="materialNameLike" value="'%'+materialName+'%'"/>
+                and w.material_name like #{materialNameLike}
+            </if>
+            <if test="alarmStatus != null and alarmStatus == 'noAlarm'">
+                and qtySum &gt; lower and qtySum &lt; upper
+            </if>
+            <if test="alarmStatus != null and alarmStatus == 'isAlarm'">
+                and (qtySum &lt;= lower or qtySum &gt;= upper or qtySum is null)
+            </if>
+            <if test="alarmStatus != null and alarmStatus == 'lowerAlarm'">
+                and (qtySum &lt;= lower or qtySum is null)
+            </if>
+            <if test="alarmStatus != null and alarmStatus == 'upperAlarm'">
+                and qtySum &gt;= upper
+            </if>
+        </where>
+    </select>
+</mapper>
\ No newline at end of file
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/IInventoryLevelAlarmService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/IInventoryLevelAlarmService.java
new file mode 100644
index 0000000..fd4b3fd
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/IInventoryLevelAlarmService.java
@@ -0,0 +1,21 @@
+package org.jeecg.modules.wms.inventory.inventoryLevel.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
+import org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm;
+
+import java.util.List;
+
+/**
+ * @Description: inventory_level_alarm
+ * @Author: jeecg-boot
+ * @Date:   2023-10-30
+ * @Version: V1.0
+ */
+public interface IInventoryLevelAlarmService extends IService<InventoryLevelAlarm> {
+    List<InventoryLevelAlarm> getLevelAlarm(String materialCode);
+
+    IPage<InventoryLevelAlarm> queryLevelAlarm(IPage<InventoryLevelAlarm> page, String materialCode, String materialName, String alarmStatus);
+
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/impl/InventoryLevelAlarmServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/impl/InventoryLevelAlarmServiceImpl.java
new file mode 100644
index 0000000..63ec826
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryLevel/service/impl/InventoryLevelAlarmServiceImpl.java
@@ -0,0 +1,54 @@
+package org.jeecg.modules.wms.inventory.inventoryLevel.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.wms.config.materialWarning.entity.MaterialWarning;
+import org.jeecg.modules.wms.config.materialWarning.service.impl.MaterialWarningServiceImpl;
+import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
+import org.jeecg.modules.wms.inventory.inventoryHeader.service.impl.InventoryDetailServiceImpl;
+import org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm;
+import org.jeecg.modules.wms.inventory.inventoryLevel.mapper.InventoryLevelAlarmMapper;
+import org.jeecg.modules.wms.inventory.inventoryLevel.service.IInventoryLevelAlarmService;
+import org.jeecg.utils.StringUtils;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: inventory_level_alarm
+ * @Author: jeecg-boot
+ * @Date: 2023-10-30
+ * @Version: V1.0
+ */
+@Service
+public class InventoryLevelAlarmServiceImpl extends ServiceImpl<InventoryLevelAlarmMapper, InventoryLevelAlarm> implements IInventoryLevelAlarmService {
+
+    @Resource
+    InventoryDetailServiceImpl inventoryDetailService;
+
+    @Resource
+    MaterialWarningServiceImpl materialWarningService;
+
+    @Resource
+    InventoryLevelAlarmMapper inventoryLevelAlarmMapper;
+
+    @Override
+    public List<InventoryLevelAlarm> getLevelAlarm(String materialCode) {
+        List<InventoryLevelAlarm> alarmList = inventoryLevelAlarmMapper.queryLevelAlarm(materialCode,null,"isAlarm");
+
+        return alarmList;
+    }
+
+
+    @Override
+    public IPage<InventoryLevelAlarm> queryLevelAlarm(IPage<InventoryLevelAlarm> page, String materialCode, String materialName, String alarmStatus) {
+        return inventoryLevelAlarmMapper.queryLevelAlarm(page, materialCode, materialName, alarmStatus);
+    }
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/MaterialLevelAlarmTask.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/InventoryLevelAlarmTask.java
index 031af70..f4f6048 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/MaterialLevelAlarmTask.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/monitor/job/InventoryLevelAlarmTask.java
@@ -11,14 +11,12 @@ import org.jeecg.modules.system.entity.SysUser;
 import org.jeecg.modules.system.service.impl.SysAnnouncementServiceImpl;
 import org.jeecg.modules.system.service.impl.SysRoleServiceImpl;
 import org.jeecg.modules.system.service.impl.SysUserServiceImpl;
-import org.jeecg.modules.wms.config.materialWarning.entity.MaterialLevelAlarm;
-import org.jeecg.modules.wms.config.materialWarning.service.impl.MaterialWarningServiceImpl;
+import org.jeecg.modules.wms.inventory.inventoryLevel.entity.InventoryLevelAlarm;
+import org.jeecg.modules.wms.inventory.inventoryLevel.service.impl.InventoryLevelAlarmServiceImpl;
 import org.quartz.*;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -31,7 +29,7 @@ import java.util.stream.Collectors;
 @Slf4j
 @PersistJobDataAfterExecution
 @DisallowConcurrentExecution
-public class MaterialLevelAlarmTask implements Job {
+public class InventoryLevelAlarmTask implements Job {
     private String parameter;
 
     @Resource
@@ -43,14 +41,14 @@ public class MaterialLevelAlarmTask implements Job {
     @Resource
     private SysRoleServiceImpl sysRoleService;
 
-    @Autowired
+    @Resource
     private SqlSession sqlSession;
 
-    @Autowired
+    @Resource
     private SysAnnouncementServiceImpl sysAnnouncementService;
 
-    @Autowired
-    private MaterialWarningServiceImpl materialWarningService;
+    @Resource
+    private InventoryLevelAlarmServiceImpl inventoryLevelAlarmService;
 
     public void setParameter(String parameter) {
         this.parameter = parameter;
@@ -60,13 +58,15 @@ public class MaterialLevelAlarmTask implements Job {
     public void execute(JobExecutionContext context) throws JobExecutionException {
         log.info(StrUtil.format("定时任务 MaterialLevelAlarmTask 参数:{},执行时间:{}", this.parameter, DateUtils.getTimestamp()));
 
-        List<MaterialLevelAlarm> alarmList = materialWarningService.getLevelAlarm(null);
+        List<InventoryLevelAlarm> alarmList = inventoryLevelAlarmService.getLevelAlarm(null);
         if (CollectionUtils.isEmpty(alarmList)) {
             return;
         }
 
-        List<String> list = alarmList.stream().map(MaterialLevelAlarm::toString).collect(Collectors.toList());
+        List<String> list = alarmList.stream().map(InventoryLevelAlarm::toString).collect(Collectors.toList());
         String msg = String.join("\n", list);
+        msg = msg + "<a href='/wms/index.html#/system/inventory/inventoryLevel'>点击查看详情</a>";
+//                "&nbsp;&nbsp;&nbsp;&nbsp;<a href='/wms/index.html#/system/config/MaterialWarningList'>预警配置</a>";
 
         List<SysUser> userList;
         try {
@@ -75,7 +75,7 @@ public class MaterialLevelAlarmTask implements Job {
             if (userList.size() == 0) {
                 userList = null;
             }
-            sysAnnouncementService.quickAnnouncementToUser(userList, "物料水位预警", msg, DateUtil.offsetDay(new Date(), 1), "H");
+            sysAnnouncementService.quickAnnouncementToUser(userList, "库存水位预警", msg, DateUtil.offsetDay(new Date(), 1), "H");
         } catch (Exception e) {
             log.error("获取预警通知用户出错", e);
         }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityHeaderController.java
new file mode 100644
index 0000000..cd5fc93
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityHeaderController.java
@@ -0,0 +1,319 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.controller;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityHeader;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityHeaderService;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: 质检表单头
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+@Api(tags = "质检表单头")
+@RestController
+@RequestMapping("/receipt/qualityHeader")
+@Slf4j
+public class QualityHeaderController extends JeecgController<QualityHeader, IQualityHeaderService> {
+
+    @Autowired
+    private IQualityHeaderService qualityHeaderService;
+
+    @Autowired
+    private IQualityDetailService qualityDetailService;
+
+    /*---------------------------------主表处理-begin-------------------------------------*/
+
+    /**
+     * 分页列表查询
+     * @param  qualityHeader
+     * @param  pageNo
+     * @param  pageSize
+     * @param  req
+     * @return
+     */
+    // @AutoLog(value = "质检表单头-分页列表查询")
+    @ApiOperation(value = "质检表单头-分页列表查询", notes = "质检表单头-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<QualityHeader>> queryPageList(QualityHeader qualityHeader, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
+        QueryWrapper<QualityHeader> queryWrapper = QueryGenerator.initQueryWrapper(qualityHeader, req.getParameterMap());
+        Page<QualityHeader> page = new Page<QualityHeader>(pageNo, pageSize);
+        IPage<QualityHeader> pageList = qualityHeaderService.page(page, queryWrapper);
+        return Result.OK(pageList);
+    }
+
+    /**
+     * 添加
+     * @param  qualityHeader
+     * @return
+     */
+    @AutoLog(value = "质检表单头-添加")
+    @ApiOperation(value = "质检表单头-添加", notes = "质检表单头-添加")
+    @PostMapping(value = "/add")
+    public Result<String> add(@RequestBody QualityHeader qualityHeader) {
+        qualityHeaderService.save(qualityHeader);
+        return Result.OK("添加成功!");
+    }
+
+    /**
+     * 编辑
+     * @param  qualityHeader
+     * @return
+     */
+    @AutoLog(value = "质检表单头-编辑")
+    @ApiOperation(value = "质检表单头-编辑", notes = "质检表单头-编辑")
+    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
+    public Result<String> edit(@RequestBody QualityHeader qualityHeader) {
+        if (qualityHeader.getFirstStatus().intValue() > QuantityConstant.QUALITY_HEADER_BUILD) {
+            throw new JeecgBootException("不能删除非新建状态单据");
+        }
+        qualityHeaderService.updateById(qualityHeader);
+        return Result.OK("编辑成功!");
+    }
+
+    /**
+     * 通过id删除
+     * @param  id
+     * @return
+     */
+    @AutoLog(value = "质检表单头-通过id删除")
+    @ApiOperation(value = "质检表单头-通过id删除", notes = "质检表单头-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
+        QualityHeader qualityHeader = qualityHeaderService.getById(id);
+        if (qualityHeader.getFirstStatus().intValue() > QuantityConstant.QUALITY_HEADER_BUILD) {
+            throw new JeecgBootException("不能删除非新建状态单据");
+        }
+        qualityHeaderService.delMain(id);
+        return Result.OK("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     * @param  ids
+     * @return
+     */
+    @AutoLog(value = "质检表单头-批量删除")
+    @ApiOperation(value = "质检表单头-批量删除", notes = "质检表单头-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        this.qualityHeaderService.delBatchMain(Arrays.asList(ids.split(",")));
+        return Result.OK("批量删除成功!");
+    }
+
+    /**
+     * 导出
+     * @return
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, QualityHeader qualityHeader) {
+        return super.exportXls(request, qualityHeader, QualityHeader.class, "质检表单头");
+    }
+
+    /**
+     * 导入
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        return super.importExcel(request, response, QualityHeader.class);
+    }
+    /*---------------------------------主表处理-end-------------------------------------*/
+
+    /*--------------------------------子表处理-质检单详情-begin----------------------------------------------*/
+    /**
+     * 通过主表ID查询
+     * @return
+     */
+    // @AutoLog(value = "质检单详情-通过主表ID查询")
+    @ApiOperation(value = "质检单详情-通过主表ID查询", notes = "质检单详情-通过主表ID查询")
+    @GetMapping(value = "/listQualityDetailByMainId")
+    public Result<IPage<QualityDetail>> listQualityDetailByMainId(QualityDetail qualityDetail, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
+        QueryWrapper<QualityDetail> queryWrapper = QueryGenerator.initQueryWrapper(qualityDetail, req.getParameterMap());
+        Page<QualityDetail> page = new Page<QualityDetail>(pageNo, pageSize);
+        IPage<QualityDetail> pageList = qualityDetailService.page(page, queryWrapper);
+        return Result.OK(pageList);
+    }
+
+    /**
+     * 添加
+     * @param  qualityDetail
+     * @return
+     */
+    @AutoLog(value = "质检单详情-添加")
+    @ApiOperation(value = "质检单详情-添加", notes = "质检单详情-添加")
+    @PostMapping(value = "/addQualityDetail")
+    public Result<String> addQualityDetail(@RequestBody QualityDetail qualityDetail) {
+
+        qualityDetailService.save(qualityDetail);
+        return Result.OK("添加成功!");
+    }
+
+    /**
+     * 编辑
+     * @param  qualityDetail
+     * @return
+     */
+    @AutoLog(value = "质检单详情-编辑")
+    @ApiOperation(value = "质检单详情-编辑", notes = "质检单详情-编辑")
+    @RequestMapping(value = "/editQualityDetail", method = {RequestMethod.PUT, RequestMethod.POST})
+    public Result<String> editQualityDetail(@RequestBody QualityDetail qualityDetail) {
+        if (qualityDetail.getStatus().intValue() > QuantityConstant.QUALITY_HEADER_BUILD) {
+            throw new JeecgBootException("不能添加非新建状态单据");
+        }
+        qualityDetailService.updateById(qualityDetail);
+        return Result.OK("编辑成功!");
+    }
+
+    /**
+     * 通过id删除
+     * @param  id
+     * @return
+     */
+    @AutoLog(value = "质检单详情-通过id删除")
+    @ApiOperation(value = "质检单详情-通过id删除", notes = "质检单详情-通过id删除")
+    @DeleteMapping(value = "/deleteQualityDetail")
+    public Result<String> deleteQualityDetail(@RequestParam(name = "id", required = true) String id) {
+        QualityDetail qualityDetail = qualityDetailService.getById(id);
+        if (qualityDetail.getStatus().intValue() > QuantityConstant.QUALITY_HEADER_BUILD) {
+            throw new JeecgBootException("不能添加非新建状态单据");
+        }
+        qualityDetailService.removeById(id);
+        return Result.OK("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     * @param  ids
+     * @return
+     */
+    @AutoLog(value = "质检单详情-批量删除")
+    @ApiOperation(value = "质检单详情-批量删除", notes = "质检单详情-批量删除")
+    @DeleteMapping(value = "/deleteBatchQualityDetail")
+    public Result<String> deleteBatchQualityDetail(@RequestParam(name = "ids", required = true) String ids) {
+        this.qualityDetailService.removeByIds(Arrays.asList(ids.split(",")));
+        return Result.OK("批量删除成功!");
+    }
+
+    /**
+     * 导出
+     * @return
+     */
+    @RequestMapping(value = "/exportQualityDetail")
+    public ModelAndView exportQualityDetail(HttpServletRequest request, QualityDetail qualityDetail) {
+        // Step.1 组装查询条件
+        QueryWrapper<QualityDetail> queryWrapper = QueryGenerator.initQueryWrapper(qualityDetail, request.getParameterMap());
+        LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
+
+        // Step.2 获取导出数据
+        List<QualityDetail> pageList = qualityDetailService.list(queryWrapper);
+        List<QualityDetail> exportList = null;
+
+        // 过滤选中数据
+        String selections = request.getParameter("selections");
+        if (oConvertUtils.isNotEmpty(selections)) {
+            List<String> selectionList = Arrays.asList(selections.split(","));
+            exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
+        } else {
+            exportList = pageList;
+        }
+
+        // Step.3 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        mv.addObject(NormalExcelConstants.FILE_NAME, "质检单详情"); // 此处设置的filename无效 ,前端会重更新设置一下
+        mv.addObject(NormalExcelConstants.CLASS, QualityDetail.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("质检单详情报表", "导出人:" + sysUser.getRealname(), "质检单详情"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
+        return mv;
+    }
+
+    /**
+     * 导入
+     * @return
+     */
+    @RequestMapping(value = "/importQualityDetail/{mainId}")
+    public Result<?> importQualityDetail(HttpServletRequest request, HttpServletResponse response, @PathVariable("mainId") Integer mainId) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();// 获取上传文件对象
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<QualityDetail> list = ExcelImportUtil.importExcel(file.getInputStream(), QualityDetail.class, params);
+                for (QualityDetail temp : list) {
+                    temp.setQualityId(mainId);
+                }
+                long start = System.currentTimeMillis();
+                qualityDetailService.saveBatch(list);
+                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
+                return Result.OK("文件导入成功!数据行数:" + list.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.error("文件导入失败!");
+    }
+
+    /*--------------------------------子表处理-质检单详情-end----------------------------------------------*/
+
+    /**
+     * 质检
+     * @param  qualityDetail
+     * @return
+     */
+    @AutoLog(value = "质检单详情-质检")
+    @ApiOperation(value = "质检单详情-质检", notes = "质检单详情-质检")
+    @RequestMapping(value = "/qualityTesting", method = {RequestMethod.PUT, RequestMethod.POST})
+    public Result<String> qualityTesting(@RequestBody QualityDetail qualityDetail) {
+        return qualityDetailService.qualityTesting(qualityDetail);
+    }
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java
new file mode 100644
index 0000000..cccd257
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java
@@ -0,0 +1,144 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.entity;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description: 质检单详情
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+@Data
+@TableName("quality_detail")
+@ApiModel(value = "quality_detail对象", description = "质检单详情")
+public class QualityDetail implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private java.lang.Integer id;
+    /** 质检单id */
+    @ApiModelProperty(value = "质检单id")
+    private java.lang.Integer qualityId;
+    /** 质检单号 */
+    @Excel(name = "质检单号", width = 15)
+    @ApiModelProperty(value = "质检单号")
+    private java.lang.String qualityCode;
+    /** 仓库编码 */
+    @Excel(name = "仓库编码", width = 15)
+    @ApiModelProperty(value = "仓库编码")
+    private java.lang.String warehouseCode;
+    /** 货主编码 */
+    @Excel(name = "货主编码", width = 15)
+    @ApiModelProperty(value = "货主编码")
+    private java.lang.String companyCode;
+    /** 物料编码 */
+    @Excel(name = "物料编码", width = 15)
+    @ApiModelProperty(value = "物料编码")
+    private java.lang.String materialCode;
+    /** 物料名称 */
+    @Excel(name = "物料名称", width = 15)
+    @ApiModelProperty(value = "物料名称")
+    private java.lang.String materialName;
+    /** 物料规格 */
+    @Excel(name = "物料规格", width = 15)
+    @ApiModelProperty(value = "物料规格")
+    private java.lang.String materialSpec;
+    /** 物料单位 */
+    @Excel(name = "物料单位", width = 15)
+    @ApiModelProperty(value = "物料单位")
+    private java.lang.String materialUnit;
+    /** 单据数量 */
+    @Excel(name = "单据数量", width = 15)
+    @ApiModelProperty(value = "单据数量")
+    private BigDecimal qty;
+    /** 合格数量 */
+    @Excel(name = "合格数量", width = 15)
+    @ApiModelProperty(value = "合格数量")
+    private BigDecimal qualityfiedQty;
+    /** 不合格数量 */
+    @Excel(name = "不合格数量", width = 15)
+    @ApiModelProperty(value = "不合格数量")
+    private BigDecimal unqualityfiedQty;
+    /** 不合格原因 */
+    @Excel(name = "不合格原因", width = 15)
+    @ApiModelProperty(value = "不合格原因")
+    private java.lang.String remark;
+    /** 库存状态 */
+    @Excel(name = "库存状态", width = 15)
+    @ApiModelProperty(value = "库存状态")
+    @Dict(dicCode = "inventory_status")
+    private java.lang.String inventoryStatus;
+    /** 批次 */
+    @Excel(name = "批次", width = 15)
+    @ApiModelProperty(value = "批次")
+    private java.lang.String batch;
+    /** 批号 */
+    @Excel(name = "批号", width = 15)
+    @ApiModelProperty(value = "批号")
+    private java.lang.String lot;
+    /** 项目号 */
+    @Excel(name = "项目号", width = 15)
+    @ApiModelProperty(value = "项目号")
+    private java.lang.String project;
+    /** 单据状态 */
+    @Excel(name = "单据状态", width = 15)
+    @ApiModelProperty(value = "单据状态")
+    @Dict(dicCode = "quality_header_status")
+    private java.lang.Integer status;
+    /** 上游单号 */
+    @Excel(name = "上游单号", width = 15)
+    @ApiModelProperty(value = "上游单号")
+    private java.lang.String referCode;
+    /** 上游行号 */
+    @Excel(name = "上游行号", width = 15)
+    @ApiModelProperty(value = "上游行号")
+    private java.lang.Integer referLineNum;
+    /** 创建人 */
+    @ApiModelProperty(value = "创建人")
+    private java.lang.String createBy;
+    /** 创建日期 */
+    @ApiModelProperty(value = "创建日期")
+    private java.util.Date createTime;
+    /** 更新人 */
+    @ApiModelProperty(value = "更新人")
+    private java.lang.String updateBy;
+    /** 更新日期 */
+    @ApiModelProperty(value = "更新日期")
+    private java.util.Date updateTime;
+
+    public void setQty(BigDecimal qty) {
+        if (qty.compareTo(BigDecimal.ZERO) < 0) {
+            throw new JeecgBootException("质检单据数量不能小于0");
+        }
+        this.qty = qty;
+    }
+
+    public void setQualityfiedQty(BigDecimal qualityfiedQty) {
+        if (qualityfiedQty.compareTo(BigDecimal.ZERO) < 0) {
+            throw new JeecgBootException("质检合格数量不能小于0");
+        }
+        this.qualityfiedQty = qualityfiedQty;
+    }
+
+    public void setUnqualityfiedQty(BigDecimal unqualityfiedQty) {
+        if (unqualityfiedQty.compareTo(BigDecimal.ZERO) < 0) {
+            throw new JeecgBootException("质检不合格数量不能小于0");
+        }
+        this.unqualityfiedQty = unqualityfiedQty;
+    }
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityHeader.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityHeader.java
new file mode 100644
index 0000000..ed473bd
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityHeader.java
@@ -0,0 +1,91 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.entity;
+
+import java.io.Serializable;
+
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description: 质检表单头
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+@Data
+@TableName("quality_header")
+@ApiModel(value = "quality_header对象", description = "质检表单头")
+public class QualityHeader implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private java.lang.Integer id;
+    /** 编码 */
+    @Excel(name = "编码", width = 15)
+    @ApiModelProperty(value = "编码")
+    private java.lang.String code;
+    /** 类型 */
+    @Excel(name = "类型", width = 15)
+    @ApiModelProperty(value = "类型")
+    @Dict(dicCode = "quality_type")
+    private java.lang.String type;
+    /** 仓库编码 */
+    @Excel(name = "仓库编码", width = 15)
+    @ApiModelProperty(value = "仓库编码")
+    private java.lang.String warehouseCode;
+    /** 货主编码 */
+    @Excel(name = "货主编码", width = 15)
+    @ApiModelProperty(value = "货主编码")
+    private java.lang.String companyCode;
+    /** 头状态 */
+    @Excel(name = "头状态", width = 15)
+    @ApiModelProperty(value = "头状态")
+    @Dict(dicCode = "quality_header_status")
+    private java.lang.Integer firstStatus;
+    /** 尾状态 */
+    @Excel(name = "尾状态", width = 15)
+    @ApiModelProperty(value = "尾状态")
+    @Dict(dicCode = "quality_header_status")
+    private java.lang.Integer lastStatus;
+    /** 上游单号 */
+    @Excel(name = "上游单号", width = 15)
+    @ApiModelProperty(value = "上游单号")
+    private java.lang.String referCode;
+    /** 供应商编码 */
+    @Excel(name = "供应商编码", width = 15)
+    @ApiModelProperty(value = "供应商编码")
+    private java.lang.String supplierCode;
+    /** 总数量 */
+    @Excel(name = "总数量", width = 15)
+    @ApiModelProperty(value = "总数量")
+    private java.math.BigDecimal totalQty;
+    /** 总行数 */
+    @Excel(name = "总行数", width = 15)
+    @ApiModelProperty(value = "总行数")
+    private java.lang.Integer totalLines;
+    /** 备注 */
+    @Excel(name = "备注", width = 15)
+    @ApiModelProperty(value = "备注")
+    private java.lang.String remark;
+    /** 创建人 */
+    @ApiModelProperty(value = "创建人")
+    private java.lang.String createBy;
+    /** 创建日期 */
+    @ApiModelProperty(value = "创建日期")
+    private java.util.Date createTime;
+    /** 更新人 */
+    @ApiModelProperty(value = "更新人")
+    private java.lang.String updateBy;
+    /** 更新日期 */
+    @ApiModelProperty(value = "更新日期")
+    private java.util.Date updateTime;
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityDetailMapper.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityDetailMapper.java
new file mode 100644
index 0000000..1ec662e
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityDetailMapper.java
@@ -0,0 +1,22 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 质检单详情
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+public interface QualityDetailMapper extends BaseMapper<QualityDetail> {
+
+    public boolean deleteByMainId(@Param("mainId") String mainId);
+
+    public List<QualityDetail> selectByMainId(@Param("mainId") String mainId);
+
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityHeaderMapper.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityHeaderMapper.java
new file mode 100644
index 0000000..8256d67
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/QualityHeaderMapper.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityHeader;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Description: 质检表单头
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+public interface QualityHeaderMapper extends BaseMapper<QualityHeader> {
+
+    @Select("select r.code from quality_header r where r.type = #{qualityType}  order by r.code desc limit 1")
+    QualityHeader getMaxQualityHeaderCode(@Param("qualityType") String qualityType);
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityDetailMapper.xml b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityDetailMapper.xml
new file mode 100644
index 0000000..7e75c08
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityDetailMapper.xml
@@ -0,0 +1,18 @@
+<?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="org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityDetailMapper">
+
+    <delete id="deleteByMainId" parameterType="java.lang.String">
+        DELETE
+        FROM quality_detail
+        WHERE quality_id = #{mainId}
+    </delete>
+
+    <select id="selectByMainId" parameterType="java.lang.String"
+            resultType="org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityDetailMapper">
+        SELECT *
+        FROM quality_detail
+        WHERE quality_id = #{mainId}
+    </select>
+
+</mapper>
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityHeaderMapper.xml b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityHeaderMapper.xml
new file mode 100644
index 0000000..ad7d67d
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/mapper/xml/QualityHeaderMapper.xml
@@ -0,0 +1,5 @@
+<?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="org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityHeaderMapper">
+
+</mapper>
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityDetailService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityDetailService.java
new file mode 100644
index 0000000..594a005
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityDetailService.java
@@ -0,0 +1,32 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.service;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: 质检单详情
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+public interface IQualityDetailService extends IService<QualityDetail> {
+
+    public List<QualityDetail> selectByMainId(String mainId);
+
+    /**
+     * 质检
+     * @return
+     */
+    Result qualityTesting(QualityDetail qualityDetail);
+
+    /**
+     * 更新质检信息
+     * @return
+     */
+    boolean updateQualityById(BigDecimal qualityfiedQty, BigDecimal unqualityfiedQty, int id);
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityHeaderService.java
new file mode 100644
index 0000000..181841f
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/IQualityHeaderService.java
@@ -0,0 +1,35 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.service;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityHeader;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: 质检表单头
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+public interface IQualityHeaderService extends IService<QualityHeader> {
+
+    /**
+     * 删除一对多
+     */
+    public void delMain(String id);
+
+    /**
+     * 批量删除一对多
+     */
+    public void delBatchMain(Collection<? extends Serializable> idList);
+
+    QualityHeader getQualityHeaderByReferCode(String referCode, String warehouseCode);
+
+    String createQualityCode(String qualityType);
+
+    boolean updateQualityHeader(Integer id);
+
+    boolean updateQualityHeaderStatus(Integer id);
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityDetailServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityDetailServiceImpl.java
new file mode 100644
index 0000000..feed265
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityDetailServiceImpl.java
@@ -0,0 +1,127 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.service.impl;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction;
+import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTransactionService;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+import org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityDetailMapper;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityHeaderService;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 质检单详情
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+@Service
+public class QualityDetailServiceImpl extends ServiceImpl<QualityDetailMapper, QualityDetail> implements IQualityDetailService {
+
+    @Autowired
+    private QualityDetailMapper qualityDetailMapper;
+    @Resource
+    private IQualityDetailService qualityDetailService;
+    @Resource
+    private IQualityHeaderService qualityHeaderService;
+    @Resource
+    private IInventoryTransactionService inventoryTransactionService;
+
+    @Override
+    public List<QualityDetail> selectByMainId(String mainId) {
+        return qualityDetailMapper.selectByMainId(mainId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result qualityTesting(QualityDetail qualityDetail) {
+        if (qualityDetail == null) {
+            return Result.error("质检失败, 质检数据为空");
+        }
+        if (qualityDetail.getStatus().intValue() == QuantityConstant.QUALITY_HEADER_COMPLETE) {
+            return Result.error("质检失败, 已经质检完成");
+        }
+        BigDecimal qty = qualityDetail.getQty();
+        BigDecimal qualityfiedQty = qualityDetail.getQualityfiedQty();
+        BigDecimal unqualityfiedQty = qualityDetail.getUnqualityfiedQty();
+        BigDecimal totalQty = qualityfiedQty.add(unqualityfiedQty);
+        if (qty.compareTo(totalQty) != 0) {
+            return Result.error("质检失败, 质检总数应该等于单据数量");
+        }
+        QualityDetail qualityDetail1 = new QualityDetail();
+        qualityDetail1.setId(qualityDetail.getId());
+        qualityDetail1.setQualityfiedQty(qualityfiedQty);
+        qualityDetail1.setUnqualityfiedQty(unqualityfiedQty);
+        qualityDetail1.setRemark(qualityDetail.getRemark());
+        qualityDetail1.setStatus(QuantityConstant.QUALITY_HEADER_COMPLETE);
+        if (!qualityDetailService.updateById(qualityDetail1)) {
+            throw new JeecgBootException("质检失败,更新质检数据失败");
+        }
+
+        if (!qualityHeaderService.updateQualityHeaderStatus(qualityDetail.getQualityId())) {
+            throw new JeecgBootException("质检失败,更新质检状态失败");
+        }
+
+        List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
+        if (qualityfiedQty.compareTo(BigDecimal.ZERO) > 0) {
+            InventoryTransaction inventoryTransaction = new InventoryTransaction();
+            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_QUALITY);
+            inventoryTransaction.setWarehouseCode(qualityDetail.getWarehouseCode());
+            inventoryTransaction.setCompanyCode(qualityDetail.getCompanyCode());
+            inventoryTransaction.setReceiptCode(qualityDetail.getQualityCode());
+            inventoryTransaction.setMaterialCode(qualityDetail.getMaterialCode());
+            inventoryTransaction.setMaterialName(qualityDetail.getMaterialName());
+            inventoryTransaction.setMaterialSpec(qualityDetail.getMaterialSpec());
+            inventoryTransaction.setMaterialUnit(qualityDetail.getMaterialUnit());
+            inventoryTransaction.setBatch(qualityDetail.getBatch());
+            inventoryTransaction.setLot(qualityDetail.getLot());
+            inventoryTransaction.setProject(qualityDetail.getProject());
+            inventoryTransaction.setInventoryStatus(QuantityConstant.QUALITY_GOOD);
+            inventoryTransaction.setQty(qualityfiedQty);
+            inventoryTransactionList.add(inventoryTransaction);
+        }
+        if (unqualityfiedQty.compareTo(BigDecimal.ZERO) > 0) {
+            InventoryTransaction inventoryTransaction = new InventoryTransaction();
+            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_QUALITY);
+            inventoryTransaction.setWarehouseCode(qualityDetail.getWarehouseCode());
+            inventoryTransaction.setCompanyCode(qualityDetail.getCompanyCode());
+            inventoryTransaction.setReceiptCode(qualityDetail.getQualityCode());
+            inventoryTransaction.setMaterialCode(qualityDetail.getMaterialCode());
+            inventoryTransaction.setMaterialName(qualityDetail.getMaterialName());
+            inventoryTransaction.setMaterialSpec(qualityDetail.getMaterialSpec());
+            inventoryTransaction.setMaterialUnit(qualityDetail.getMaterialUnit());
+            inventoryTransaction.setBatch(qualityDetail.getBatch());
+            inventoryTransaction.setLot(qualityDetail.getLot());
+            inventoryTransaction.setProject(qualityDetail.getProject());
+            inventoryTransaction.setInventoryStatus(QuantityConstant.QUALITY_DEFECTIVE);
+            inventoryTransaction.setQty(unqualityfiedQty);
+            inventoryTransactionList.add(inventoryTransaction);
+        }
+        if (!inventoryTransactionService.saveBatch(inventoryTransactionList)) {
+            throw new JeecgBootException("质检失败,增加库存交易记录失败");
+        }
+        return Result.ok("质检成功");
+    }
+
+    @Override
+    public boolean updateQualityById(BigDecimal qualityfiedQty, BigDecimal unqualityfiedQty, int id) {
+        QualityDetail qualityDetail = new QualityDetail();
+        qualityDetail.setId(id);
+        qualityDetail.setQualityfiedQty(qualityfiedQty);
+        qualityDetail.setUnqualityfiedQty(unqualityfiedQty);
+        return updateById(qualityDetail);
+    }
+
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityHeaderServiceImpl.java
new file mode 100644
index 0000000..9f93442
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/service/impl/QualityHeaderServiceImpl.java
@@ -0,0 +1,161 @@
+package org.jeecg.modules.wms.receipt.qualityHeader.service.impl;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityHeader;
+import org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityDetailMapper;
+import org.jeecg.modules.wms.receipt.qualityHeader.mapper.QualityHeaderMapper;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityHeaderService;
+import org.jeecg.utils.constant.QuantityConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @Description: 质检表单头
+ * @Author:      jeecg-boot
+ * @Date:        2023-10-24
+ * @Version:     V1.0
+ */
+@Service
+public class QualityHeaderServiceImpl extends ServiceImpl<QualityHeaderMapper, QualityHeader> implements IQualityHeaderService {
+
+    @Autowired
+    private QualityHeaderMapper qualityHeaderMapper;
+    @Autowired
+    private QualityDetailMapper qualityDetailMapper;
+    @Resource
+    private IQualityDetailService qualityDetailService;
+    @Resource
+    private IQualityHeaderService qualityHeaderService;
+
+    @Override
+    @Transactional
+    public void delMain(String id) {
+        qualityDetailMapper.deleteByMainId(id);
+        qualityHeaderMapper.deleteById(id);
+    }
+
+    @Override
+    @Transactional
+    public void delBatchMain(Collection<? extends Serializable> idList) {
+        for (Serializable id : idList) {
+            qualityDetailMapper.deleteByMainId(id.toString());
+            qualityHeaderMapper.deleteById(id);
+        }
+    }
+
+    @Override
+    public QualityHeader getQualityHeaderByReferCode(String referCode, String warehouseCode) {
+        LambdaQueryWrapper<QualityHeader> qualityHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
+        qualityHeaderLambdaQueryWrapper.eq(QualityHeader::getReferCode, referCode);
+        QualityHeader qualityHeader = getOne(qualityHeaderLambdaQueryWrapper);
+        return qualityHeader;
+    }
+
+    @Override
+    @Transactional
+    public String createQualityCode(String qualityType) {
+        String code = null;
+        Date now = new Date();
+        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
+        String maxCode = null;
+        QualityHeader qualityHeader = qualityHeaderMapper.getMaxQualityHeaderCode(qualityType);
+        if (qualityHeader != null) {
+            maxCode = qualityHeader.getCode();
+        }
+        if (maxCode != null) {
+            String day = maxCode.substring(maxCode.length() - 13, maxCode.length() - 5);
+            if (day.equals(df.format(now))) {
+                Integer Count = Integer.valueOf(maxCode.substring(maxCode.length() - 5, maxCode.length()));
+                code = qualityType + df.format(now) + String.format("%05d", Count + 1);
+            } else {
+                code = qualityType + df.format(now) + String.format("%05d", 0000 + 1);
+            }
+        } else {
+            code = qualityType + df.format(now) + String.format("%05d", 0000 + 1);
+        }
+        return code;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateQualityHeader(Integer id) {
+        LambdaQueryWrapper<QualityDetail> qualityDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        qualityDetailLambdaQueryWrapper.eq(QualityDetail::getQualityId, id);
+        List<QualityDetail> qualityDetailList = qualityDetailService.list(qualityDetailLambdaQueryWrapper);
+        QualityHeader qualityHeader = qualityHeaderService.getById(id);
+        if (qualityHeader == null) {
+            return false;
+        }
+        BigDecimal totalQty = new BigDecimal(0);
+        int totalLines = 0;
+        for (QualityDetail qualityDetail : qualityDetailList) {
+            totalLines++;
+            totalQty = totalQty.add(qualityDetail.getQty());
+        }
+        qualityHeader = new QualityHeader();
+        qualityHeader.setId(id);
+        qualityHeader.setTotalQty(totalQty);
+        qualityHeader.setTotalLines(totalLines);
+        if (!qualityHeaderService.updateById(qualityHeader)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateQualityHeaderStatus(Integer id) {
+        LambdaQueryWrapper<QualityDetail> qualityDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
+        qualityDetailLambdaQueryWrapper.eq(QualityDetail::getQualityId, id);
+        List<QualityDetail> qualityDetailList = qualityDetailService.list(qualityDetailLambdaQueryWrapper);
+        QualityHeader qualityHeader = qualityHeaderService.getById(id);
+        if (qualityHeader == null) {
+            return false;
+        }
+        int minStatus;
+        int maxStatus;
+        if (qualityDetailList.size() == 0) {
+            minStatus = QuantityConstant.QUALITY_HEADER_BUILD;
+            maxStatus = QuantityConstant.QUALITY_HEADER_BUILD;
+        } else {
+            minStatus = qualityDetailList.get(0).getStatus();
+            maxStatus = qualityDetailList.get(0).getStatus();
+            for (QualityDetail qualityDetail : qualityDetailList) {
+                int status = qualityDetail.getStatus();
+                if (minStatus > status) {
+                    minStatus = status;
+                }
+                if (maxStatus < status) {
+                    maxStatus = status;
+                }
+            }
+        }
+        QualityHeader updateQualityHeader = new QualityHeader();
+        updateQualityHeader.setId(id);
+        updateQualityHeader.setCode(qualityHeader.getCode());
+        updateQualityHeader.setReferCode(qualityHeader.getReferCode());
+        updateQualityHeader.setWarehouseCode(qualityHeader.getWarehouseCode());
+        updateQualityHeader.setFirstStatus(maxStatus);
+        updateQualityHeader.setLastStatus(minStatus);
+        if (!qualityHeaderService.updateById(updateQualityHeader)) {
+            throw new JeecgBootException("更新收货单:" + id + " 状态失败");
+        }
+        return true;
+    }
+}
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
index 220f9f9..7cbe865 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
@@ -125,7 +125,7 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl<ReceiptContai
     @OperationLog(bizId = "''", bizType = "'入库单追踪'", tag = "'入库任务生成'", extra = "#extraJsonString1", msg = "'任务ID:' + #taskHeader.getId()",
         condition = "#receiptContainerDetailList.size() > 0", recordReturnValue = true)
     @OperationLog(bizId = "''", bizType = "'任务追踪'", tag = "'入库任务生成'", extra = "#extraJsonString2",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
         condition = "#taskDetailList.size() > 0", recordReturnValue = true)
     public Result<TaskHeader> createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
         log.info("开始创建入库任务");
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/controller/ReceiptHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/controller/ReceiptHeaderController.java
index 54a8a6f..1429c51 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/controller/ReceiptHeaderController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/controller/ReceiptHeaderController.java
@@ -403,4 +403,13 @@ public class ReceiptHeaderController extends JeecgController<ReceiptHeader, IRec
         }
         return result;
     }
+
+    @AutoLog(value = "越库")
+    @ApiOperation(value = "越库", notes = "越库")
+    @PostMapping("/crossDocking")
+    @ResponseBody
+    @ApiLogger(apiName = "越库", from = "WMS")
+    public Result<?> crossDocking(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
+        return receiptHeaderService.crossDocking(id);
+    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/IReceiptHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/IReceiptHeaderService.java
index 116807a..584db7e 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/IReceiptHeaderService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/IReceiptHeaderService.java
@@ -41,4 +41,5 @@ public interface IReceiptHeaderService extends IService<ReceiptHeader> {
 
     String createReceiptCode(String receiptType);
 
+    Result crossDocking(String id);
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
index 567ab3e..6d390e5 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
@@ -3,6 +3,7 @@ package org.jeecg.modules.wms.receipt.receiptHeader.service.impl;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -15,6 +16,8 @@ import org.jeecg.modules.wms.audit.service.IAuditService;
 import org.jeecg.modules.wms.config.receiptType.entity.ReceiptType;
 import org.jeecg.modules.wms.config.receiptType.service.IReceiptTypeService;
 import org.jeecg.modules.wms.flow.service.IFlowDetailService;
+import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction;
+import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTransactionService;
 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail;
 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
 import org.jeecg.modules.wms.receipt.receiptHeader.mapper.ReceiptDetailMapper;
@@ -29,6 +32,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
@@ -60,6 +64,8 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl<ReceiptHeaderMapper, R
     private IFlowDetailService iFlowDetailService;
     @Resource
     private IAuditService iAuditService;
+    @Resource
+    private IInventoryTransactionService inventoryTransactionService;
 
     /**
      * @param  id     入库单主表id
@@ -136,18 +142,80 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl<ReceiptHeaderMapper, R
         }
         if (maxCode != null) {
             String day = maxCode.substring(maxCode.length() - 13, maxCode.length() - 5);
-            if (day.equals(df.format(now))) {
-                Integer Count = Integer.valueOf(maxCode.substring(maxCode.length() - 5, maxCode.length()));
-                code = receiptType + df.format(now) + String.format("%05d", Count + 1);
-            } else {
-                code = receiptType + df.format(now) + String.format("%05d", 0000 + 1);
-            }
+            Integer Count = Integer.valueOf(maxCode.substring(maxCode.length() - 5, maxCode.length()));
+            code = receiptType + df.format(now) + String.format("%05d", Count + 1);
         } else {
             code = receiptType + df.format(now) + String.format("%05d", 0000 + 1);
         }
         return code;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result crossDocking(String id) {
+        ReceiptHeader receiptHeader = receiptHeaderService.getById(id);
+        if (receiptHeader == null) {
+            return Result.error("越库失败,没有找到入库单头" + id);
+        }
+        List<ReceiptDetail> receiptDetailList = receiptDetailService.selectByMainId(id);
+        if (CollectionUtils.isEmpty(receiptDetailList)) {
+            return Result.error("越库失败,没有找到入库详情" + id);
+        }
+        List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
+        for (ReceiptDetail receiptDetail : receiptDetailList) {
+            BigDecimal qty = receiptDetail.getQty();
+            receiptDetail.setTaskQty(qty);
+            receiptDetail.setReceiptQty(qty);
+            receiptDetail.setStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED);
+            InventoryTransaction inventoryTransaction = new InventoryTransaction();
+            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_RECEIPT);
+            inventoryTransaction.setWarehouseCode(receiptDetail.getWarehouseCode());
+            inventoryTransaction.setCompanyCode(receiptDetail.getCompanyCode());
+            inventoryTransaction.setMaterialCode(receiptDetail.getMaterialCode());
+            inventoryTransaction.setMaterialName(receiptDetail.getMaterialName());
+            inventoryTransaction.setMaterialSpec(receiptDetail.getMaterialSpec());
+            inventoryTransaction.setMaterialUnit(receiptDetail.getMaterialUnit());
+            inventoryTransaction.setReceiptId(receiptDetail.getReceiptId());
+            inventoryTransaction.setReceiptCode(receiptHeader.getCode());
+            inventoryTransaction.setReceiptType(receiptHeader.getType());
+            inventoryTransaction.setReceiptDetailId(receiptDetail.getId());
+            inventoryTransaction.setBatch(receiptDetail.getBatch());
+            inventoryTransaction.setLot(receiptDetail.getLot());
+            inventoryTransaction.setProject(receiptDetail.getProject());
+            inventoryTransaction.setInventoryStatus(receiptDetail.getInventoryStatus());
+            inventoryTransaction.setQty(qty);
+            inventoryTransaction.setReceiptQty(qty);
+            inventoryTransactionList.add(inventoryTransaction);
+
+            inventoryTransaction = new InventoryTransaction();
+            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
+            inventoryTransaction.setWarehouseCode(receiptDetail.getWarehouseCode());
+            inventoryTransaction.setCompanyCode(receiptDetail.getCompanyCode());
+            inventoryTransaction.setMaterialCode(receiptDetail.getMaterialCode());
+            inventoryTransaction.setMaterialName(receiptDetail.getMaterialName());
+            inventoryTransaction.setMaterialSpec(receiptDetail.getMaterialSpec());
+            inventoryTransaction.setMaterialUnit(receiptDetail.getMaterialUnit());
+            inventoryTransaction.setInventoryStatus(receiptDetail.getInventoryStatus());
+            inventoryTransaction.setBatch(receiptDetail.getBatch());
+            inventoryTransaction.setLot(receiptDetail.getLot());
+            inventoryTransaction.setProject(receiptDetail.getProject());
+            inventoryTransaction.setQty(receiptDetail.getQty());
+            inventoryTransaction.setShipmentQty(receiptDetail.getQty());
+            inventoryTransactionList.add(inventoryTransaction);
+        }
+
+        if (!receiptDetailService.updateBatchById(receiptDetailList)) {
+            throw new JeecgBootException("越库失败,批量更新入库单详情失败");
+        }
+        if (!inventoryTransactionService.saveBatch(inventoryTransactionList)) {
+            throw new JeecgBootException("越库失败,批量保存库存交易记录失败");
+        }
+        if (!receiptHeaderService.updateReceiptHeaderStatus(Integer.parseInt(id))) {
+            throw new JeecgBootException("越库失败,批更新入库单失败");
+        }
+        return Result.ok("越库成功");
+    }
+
     /**
      * 更新入库单 头状态和尾状态
      * 头状态是单据详情中最大的状态
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/controller/ReceiveHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/controller/ReceiveHeaderController.java
index e462a60..f7fa08f 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/controller/ReceiveHeaderController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/controller/ReceiveHeaderController.java
@@ -359,4 +359,47 @@ public class ReceiveHeaderController extends JeecgController<ReceiveHeader, IRec
         return result;
     }
 
+    /**
+     * 全部收货
+     * @return
+     */
+    @AutoLog("收货单-全部收货")
+    @ApiOperation(value = "收货单-全部收货", notes = "收货单-全部收货")
+    @PostMapping("/receiveHeader")
+    @ResponseBody
+    public Result receiveHeader(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
+        String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
+        String lockKey = warehouseCode;
+        Result result = receiveDetailService.receiveHeader(id, warehouseCode);
+        return result;
+    }
+
+    /**
+     * 收货详情质检
+     * @return
+     */
+    @AutoLog("收货单-收货详情质检")
+    @ApiOperation(value = "收货单-收货详情质检", notes = "收货单-收货详情质检")
+    @PostMapping("/receiveDetailToQuality")
+    @ResponseBody
+    public Result receiveDetailToQuality(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
+        String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
+        String lockKey = warehouseCode;
+        Result result = receiveDetailService.receiveToQuality(id, warehouseCode);
+        return result;
+    }
+
+    /**
+     * 全部质检
+     * @return
+     */
+    @AutoLog("收货单-全部质检")
+    @ApiOperation(value = "收货单-全部质检", notes = "收货单-全部质检")
+    @PostMapping("/receiveHeaderToQuality")
+    @ResponseBody
+    public Result receiveHeaderToQuality(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
+        String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req);
+        Result result = receiveHeaderService.receiveHeaderToQuality(id, warehouseCode);
+        return result;
+    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/entity/ReceiveDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/entity/ReceiveDetail.java
index 51cab06..b07ca70 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/entity/ReceiveDetail.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/entity/ReceiveDetail.java
@@ -69,6 +69,10 @@ public class ReceiveDetail implements Serializable {
     @Excel(name = "已收数量", width = 15)
     @ApiModelProperty(value = "已收数量")
     private java.math.BigDecimal taskQty;
+    /** 质检数量 */
+    @Excel(name = "质检数量", width = 15)
+    @ApiModelProperty(value = "质检数量")
+    private java.math.BigDecimal qualityQty;
     /** 库存状态 */
     @Excel(name = "库存状态", width = 15)
     @Dict(dicCode = "inventory_status")
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveDetailService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveDetailService.java
index 9777828..82d5be2 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveDetailService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveDetailService.java
@@ -1,5 +1,6 @@
 package org.jeecg.modules.wms.receipt.receiveHeader.service;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 import org.jeecg.common.api.vo.Result;
@@ -21,4 +22,18 @@ public interface IReceiveDetailService extends IService<ReceiveDetail> {
     Result saveReceiveDetail(ReceiveDetail receiveDetail);
 
     Result receive(List<Receive> receiveList, String warehouseCode);
+
+    Result receiveHeader(String id, String warehouseCode);
+
+    /**
+     * 收货单转质检单
+     * @param  id
+     * @param  warehouseCode
+     * @return
+     */
+    Result receiveToQuality(String id, String warehouseCode);
+
+    boolean updateQualityQtyById(BigDecimal qualityQty, int id);
+
+    boolean updateStatusById(int status, int id);
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveHeaderService.java
index b531ddb..dbc648e 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveHeaderService.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/IReceiveHeaderService.java
@@ -38,4 +38,6 @@ public interface IReceiveHeaderService extends IService<ReceiveHeader> {
     boolean updateReceiveHeader(Integer id);
 
     boolean updateReceiptHeaderStatus(Integer id);
+
+    Result receiveHeaderToQuality(String id, String warehouseCode);
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveDetailServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveDetailServiceImpl.java
index 955da9d..54e3f7c 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveDetailServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveDetailServiceImpl.java
@@ -3,7 +3,6 @@ package org.jeecg.modules.wms.receipt.receiveHeader.service.impl;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 
 import javax.annotation.Resource;
@@ -13,11 +12,16 @@ import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.modules.wms.config.material.entity.Material;
 import org.jeecg.modules.wms.config.material.service.IMaterialService;
 import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
-import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryHeader;
 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
 import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
 import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction;
 import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTransactionService;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail;
+import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityHeader;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService;
+import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityHeaderService;
+import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptDetailService;
+import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptHeaderService;
 import org.jeecg.modules.wms.receipt.receiveHeader.entity.ReceiveDetail;
 import org.jeecg.modules.wms.receipt.receiveHeader.entity.ReceiveHeader;
 import org.jeecg.modules.wms.receipt.receiveHeader.mapper.ReceiveDetailMapper;
@@ -52,6 +56,14 @@ public class ReceiveDetailServiceImpl extends ServiceImpl<ReceiveDetailMapper, R
     @Resource
     private IReceiveHeaderService receiveHeaderService;
     @Resource
+    private IReceiptHeaderService receiptHeaderService;
+    @Resource
+    private IReceiptDetailService receiptDetailService;
+    @Resource
+    private IQualityHeaderService qualityHeaderService;
+    @Resource
+    private IQualityDetailService qualityDetailService;
+    @Resource
     private IMaterialService materialService;
     @Resource
     private IReceiveDetailService receiveDetailService;
@@ -116,7 +128,7 @@ public class ReceiveDetailServiceImpl extends ServiceImpl<ReceiveDetailMapper, R
     @Transactional(rollbackFor = Exception.class)
     public Result receive(List<Receive> receiveList, String warehouseCode) {
         boolean success = false;
-        if (receiveList == null || receiveList.size() == 0) {
+        if (CollectionUtils.isEmpty(receiveList)) {
             return Result.error("收货,收货信息为空");
         }
         List<InventoryDetail> inventoryDetailList = new ArrayList<>();
@@ -172,41 +184,9 @@ public class ReceiveDetailServiceImpl extends ServiceImpl<ReceiveDetailMapper, R
                 receiveDetail1.setStatus(QuantityConstant.RECEIVE_HEADER_COMPLETE);
             }
             receiveDetailList.add(receiveDetail1);
-            InventoryHeader inventoryHeader = inventoryHeaderService.getInventoryHeaderByContainerCode(receiveCode, warehouseCode);
-            if (inventoryHeader == null) {
-                inventoryHeader = new InventoryHeader();
-                inventoryHeader.setWarehouseCode(warehouseCode);
-                inventoryHeader.setCompanyCode(receiveDetail.getCompanyCode());
-                inventoryHeader.setZoneCode(QuantityConstant.ZONE_RECEIVE);
-                inventoryHeader.setContainerCode(receiveCode);
-                inventoryHeader.setContainerStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
-                inventoryHeader.setEnable(QuantityConstant.STATUS_ENABLE);
-                if (!inventoryHeaderService.save(inventoryHeader)) {
-                    throw new JeecgBootException("收货, 添加库存头失败");
-                }
-            }
-
-            InventoryDetail inventoryDetail = new InventoryDetail();
-            inventoryDetail.setInventoryHeaderId(inventoryHeader.getId());
-            inventoryDetail.setWarehouseCode(warehouseCode);
-            inventoryDetail.setCompanyCode(receiveDetail.getCompanyCode());
-            inventoryDetail.setZoneCode(QuantityConstant.ZONE_RECEIVE);
-            inventoryDetail.setContainerCode(receiveCode);
-            inventoryDetail.setContainerStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
-            inventoryDetail.setMaterialCode(receiveDetail.getMaterialCode());
-            inventoryDetail.setMaterialName(receiveDetail.getMaterialName());
-            inventoryDetail.setMaterialSpec(receiveDetail.getMaterialSpec());
-            inventoryDetail.setMaterialUnit(receiveDetail.getMaterialUnit());
-            inventoryDetail.setQty(receiveQty);
-            inventoryDetail.setInventoryStatus(receiveDetail.getInventoryStatus());
-            inventoryDetail.setBatch(receiveDetail.getBatch());
-            inventoryDetail.setLot(receiveDetail.getLot());
-            inventoryDetail.setProject(receiveDetail.getProject());
-            inventoryDetail.setReceiveTime(new Date());
-            inventoryDetailList.add(inventoryDetail);
 
             InventoryTransaction inventoryTransaction = new InventoryTransaction();
-            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_RECEIPT);
+            inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_RECEIVE);
             inventoryTransaction.setWarehouseCode(receiveDetail.getWarehouseCode());
             inventoryTransaction.setCompanyCode(receiveDetail.getCompanyCode());
             inventoryTransaction.setContainerCode(receiveCode);
@@ -219,7 +199,7 @@ public class ReceiveDetailServiceImpl extends ServiceImpl<ReceiveDetailMapper, R
             inventoryTransaction.setLot(receiveDetail.getLot());
             inventoryTransaction.setProject(receiveDetail.getProject());
             inventoryTransaction.setInventoryStatus(receiveDetail.getInventoryStatus());
-            inventoryTransaction.setQty(receiveQty);
+            inventoryTransaction.setQty(taskQty);
             inventoryTransactionList.add(inventoryTransaction);
         }
         if (CollectionUtils.isEmpty(receiveDetailList)) {
@@ -231,16 +211,126 @@ public class ReceiveDetailServiceImpl extends ServiceImpl<ReceiveDetailMapper, R
         if (!receiveHeaderService.updateReceiptHeaderStatus(receiveId)) {
             throw new JeecgBootException("收货, 保存库存头失败");
         }
-        if (!inventoryDetailService.saveBatch(inventoryDetailList)) {
-            throw new JeecgBootException("收货, 保存库存详情失败");
-        }
+
         if (!inventoryTransactionService.saveBatch(inventoryTransactionList)) {
             throw new JeecgBootException("收货, 保存库存交易失败");
         }
-        if (!taskHeaderService.combineInventoryDetail(receiveCode, warehouseCode)) {
-            throw new JeecgBootException("收货, 合并入库库存失败");
-        }
 
         return Result.OK("收货成功");
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result receiveHeader(String id, String warehouseCode) {
+        ReceiveHeader receiveHeader = receiveHeaderService.getById(id);
+        if (receiveHeader == null) {
+            return Result.error("收货失败, 没有找到收货头表" + id);
+        }
+        List<ReceiveDetail> receiveDetailList = receiveDetailService.selectByMainId(id);
+        if (CollectionUtils.isEmpty(receiveDetailList)) {
+            return Result.error("收货失败, 没有找到收货明细表" + id);
+        }
+        List<Receive> receiveList = new ArrayList<>();
+        for (ReceiveDetail receiveDetail : receiveDetailList) {
+            Receive receive = new Receive();
+            receive.setId(receiveDetail.getId());
+            receive.setQty(receiveDetail.getQty());
+            BigDecimal taskQty = receiveDetail.getQty().subtract(receiveDetail.getTaskQty());
+            receive.setTaskQty(taskQty);
+            receiveList.add(receive);
+        }
+        return receiveDetailService.receive(receiveList, warehouseCode);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result receiveToQuality(String id, String warehouseCode) {
+        ReceiveDetail receiveDetail = receiveDetailService.getById(id);
+        if (receiveDetail == null) {
+            throw new JeecgBootException("生成质检单失败, 没有找到收货明细表" + id);
+        }
+        if (receiveDetail.getQty().compareTo(receiveDetail.getTaskQty()) > 0) {
+            throw new JeecgBootException("生成质检单失败, 收货明细没有收货完成" + id);
+        }
+        if (receiveDetail.getQty().compareTo(receiveDetail.getQualityQty()) == 0) {
+            throw new JeecgBootException("生成质检单失败, 收货明细已经生成质检单" + id);
+        }
+        ReceiveHeader receiveHeader = receiveHeaderService.getById(receiveDetail.getReceiveId());
+        if (receiveHeader == null) {
+            throw new JeecgBootException("生成质检单失败, 没有找到收货主表" + id);
+        }
+        String referCode = receiveHeader.getCode();
+        QualityHeader qualityHeader = qualityHeaderService.getQualityHeaderByReferCode(referCode, warehouseCode);
+        if (qualityHeader == null) {
+            qualityHeader = new QualityHeader();
+            qualityHeader.setWarehouseCode(warehouseCode);
+            qualityHeader.setReferCode(referCode);
+            qualityHeader.setCompanyCode(receiveHeader.getCompanyCode());
+            qualityHeader.setType(QuantityConstant.QUALITY_TYPE_INCOMING);
+            qualityHeader.setSupplierCode(receiveHeader.getSupplierCode());
+            String code = qualityHeaderService.createQualityCode(QuantityConstant.QUALITY_TYPE_INCOMING);
+            qualityHeader.setCode(code);
+            qualityHeader.setFirstStatus(QuantityConstant.QUALITY_HEADER_BUILD);
+            qualityHeader.setLastStatus(QuantityConstant.QUALITY_HEADER_BUILD);
+            if (!qualityHeaderService.save(qualityHeader)) {
+                throw new JeecgBootException("生成质检单失败, 创建单据表头失败");
+            }
+        }
+        QualityDetail qualityDetail = new QualityDetail();
+        qualityDetail.setWarehouseCode(warehouseCode);
+        qualityDetail.setCompanyCode(receiveHeader.getCompanyCode());
+        qualityDetail.setReferCode(referCode);
+        qualityDetail.setQualityCode(qualityHeader.getCode());
+        qualityDetail.setQualityId(qualityHeader.getId());
+        qualityDetail.setStatus(QuantityConstant.QUALITY_HEADER_BUILD);
+        qualityDetail.setQty(receiveDetail.getQty());
+        qualityDetail.setInventoryStatus(QuantityConstant.QUALITY_DISUSSED);
+        qualityDetail.setMaterialCode(receiveDetail.getMaterialCode());
+        qualityDetail.setMaterialName(receiveDetail.getMaterialName());
+        qualityDetail.setMaterialSpec(receiveDetail.getMaterialSpec());
+        qualityDetail.setMaterialUnit(receiveDetail.getMaterialUnit());
+        qualityDetail.setBatch(receiveDetail.getBatch());
+        qualityDetail.setLot(receiveDetail.getLot());
+        qualityDetail.setProject(receiveDetail.getProject());
+        if (!qualityDetailService.save(qualityDetail)) {
+            throw new JeecgBootException("生成质检单失败, 创建单据表详情失败");
+        }
+
+        if (!receiveDetailService.updateQualityQtyById(receiveDetail.getQty(), receiveDetail.getId())) {
+            throw new JeecgBootException("生成质检单失败, 更新单据详情失败");
+        }
+        if (!receiveDetailService.updateStatusById(QuantityConstant.RECEIVE_HEADER_QUALITY, receiveDetail.getId())) {
+            throw new JeecgBootException("生成质检单失败, 更新单据详情失败");
+        }
+
+        if (!receiveHeaderService.updateReceiptHeaderStatus(receiveDetail.getReceiveId())) {
+            throw new JeecgBootException("质检失败,更新质检状态失败");
+        }
+
+        if (!qualityHeaderService.updateQualityHeader(qualityHeader.getId())) {
+            throw new JeecgBootException("生成质检单失败, 更新单据数量失败");
+        }
+
+        if (!qualityHeaderService.updateQualityHeaderStatus(qualityHeader.getId())) {
+            throw new JeecgBootException("生成质检单失败, 更新单据状态失败");
+        }
+
+        return Result.ok("生成质检单成功");
+    }
+
+    @Override
+    public boolean updateQualityQtyById(BigDecimal qualityQty, int id) {
+        ReceiveDetail receiveDetail = new ReceiveDetail();
+        receiveDetail.setId(id);
+        receiveDetail.setQualityQty(qualityQty);
+        return receiveDetailService.updateById(receiveDetail);
+    }
+
+    @Override
+    public boolean updateStatusById(int status, int id) {
+        ReceiveDetail receiveDetail = new ReceiveDetail();
+        receiveDetail.setId(id);
+        receiveDetail.setStatus(status);
+        return receiveDetailService.updateById(receiveDetail);
+    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveHeaderServiceImpl.java
index d2ad814..46a96ca 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/receiveHeader/service/impl/ReceiveHeaderServiceImpl.java
@@ -187,4 +187,14 @@ public class ReceiveHeaderServiceImpl extends ServiceImpl<ReceiveHeaderMapper, R
         }
         return true;
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result receiveHeaderToQuality(String id, String warehouseCode) {
+        List<ReceiveDetail> receiveDetailList = receiveDetailService.selectByMainId(id);
+        for (ReceiveDetail receiveDetail : receiveDetailList) {
+            receiveDetailService.receiveToQuality(String.valueOf(receiveDetail.getId()), warehouseCode);
+        }
+        return Result.ok("生成质检单成功");
+    }
 }
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
index d8478c0..eb4d759 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java
@@ -834,7 +834,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi
         msg = "'任务ID:' + #taskHeader.getId() + ',库位编码:' + #shipmentContainerHeader.getFromLocationCode() + ',容器编码:' + #shipmentContainerHeader.getContainerCode() + ',目标出入口:' + #shipmentContainerHeader.getToPort()",
         condition = "#shipmentContainerDetailList.size() > 0", recordReturnValue = true)
     @OperationLog(bizId = "''", bizType = "'任务追踪'", tag = "'出库任务生成'", extra = "#extraJsonString2",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
         condition = "#taskDetailList.size() > 0", recordReturnValue = true)
     public Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, int forceTaskType, String warehouseCode, long shipmentOrder, int sequence,
         int sequenceNumber) {
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
index 3abfe74..1b44a64 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
@@ -1085,7 +1085,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "''", bizType = "'任务追踪'", tag = "'入库任务完成'", extra = "#extraJsonString1",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
         recordReturnValue = true)
     @OperationLog(bizId = "''", bizType = "'入库单追踪'", tag = "'入库任务完成'", extra = "#extraJsonString1",
         msg = "'任务ID:' + #taskHeader.getId() + ',库位编码:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()", recordReturnValue = true)
@@ -1274,7 +1274,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea
     @Override
     @Transactional(rollbackFor = Exception.class)
     @OperationLog(bizId = "''", bizType = "'任务追踪'", tag = "'出库任务完成'", extra = "#extraJsonString1",
-        msg = "'任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
+        msg = "#taskHeader == null ? '' : '任务类型:' + #taskHeader.getTaskType() + ',起始库位:' + #taskHeader.getFromLocationCode() + ',目标库位:' + #taskHeader.getToLocationCode() + ',容器编码:' + #taskHeader.getContainerCode()",
         recordReturnValue = true)
     @OperationLog(bizId = "''", bizType = "'出库单追踪'", tag = "'出库任务完成'", extra = "#extraJsonString1",
         msg = "'任务ID:' + #taskHeader.getId() + ',库位编码:' + #taskHeader.getFromLocationCode() + ',容器编码:' + #taskHeader.getContainerCode() + ',目标出入口:' + #taskHeader.getToPortCode()",
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java
index 3558fe0..aa49a40 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java
@@ -12,7 +12,7 @@ package org.jeecg.utils.constant;
  * 8、波次状态
  * 9、质检状态
  * 10、盘点状态
- * 11、INVENTORY_TRANSACTION_RECEIPT
+ * 11、库存交易记录
  * 12、调整单状态
  * 13、任务内部类型
  * 14、质检单类型
@@ -307,6 +307,12 @@ public class QuantityConstant {
     /** 移库 */
     public static final Integer INVENTORY_TRANSACTION_TRANSFER = 50;
 
+    /** 收货 */
+    public static final Integer INVENTORY_TRANSACTION_RECEIVE = 60;
+
+    /** 质检 */
+    public static final Integer INVENTORY_TRANSACTION_QUALITY = 70;
+
     // 12、调整单状态
 
     // 未批准
@@ -402,7 +408,22 @@ public class QuantityConstant {
     public static final Integer RECEIVE_HEADER_HALF = 100;
     // 收货单完成收货状态
     public static final Integer RECEIVE_HEADER_COMPLETE = 200;
-    
+    // 生成质检单
+    public static final Integer RECEIVE_HEADER_QUALITY = 300;
+
+    // 新建
+    public static final Integer QUALITY_HEADER_BUILD = 0;
+    // 部分质检
+    public static final Integer QUALITY_HEADER_HALF = 100;
+    // 质检完成
+    public static final Integer QUALITY_HEADER_COMPLETE = 200;
+
+    /** 来料质检 */
+    public static final String QUALITY_TYPE_INCOMING = "QI";
+    /** 库内全检 */
+    public static final String QUALITY_TYPE_INHOUSE_FULL = "QIF";
+    /** 库内抽检 */
+    public static final String QUALITY_TYPE_INHOUSE_PART = "QIP";
 
     /** 对接WCS可用巷道API */
     public static final String ADDRESS_WCS_AVAILABLE_ROWDWAY = "WCS_AVAILABLE_ROWDWAY";
@@ -451,8 +472,14 @@ public class QuantityConstant {
     public static final String PLATFORM_CODING = "赋码系统";
     public static final String PLATFORM_ERP = "ERP";
     public static final String PLATFORM_WMS = "WMS";
-    // good
+    // 良品
     public static final String QUALITY_GOOD = "good";
+    // 次品
+    public static final String QUALITY_DEFECTIVE = "defective";
+    // 报废品
+    public static final String QUALITY_SCRAP = "scrap";
+    // 待确认
+    public static final String QUALITY_DISUSSED = "discussed";
 
     // 发送AGV任务成功
     public static final int AGV_NEED_SEND = 0;
@@ -515,23 +542,25 @@ public class QuantityConstant {
      * 出库依赖库区
      */
     public static final int SHIPMENT_BY_ZONE = 1;
-    
-    /** 对接WCS可用巷道API:关闭  */
+
+    /** 对接WCS可用巷道API:关闭 */
     public static final String AVAILABLE_ROWDWAY_CLOSE = "0";
-    
+
     /** 对接WCS可用巷道API:开启 */
     public static final String AVAILABLE_ROWDWAY_OPEN = "1";
-    
+
     /** 启用获取可用巷道API */
     public static final String RULE_AVAILABLE_ROWDWAY_STATUS = "availableRowdwayStatus";
-    
-    /** 定时任务异常响应通知配置  */
+
+    /** 接口异常响应通知配置 */
+
+    /** 定时任务异常响应通知配置 */
     public static final String RULE_JOB_EXCEPTION_NOTICE_ROLE_OR_NAME = "jobExceptionNoticeRoleOrName";
-    
-    /** 接口异常响应通知配置  */
+
+    /** 接口异常响应通知配置 */
     public static final String RULE_API_EXCEPTION_NOTICE_ROLE_OR_NAME = "apiExceptionNoticeRoleOrName";
-    
-    /** 定时任务执行消息通知配置  */
+
+    /** 定时任务执行消息通知配置 */
     public static final String RULE_TASK_RUN_NOTICE_CLASS_NAME = "taskRunNoticeClassName";
 
     public static final int RULE_TASK_NOT_CLEAR = 0;
diff --git a/huaheng-wms-core/src/main/resources/application-dev.yml b/huaheng-wms-core/src/main/resources/application-dev.yml
index e373f58..de768bd 100644
--- a/huaheng-wms-core/src/main/resources/application-dev.yml
+++ b/huaheng-wms-core/src/main/resources/application-dev.yml
@@ -116,7 +116,7 @@ spring:
         # 初始化大小,最小,最大
         initial-size: 5
         min-idle: 5
-        maxActive: 20
+        maxActive: 50
         # 配置获取连接等待超时的时间
         maxWait: 60000
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -136,7 +136,7 @@ spring:
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:log4jdbc:mysql://localhost:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
+          url: jdbc:log4jdbc:mysql://localhost:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999
           username: root
           password: 123456
           driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
diff --git a/huaheng-wms-core/src/main/resources/application-prod.yml b/huaheng-wms-core/src/main/resources/application-prod.yml
index c4f050f..0d5f5be 100644
--- a/huaheng-wms-core/src/main/resources/application-prod.yml
+++ b/huaheng-wms-core/src/main/resources/application-prod.yml
@@ -116,7 +116,7 @@ spring:
         # 初始化大小,最小,最大
         initial-size: 5
         min-idle: 5
-        maxActive: 20
+        maxActive: 50
         # 配置获取连接等待超时的时间
         maxWait: 60000
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -136,7 +136,7 @@ spring:
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
+          url: jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999
           username: root
           password: hhsoftware
           driver-class-name: com.mysql.cj.jdbc.Driver
@@ -250,7 +250,7 @@ jeecg:
       - title: 物料双边打印机纸
         size:
           - 85
-          - 60      
+          - 60
       - title: 条码单边打印机纸
         size:
           - 60
diff --git a/huaheng-wms-core/src/main/resources/application-test.yml b/huaheng-wms-core/src/main/resources/application-test.yml
index f9a38b7..3f1a0e1 100644
--- a/huaheng-wms-core/src/main/resources/application-test.yml
+++ b/huaheng-wms-core/src/main/resources/application-test.yml
@@ -137,7 +137,7 @@ spring:
       datasource:
         master:
           # mysql数据源配置
-          url: jdbc:log4jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
+          url: jdbc:log4jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999
           username: root
           password: hhsoftware
           driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy