20 Commits 7b64139901 ... e4dccfdbaf

Author SHA1 Message Date
  13660505945 e4dccfdbaf Merge remote-tracking branch 'origin/xq' 2 months ago
  13660505945 33c24accbf Merge remote-tracking branch 'origin/dev_huangjunjie' 2 months ago
  maliang 617f250e70 fix:商品信息 2 months ago
  huang c8c2fa7378 新增数据库表格sql语句 2 months ago
  huang 8ec2116df6 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 2 months ago
  huang e79c10df96 商品批次号逻辑改为条码逻辑 2 months ago
  15102826049 8c9c84c6f0 盘点状态更新 2 months ago
  15102826049 f9800acf37 盘点核对编辑状态显示修改 2 months ago
  15102826049 a3143a0be9 Merge branch 'dev_ml_423' into xq 2 months ago
  maliang 9b584599de feat:4.23需求 2 months ago
  maliang ff03d39a36 fix:bug[937] 2 months ago
  maliang c1187dfb9f feat:app版本管理 2 months ago
  maliang 4594b14eda fix:bug[935] 2 months ago
  huang 4561631adf apk文件上传 2 months ago
  huang 4deef449da pda商品出入库明细修改 2 months ago
  huang a80d90b281 pda拣货入库模糊查询添加,订单出库时间添加,pc端订单商品数据显示,详情修改 2 months ago
  15102826049 82507ae171 Merge branch 'dev_xq' into xq 2 months ago
  15102826049 7ac807331c 供应商信息增加限制输入 2 months ago
  huang 8461fdf890 修改sql语句 2 months ago
  15102826049 12ad5140f1 bug修改提交 2 months ago
71 changed files with 2843 additions and 1382 deletions
  1. 109 0
      docs/new_sql.sql
  2. 1 1
      jshERP-web/src/components/jeecg/JEditableTable.vue
  3. 42 0
      jshERP-web/src/components/jeecgbiz/JSelectList.vue
  4. 522 0
      jshERP-web/src/components/jeecgbiz/modal/JSelectMaterialModal2.vue
  5. 1 0
      jshERP-web/src/utils/JEditableTableUtil.js
  6. 6 6
      jshERP-web/src/views/bill/dialog/BillDetail.vue
  7. 97 3
      jshERP-web/src/views/bill/mixins/BillModalMixin.js
  8. 1 1
      jshERP-web/src/views/bill/modules/AllocationOutModal.vue
  9. 56 43
      jshERP-web/src/views/bill/modules/OtherInModal.vue
  10. 44 43
      jshERP-web/src/views/bill/modules/OtherOutModal.vue
  11. 67 54
      jshERP-web/src/views/bill/modules/PurchaseInModal.vue
  12. 58 46
      jshERP-web/src/views/bill/modules/PurchaseOrderModal.vue
  13. 38 38
      jshERP-web/src/views/bill/modules/SaleOrderModal.vue
  14. 46 46
      jshERP-web/src/views/bill/modules/SaleOutModal.vue
  15. 2 2
      jshERP-web/src/views/material/MaterialList.vue
  16. 1 1
      jshERP-web/src/views/material/modules/BatchSetStockModal.vue
  17. 194 590
      jshERP-web/src/views/material/modules/MaterialModal.vue
  18. 1 2
      jshERP-web/src/views/stock/CheckList.vue
  19. 3 3
      jshERP-web/src/views/stock/TaskList.vue
  20. 1 1
      jshERP-web/src/views/stock/components/FilterForm.vue
  21. 58 23
      jshERP-web/src/views/stock/components/checkModal.vue
  22. 6 2
      jshERP-web/src/views/stock/components/stockModal.vue
  23. 87 0
      jshERP-web/src/views/system/AppVersionList.vue
  24. 293 0
      jshERP-web/src/views/system/modules/AppVersionModal.vue
  25. 22 5
      jshERP-web/src/views/system/modules/VendorModal.vue
  26. 2 1
      jshERP-web/vue.config.js
  27. 2 1
      src/main/java/com/jsh/erp/controller/DepotController.java
  28. 16 13
      src/main/java/com/jsh/erp/controller/DepotItemController.java
  29. 17 14
      src/main/java/com/jsh/erp/controller/MaterialController.java
  30. 1 0
      src/main/java/com/jsh/erp/controller/MaterialExtendController.java
  31. 50 3
      src/main/java/com/jsh/erp/controller/apkVersion/apkVersionController.java
  32. 45 0
      src/main/java/com/jsh/erp/controller/materialBatch/MaterialBatchController.java
  33. 3 1
      src/main/java/com/jsh/erp/controller/pda/PdaController.java
  34. 1 1
      src/main/java/com/jsh/erp/controller/stocktaking/StocktakingController.java
  35. 26 0
      src/main/java/com/jsh/erp/datasource/dto/DepotHeadDto.java
  36. 29 0
      src/main/java/com/jsh/erp/datasource/dto/MaterialDto.java
  37. 2 0
      src/main/java/com/jsh/erp/datasource/entities/ApkVersion.java
  38. 4 0
      src/main/java/com/jsh/erp/datasource/entities/DepotEx.java
  39. 6 2
      src/main/java/com/jsh/erp/datasource/entities/DepotHead.java
  40. 21 0
      src/main/java/com/jsh/erp/datasource/entities/DepotItem.java
  41. 5 1
      src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4WithInfoEx.java
  42. 90 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialBatch.java
  43. 9 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialCurrentStock.java
  44. 3 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialExtend.java
  45. 5 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialInitialStock.java
  46. 1 1
      src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapperEx.java
  47. 27 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialBatchMapper.java
  48. 3 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDADepotHeadDTO.java
  49. 3 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDADepotHeadVO.java
  50. 6 0
      src/main/java/com/jsh/erp/datasource/vo/MaterialCountVo.java
  51. 6 2
      src/main/java/com/jsh/erp/service/DepotItemService.java
  52. 44 0
      src/main/java/com/jsh/erp/service/MaterialBatchService.java
  53. 3 6
      src/main/java/com/jsh/erp/service/MaterialExtendService.java
  54. 27 4
      src/main/java/com/jsh/erp/service/MaterialService.java
  55. 1 1
      src/main/java/com/jsh/erp/service/SystemConfigService.java
  56. 47 25
      src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java
  57. 55 55
      src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java
  58. 130 0
      src/main/java/com/jsh/erp/service/impl/MaterialBatchServiceImpl.java
  59. 199 196
      src/main/java/com/jsh/erp/service/impl/MaterialExtendServiceImpl.java
  60. 106 128
      src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java
  61. 12 3
      src/main/resources/application-dev.yml
  62. 2 2
      src/main/resources/application.yml
  63. 1 1
      src/main/resources/mapper_xml/DepotHeadMapper.xml
  64. 1 1
      src/main/resources/mapper_xml/DepotHeadMapperEx.xml
  65. 24 0
      src/main/resources/mapper_xml/DepotItemMapper.xml
  66. 6 5
      src/main/resources/mapper_xml/DepotItemMapperEx.xml
  67. 24 0
      src/main/resources/mapper_xml/MaterialBatchMapper.xml
  68. 9 0
      src/main/resources/mapper_xml/MaterialExtendMapper.xml
  69. 1 1
      src/main/resources/mapper_xml/MaterialExtendMapperEx.xml
  70. 10 2
      src/main/resources/mapper_xml/MaterialInitialStockMapper.xml
  71. 2 2
      src/main/resources/mapper_xml/MaterialMapperEx.xml

+ 109 - 0
docs/new_sql.sql

@@ -116,3 +116,112 @@ CREATE TABLE `apk_version` (
 ALTER TABLE jsh_depot_head
 ADD COLUMN depot_id bigint DEFAULT NULL COMMENT '仓库id',
 ADD COLUMN oper_id bigint DEFAULT NULL COMMENT '操作人';
+
+-- 单据子表  新增创建时间
+ALTER TABLE jsh_depot_item
+ADD COLUMN create_time DATETIME DEFAULT NULL COMMENT '创建时间';
+
+-- 单据主表 修改文件,凭证,价格,数量图片类型
+ALTER TABLE jsh_depot_head
+  MODIFY file_name TEXT DEFAULT NULL COMMENT '附件名称',
+  MODIFY voucher_picture TEXT DEFAULT NULL COMMENT '凭证图片',
+  MODIFY change_amount DECIMAL(24,2) DEFAULT NULL COMMENT '变动金额(收款/付款)',
+  MODIFY back_amount DECIMAL(24,2) DEFAULT NULL COMMENT '找零金额',
+  MODIFY total_price DECIMAL(24,2) DEFAULT NULL COMMENT '合计金额',
+  MODIFY discount_money DECIMAL(24,2) DEFAULT NULL COMMENT '优惠金额',
+  MODIFY discount_last_money DECIMAL(24,2) DEFAULT NULL COMMENT '优惠后金额',
+  MODIFY other_money DECIMAL(24,2) DEFAULT NULL COMMENT '销售或采购费用合计',
+  MODIFY deposit DECIMAL(24,2) DEFAULT NULL COMMENT '订金';
+
+-- 单据子表  修改数量、价格类型
+ALTER TABLE jsh_depot_item
+  MODIFY oper_number DECIMAL(24,0) DEFAULT NULL COMMENT '数量',
+  MODIFY basic_number DECIMAL(24,0) DEFAULT NULL COMMENT '基础数量',
+  MODIFY unit_price DECIMAL(24,2) DEFAULT NULL COMMENT '单价',
+  MODIFY purchase_unit_price DECIMAL(24,2) DEFAULT NULL COMMENT '采购单价',
+  MODIFY tax_unit_price DECIMAL(24,2) DEFAULT NULL COMMENT '含税单价',
+  MODIFY all_price DECIMAL(24,2) DEFAULT NULL COMMENT '金额',
+  MODIFY tax_money DECIMAL(24,2) DEFAULT NULL COMMENT '税额',
+  MODIFY tax_last_money DECIMAL(24,2) DEFAULT NULL COMMENT '价税合计',
+  MODIFY actual_quantity_in_storage DECIMAL(10,0) DEFAULT NULL COMMENT '实际出入库数量',
+  MODIFY warehousing_variance DECIMAL(10,0) DEFAULT NULL COMMENT '出入库差异';
+
+-- 商品主表 修改商品图片、重量类型
+ALTER TABLE jsh_material
+  MODIFY img_name TEXT DEFAULT NULL COMMENT '图片名称',
+  MODIFY weight DECIMAL(24,2) DEFAULT NULL COMMENT '基础重量(kg)';
+
+-- 商品子表 修改价格,库存类型
+ALTER TABLE jsh_material_extend
+  MODIFY purchase_decimal DECIMAL(24,2) DEFAULT NULL COMMENT '采购价格',
+  MODIFY commodity_decimal DECIMAL(24,2) DEFAULT NULL COMMENT '零售价格',
+  MODIFY wholesale_decimal DECIMAL(24,2) DEFAULT NULL COMMENT '销售价格',
+  MODIFY low_decimal DECIMAL(24,2) DEFAULT NULL COMMENT '最低售价',
+  MODIFY inventory DECIMAL(10,0) DEFAULT 0 COMMENT 'inventory';
+
+-- 初始库存表 修改库存类型
+ALTER TABLE jsh_material_initial_stock
+  MODIFY number DECIMAL(24,0) DEFAULT NULL COMMENT '初始库存数量',
+  MODIFY low_safe_stock DECIMAL(24,0) DEFAULT NULL COMMENT '最低库存数量',
+  MODIFY high_safe_stock DECIMAL(24,0) DEFAULT NULL COMMENT '最高库存数量';
+
+-- 当前库存表 修改价格、库存类型
+ALTER TABLE jsh_material_current_stock
+  MODIFY current_number DECIMAL(24,0) DEFAULT NULL COMMENT '当前库存数量',
+  MODIFY current_unit_price DECIMAL(24,2) DEFAULT NULL COMMENT '当前价格';
+
+-- 单据主表 新增提交时间
+ALTER TABLE jsh_depot_head
+  ADD COLUMN submit_time DATETIME DEFAULT NULL COMMENT '提交时间';
+
+-- 单据子表  新增生产日期、保质期天数、仓位货架、销售价格
+ALTER TABLE jsh_depot_item
+  ADD COLUMN production_date DATETIME DEFAULT NULL COMMENT '生产日期',
+  ADD COLUMN expiry_num INT DEFAULT NULL COMMENT '保质期天数',
+  ADD COLUMN position VARCHAR(255) DEFAULT NULL COMMENT '仓位货架',
+  ADD COLUMN wholesale_decimal DECIMAL(24,2) DEFAULT NULL COMMENT '销售价格';
+
+-- 商品子表 新增单位比例
+ALTER TABLE jsh_material_extend
+  ADD COLUMN ratio INT DEFAULT NULL COMMENT '单位比例';
+
+-- 初始库存表 新增仓位货架
+ALTER TABLE jsh_material_initial_stock
+  ADD COLUMN position VARCHAR(255) DEFAULT NULL COMMENT '仓位货架';
+
+-- 商品批次信息表
+DROP TABLE IF EXISTS `material_batch`;
+CREATE TABLE `material_batch` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `material_id` bigint DEFAULT NULL COMMENT '商品id',
+  `commodity_unit` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品单位',
+  `sku` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '多属性',
+  `purchase_decimal` decimal(24,2) DEFAULT NULL COMMENT '采购价格',
+  `commodity_decimal` decimal(24,2) DEFAULT NULL COMMENT '零售价格',
+  `wholesale_decimal` decimal(24,2) DEFAULT NULL COMMENT '销售价格',
+  `low_decimal` decimal(24,2) DEFAULT NULL COMMENT '最低售价',
+  `default_flag` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '1' COMMENT '是否为默认单位,1是,0否',
+  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
+  `create_serial` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建人编码',
+  `update_serial` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新人编码',
+  `update_time` bigint DEFAULT NULL COMMENT '更新时间戳',
+  `tenant_id` bigint DEFAULT NULL COMMENT '租户id',
+  `delete_Flag` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1删除',
+  `production_date` datetime DEFAULT NULL COMMENT '生产日期',
+  `expiry_num` int DEFAULT NULL COMMENT '保质期天数',
+  `supplier_id` bigint DEFAULT NULL COMMENT '供应商id',
+  `bar_code` varchar(50) DEFAULT NULL COMMENT '商品条码',
+  `batch_number` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '批次号',
+  `inventory` decimal(10,0) DEFAULT '0' COMMENT 'inventory',
+  `depot_id` bigint DEFAULT NULL COMMENT '仓库id',
+  `position` varchar(255) DEFAULT NULL COMMENT '仓位货架',
+  `depot_item_id` bigint DEFAULT NULL COMMENT '单据id',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='商品批次信息表';
+
+
+
+
+
+
+

+ 1 - 1
jshERP-web/src/components/jeecg/JEditableTable.vue

@@ -481,7 +481,7 @@
 
                     <!-- update-begin-author:jsh date:20210308 for:popupJsh -->
                     <template v-else-if="col.type === formTypes.popupJsh">
-                      <div :key="i">
+                      <div style="max-width: 190px" :key="i">
                         <a-tooltip
                           :id="id"
                           placement="top"

+ 42 - 0
jshERP-web/src/components/jeecgbiz/JSelectList.vue

@@ -31,6 +31,37 @@
       </a-select>
       <a-button icon="search" @click="onSearch" />
     </a-input-group>
+    <a-input-group v-if="kind === 'material2'" compact style="width: 100%; top: 0px">
+      <a-select
+        placeholder="输入商品条码"
+        :dropdownMatchSelectWidth="false"
+        showSearch
+        :showArrow="false"
+        v-model="names"
+        optionFilterProp="children"
+        :style="searchWidth"
+        notFoundContent="需在商品管理先新增才能使用"
+        @search="handleSearch"
+        @change="handleChange"
+        style="width: 100%"
+      >
+        <div slot="dropdownRender" slot-scope="menu">
+          <v-nodes :vnodes="menu" />
+          <a-divider v-if="materialData.length === 20" style="margin: 4px 0" />
+          <div
+            v-if="materialData.length === 20"
+            style="padding: 4px 8px; cursor: pointer"
+            @mousedown="(e) => e.preventDefault()"
+          >
+            此处最多显示20条,如需更多请点击放大镜查询
+          </div>
+        </div>
+        <a-select-option v-for="item in materialData" :key="item.batchNumber">
+          {{ item.batchNumber }}
+        </a-select-option>
+      </a-select>
+      <a-button icon="search" @click="onSearch" />
+    </a-input-group>
     <a-input-search
       v-if="kind === 'batch' || kind === 'sn' || kind === 'snAdd'"
       v-model="names"
@@ -47,6 +78,15 @@
       @ok="selectOK"
       @initComp="initComp"
     />
+    <j-select-material-modal2
+      v-if="kind === 'material2'"
+      ref="selectModal"
+      :rows="rows"
+      :multi="multi"
+      :bar-code="value"
+      @ok="selectOK"
+      @initComp="initComp"
+    />
     <j-select-batch-modal
       v-if="kind === 'batch'"
       ref="selectModal"
@@ -79,6 +119,7 @@
 
 <script>
 import JSelectMaterialModal from './modal/JSelectMaterialModal'
+import JSelectMaterialModal2 from './modal/JSelectMaterialModal2'
 import JSelectBatchModal from './modal/JSelectBatchModal'
 import JSelectSnModal from './modal/JSelectSnModal'
 import JSelectSnAddModal from './modal/JSelectSnAddModal'
@@ -88,6 +129,7 @@ export default {
   name: 'JSelectList',
   components: {
     JSelectMaterialModal,
+    JSelectMaterialModal2,
     JSelectBatchModal,
     JSelectSnModal,
     JSelectSnAddModal,

+ 522 - 0
jshERP-web/src/components/jeecgbiz/modal/JSelectMaterialModal2.vue

@@ -0,0 +1,522 @@
+<template>
+  <a-modal
+    :width="modalWidth"
+    :visible="visible"
+    :title="title"
+    :wrapClassName="wrapClassNameInfo()"
+    @ok="handleSubmit"
+    @cancel="close"
+    cancelText="关闭(ESC)"
+    style="top: 20px; height: 95%"
+  >
+    <a-row :gutter="10" style="padding: 10px; margin: -10px">
+      <a-col :md="24" :sm="24">
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+          <!-- 搜索区域 -->
+          <a-form layout="inline" @keyup.enter.native="onSearch">
+            <a-row :gutter="24">
+              <a-col :md="6" :sm="8">
+                <a-form-item label="关键词" :labelCol="labelCol" :wrapperCol="wrapperCol">
+                  <a-input ref="material" placeholder="请输入条码、名称、助记码等查询" v-model="queryParam.q"></a-input>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="8">
+                <a-form-item label="规格型号" :labelCol="labelCol" :wrapperCol="wrapperCol">
+                  <a-input placeholder="请输入规格、型号" v-model="queryParam.standardOrModel"></a-input>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="8">
+                <a-form-item label="颜色" :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
+                  <a-input placeholder="请输入颜色" v-model="queryParam.color"></a-input>
+                </a-form-item>
+              </a-col>
+              <!-- <a-col :md="6" :sm="8">
+                <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="仓库">
+                  <a-select
+                    placeholder="选择仓库"
+                    v-model="queryParam.depotId"
+                    @change="onDepotChange"
+                    :dropdownMatchSelectWidth="false"
+                    showSearch
+                    optionFilterProp="children"
+                    allow-clear
+                  >
+                    <a-select-option v-for="(item, index) in depotList" :key="index" :value="item.id">
+                      {{ item.depotName }}
+                    </a-select-option>
+                  </a-select>
+                </a-form-item>
+              </a-col> -->
+              <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+                <a-col :md="6" :sm="8">
+                  <a-button type="primary" @click="loadMaterialData(1)">查询</a-button>
+                  <a-button style="margin-left: 8px" @click="searchReset(1)">重置</a-button>
+                  <a-tooltip title="没查询到,决定新增商品!">
+                    <a-button style="margin-left: 8px" @click="addMaterial">新增</a-button>
+                  </a-tooltip>
+                  <a @click="handleToggleSearch" style="margin-left: 8px">
+                    {{ toggleSearchStatus ? '收起' : '展开' }}
+                    <a-icon :type="toggleSearchStatus ? 'up' : 'down'" />
+                  </a>
+                </a-col>
+              </span>
+              <template v-if="toggleSearchStatus">
+          
+                <a-col :md="6" :sm="8">
+                  <a-form-item label="品牌" :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
+                    <a-input placeholder="请输入品牌" v-model="queryParam.brand"></a-input>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="8">
+                  <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="类别">
+                    <a-tree-select
+                      style="width: 100%"
+                      :dropdownStyle="{ maxHeight: '200px', overflow: 'auto' }"
+                      allow-clear
+                      :treeData="categoryTree"
+                      v-model="queryParam.categoryId"
+                      placeholder="请选择类别"
+                    >
+                    </a-tree-select>
+                  </a-form-item>
+                </a-col>
+                <!-- <a-col :md="6" :sm="8">
+                  <a-form-item label="制造商" :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
+                    <a-input placeholder="请输入制造商" v-model="queryParam.mfrs"></a-input>
+                  </a-form-item>
+                </a-col> -->
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="序列号" :labelCol="labelCol" :wrapperCol="wrapperCol">
+                    <a-select placeholder="有无序列号" v-model="queryParam.enableSerialNumber">
+                      <a-select-option value="1">有</a-select-option>
+                      <a-select-option value="0">无</a-select-option>
+                    </a-select>
+                  </a-form-item>
+                </a-col>
+                <!-- <a-col :md="6" :sm="24">
+                  <a-form-item label="仓库货架" :labelCol="labelCol" :wrapperCol="wrapperCol">
+                    <a-input placeholder="请输入仓库货架" v-model="queryParam.position"></a-input>
+                  </a-form-item>
+                </a-col> -->
+                <!-- <a-col :md="6" :sm="24">
+                  <a-form-item label="批号" :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
+                    <a-select placeholder="有无批号" v-model="queryParam.enableBatchNumber">
+                      <a-select-option value="1">有</a-select-option>
+                      <a-select-option value="0">无</a-select-option>
+                    </a-select>
+                  </a-form-item>
+                </a-col> -->
+              </template>
+            </a-row>
+          </a-form>
+          <a-button v-if="isStock" type="primary" @click="findAllSelect">一键全选</a-button>
+          <a-table
+            ref="table"
+            :scroll="scrollTrigger"
+            size="middle"
+            rowKey="id"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="ipagination"
+            :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: getType }"
+            :loading="loading"
+            :customRow="rowAction"
+            @change="handleTableChange"
+          >
+            <template slot="customBarCode" slot-scope="text, record">
+              <div :style="record.imgName ? 'float:left;line-height:30px' : 'float:left;'">{{ record.mBarCode }}</div>
+              <a-popover placement="right" trigger="click">
+                <template slot="content">
+                  <img :src="getImgUrl(record.imgName, record.imgLarge)" width="500px" />
+                </template>
+                <div class="item-info" v-if="record.imgName">
+                  <img
+                    v-if="record.imgName"
+                    :src="getImgUrl(record.imgName, record.imgSmall)"
+                    class="item-img"
+                    title="查看大图"
+                  />
+                </div>
+              </a-popover>
+            </template>
+            <template slot="customName" slot-scope="text, record">
+              {{ record.name }}
+              <a-tag v-if="record.enableSerialNumber == 1" color="orange">序</a-tag>
+              <a-tag v-if="record.enableBatchNumber == 1" color="orange">批</a-tag>
+            </template>
+            <span slot="action" slot-scope="text, record">
+              <a @click.stop="handleEdit(record)">编辑</a>
+            </span>
+          </a-table>
+        </div>
+      </a-col>
+    </a-row>
+    <material-modal ref="modalForm" @ok="modalFormOk"></material-modal>
+  </a-modal>
+</template>
+
+<script>
+import { getAction, getFileAccessHttpUrl } from '@/api/manage'
+import { filterObj, getMpListShort } from '@/utils/util'
+import { getMaterialBySelect, queryMaterialCategoryTreeList, getMaterialById } from '@/api/api'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import { mixinDevice } from '@/utils/mixin'
+import Vue from 'vue'
+
+export default {
+  name: 'JSelectMaterialModal',
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    MaterialModal: () => import('@/views/material/modules/MaterialModal'),
+  },
+  props: ['rows', 'multi', 'barCode', 'isStock'],
+  data() {
+    return {
+      modalWidth: 1450,
+      queryParam: {
+        q: '',
+        standardOrModel: '',
+        color: '',
+        brand: '',
+        categoryId: undefined,
+        mfrs: '',
+        enableSerialNumber: undefined,
+        enableBatchNumber: undefined,
+        position: '',
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      categoryTree: [],
+      columns: [
+        {
+          title: '操作',
+          dataIndex: 'action',
+          align: 'center',
+          width: 60,
+          scopedSlots: { customRender: 'action' },
+        },
+        // { dataIndex: 'mBarCode', title: '条码', scopedSlots: { customRender: 'customBarCode' } },
+        // { dataIndex: 'batchNumber', title: '批次号' },
+        { dataIndex: 'barCode', title: '商品条码' },
+        { dataIndex: 'name', title: '名称', scopedSlots: { customRender: 'customName' } },
+        { dataIndex: 'categoryName', title: '类别' },
+        // { dataIndex: 'standard', title: '规格' },
+        { dataIndex: 'model', title: '型号' },
+        { dataIndex: 'color', title: '颜色' },
+        { dataIndex: 'brand', title: '品牌' },
+        // { dataIndex: 'supplierName', title: '供应商' },
+        { dataIndex: 'unit', title: '单位' },
+        { dataIndex: 'sku', title: '多属性' },
+        { dataIndex: 'inventory', title: '库存' },
+        // { dataIndex: 'productionDate', title: '生产日期' },
+        // { dataIndex: 'expiryNum', title: '保质期' },
+        // { dataIndex: 'barCode', title: '商品条码' },
+        // { dataIndex: 'depotName', title: '仓库名称' },
+        // { dataIndex: 'position', title: '仓库货架' },
+
+        // { dataIndex: 'expand', title: '扩展信息' },
+      ],
+      scrollTrigger: {},
+      dataSource: [],
+      selectedRowKeys: [],
+      selectMaterialRows: [],
+      selectMaterialIds: [],
+      title: '选择商品',
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0,
+      },
+      isorter: {
+        column: 'createTime',
+        order: 'desc',
+      },
+      departTree: [],
+      depotList: [],
+      visible: false,
+      form: this.$form.createForm(this),
+      loading: false,
+      expandedKeys: [],
+      disableMixinCreated: true,
+    }
+  },
+  computed: {
+    // 计算属性的 getter
+    getType: function () {
+      return this.multi == true ? 'checkbox' : 'radio'
+    },
+  },
+  watch: {
+    barCode: {
+      immediate: true,
+      handler() {
+        this.initBarCode()
+      },
+    },
+  },
+  created() {
+    // 该方法触发屏幕自适应
+    this.resetScreenSize()
+  },
+  methods: {
+    initBarCode() {
+      if (this.barCode) {
+        this.$emit('initComp', this.barCode)
+      } else {
+        // JSelectUserByDep组件bug issues/I16634
+        this.$emit('initComp', '')
+      }
+    },
+    loadMaterialData(arg) {
+      if (arg === 1) {
+        this.ipagination.current = 1
+      }
+      this.loading = true
+      let params = this.getQueryParams() //查询条件
+      getMaterialBySelect(params).then((res) => {
+        if (res) {
+          this.dataSource = res.rows
+          this.ipagination.total = res.total
+          if (res.total === 1) {
+            if (
+              this.queryParam.q === this.dataSource[0].barCode ||
+              this.queryParam.q === this.dataSource[0].name ||
+              this.queryParam.q === this.dataSource[0].mnemonic
+            ) {
+              this.title = '选择商品【再次回车可以直接选中】'
+              this.$nextTick(() => this.$refs.material.focus())
+            } else {
+              this.title = '选择商品'
+            }
+          } else {
+            this.title = '选择商品'
+          }
+        }
+        this.loading = false
+        this.onClearSelected()
+      })
+    },
+    loadTreeData() {
+      let that = this
+      let params = {}
+      params.id = ''
+      queryMaterialCategoryTreeList(params).then((res) => {
+        if (res) {
+          that.categoryTree = []
+          for (let i = 0; i < res.length; i++) {
+            let temp = res[i]
+            that.categoryTree.push(temp)
+          }
+        }
+      })
+    },
+    // 触发屏幕自适应
+    resetScreenSize() {
+      let realScreenWidth = window.screen.width
+      this.modalWidth = realScreenWidth < 1600 ? '1300px' : '1550px'
+      let screenWidth = document.body.clientWidth
+      if (screenWidth < 500) {
+        this.scrollTrigger = { x: 800 }
+      } else {
+        this.scrollTrigger = {}
+      }
+    },
+    showModal(barCode) {
+      this.visible = true
+      this.title = '选择商品'
+      this.queryParam.q = barCode
+      this.$nextTick(() => this.$refs.material.focus())
+      this.loadTreeData()
+      // this.getDepotList()
+      // this.initDepotSelect()
+      this.loadMaterialData()
+      this.form.resetFields()
+    },
+    getQueryParams() {
+      let param = Object.assign({}, this.queryParam, this.isorter)
+      param.mpList = getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
+      param.page = this.ipagination.current
+      param.rows = this.ipagination.pageSize
+      return filterObj(param)
+    },
+    getQueryField() {
+      let str = 'id,'
+      for (let a = 0; a < this.columns.length; a++) {
+        str += ',' + this.columns[a].dataIndex
+      }
+      return str
+    },
+    searchReset(num) {
+      let that = this
+      if (num !== 0) {
+        that.queryParam = {}
+        that.loadMaterialData(1)
+      }
+      that.selectedRowKeys = []
+      that.selectMaterialIds = []
+    },
+    addMaterial() {
+      this.$refs.modalForm.add()
+      this.$refs.modalForm.title = '新增商品'
+    },
+    handleEdit(record) {
+      getMaterialById({ mid: record.mid }).then((res) => {
+        this.$refs.modalForm.edit(res.data)
+        this.$refs.modalForm.title = '编辑'
+        this.$refs.modalForm.disableSubmit = false
+        this.$refs.modalForm.showOkFlag = true
+      })
+    },
+    getImgUrl(imgName, type) {
+      if (imgName && imgName.split(',')) {
+        type = type ? type + '/' : ''
+        return getFileAccessHttpUrl('systemConfig/static/' + type + imgName.split(',')[0])
+      } else {
+        return ''
+      }
+    },
+    close() {
+      this.searchReset(0)
+      this.visible = false
+    },
+    handleTableChange(pagination, filters, sorter) {
+      if (Object.keys(sorter).length > 0) {
+        this.isorter.column = sorter.field
+        this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc'
+      }
+      this.ipagination = pagination
+      this.loadMaterialData()
+    },
+    handleSubmit() {
+      let that = this
+      this.getSelectMaterialRows()
+      that.$emit('ok', that.selectMaterialRows, that.selectMaterialIds)
+      that.searchReset(0)
+      that.close()
+    },
+    //获取选择信息
+    getSelectMaterialRows(rowId) {
+      let dataSource = this.dataSource
+      let materialIds = ''
+      this.selectMaterialRows = []
+      console.log('getSelectMaterialRows', this.selectedRowKeys)
+      for (let i = 0, len = dataSource.length; i < len; i++) {
+        if (this.selectedRowKeys.includes(dataSource[i].id)) {
+          this.selectMaterialRows.push(dataSource[i])
+          materialIds = materialIds + ',' + dataSource[i].barCode
+        }
+      }
+      console.log('materialIds=====',materialIds)
+      this.selectMaterialIds = materialIds.substring(1)
+    },
+    getDepotList() {
+      let that = this
+      getAction('/depot/findDepotByCurrentUser').then((res) => {
+        if (res.code === 200) {
+          that.depotList = res.data
+        }
+      })
+    },
+    // initDepotSelect() {
+    //   if (this.rows) {
+    //     if (JSON.parse(this.rows).depotId) {
+    //       const id = JSON.parse(this.rows).depotId - 0
+    //       this.queryParam.depotId = id + ''
+    //     }
+    //   }
+    // },
+    // onDepotChange(value) {
+    //   this.queryParam.depotId = value
+    // },
+    onSelectChange(selectedRowKeys, selectionRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectionRows = selectionRows
+      console.log('onSelectChange', selectedRowKeys, selectionRows)
+    },
+    onSearch() {
+      if (this.dataSource && this.dataSource.length === 1) {
+        if (
+          this.queryParam.q === this.dataSource[0].mBarCode ||
+          this.queryParam.q === this.dataSource[0].name ||
+          this.queryParam.q === this.dataSource[0].mnemonic
+        ) {
+          let arr = []
+          arr.push(this.dataSource[0].id)
+          this.selectedRowKeys = arr
+          this.handleSubmit()
+        } else {
+          this.loadMaterialData(1)
+        }
+      } else {
+        this.loadMaterialData(1)
+      }
+    },
+    modalFormOk() {
+      this.loadMaterialData()
+    },
+    rowAction(record, index) {
+      return {
+        on: {
+          click: () => {
+            let arr = []
+            arr.push(record.id)
+            this.selectedRowKeys = arr
+          },
+          dblclick: () => {
+            let arr = []
+            arr.push(record.id)
+            this.selectedRowKeys = arr
+            this.handleSubmit()
+          },
+        },
+      }
+    },
+    findAllSelect() {
+      this.$emit('all', this.queryParam)
+    },
+  },
+}
+</script>
+
+<style scoped>
+.ant-table-tbody .ant-table-row td {
+  padding-top: 10px;
+  padding-bottom: 10px;
+}
+
+#components-layout-demo-custom-trigger .trigger {
+  font-size: 18px;
+  line-height: 64px;
+  padding: 0 24px;
+  cursor: pointer;
+  transition: color 0.3s;
+}
+
+.item-info {
+  float: left;
+  width: 30px;
+  height: 30px;
+  margin-left: 8px;
+}
+.item-img {
+  cursor: pointer;
+  position: static;
+  display: block;
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+</style>

+ 1 - 0
jshERP-web/src/utils/JEditableTableUtil.js

@@ -63,6 +63,7 @@ export function validateFormAndTables(form, cases) {
     })
   })
     .then((values) => {
+      console.log(11111,values)
       Object.assign(options, { formValue: values })
       // 验证所有子表的表单
       return validateTables(cases)

+ 6 - 6
jshERP-web/src/views/bill/dialog/BillDetail.vue

@@ -1640,7 +1640,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '序列号', dataIndex: 'snList', width: 300 },
         { title: '有效期', dataIndex: 'expirationDate', width: 90 },
@@ -1746,7 +1746,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '序列号', dataIndex: 'snList', width: 300 },
         { title: '有效期', dataIndex: 'expirationDate', width: 90 },
@@ -1786,7 +1786,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '序列号', dataIndex: 'snList', width: 300 },
         { title: '有效期', dataIndex: 'expirationDate', width: 90 },
@@ -1852,7 +1852,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '序列号', dataIndex: 'snList', width: 300 },
         { title: '有效期', dataIndex: 'expirationDate', width: 90 },
@@ -1887,7 +1887,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '序列号', dataIndex: 'snList', width: 300 },
         { title: '有效期', dataIndex: 'expirationDate', width: 90 },
@@ -1923,7 +1923,7 @@ export default {
         { title: '品牌', dataIndex: 'brand', width: 90 },
         { title: '制造商', dataIndex: 'mfrs', width: 90 },
         { title: '扩展信息', dataIndex: 'materialOther', width: 90 },
-        { title: '库存', dataIndex: 'stock', width: 90 },
+        { title: '库存', dataIndex: 'inventory', width: 90 },
         { title: '调入仓库', dataIndex: 'anotherDepotName' },
         { title: '单位', dataIndex: 'unit', width: 90 },
         { title: '多属性', dataIndex: 'sku' },

+ 97 - 3
jshERP-web/src/views/bill/mixins/BillModalMixin.js

@@ -8,6 +8,8 @@ import {
   getBatchNumberList,
   getCurrentSystemConfig,
   getMaterialByBatchNumber,
+  getMaterialByBarCode,
+  getMaterialBySelect,
   getPersonByNumType,
   getPlatformConfigByKey,
   getUnitInfo,
@@ -82,6 +84,9 @@ export const BillModalMixin = {
   },
   watch:{
     $route(to, from) {
+      if(this.handleCancel){
+        this.handleCancel()
+      }
       this.visible = false
     }
   },
@@ -383,8 +388,6 @@ export const BillModalMixin = {
       this.initRetail(1)
     },
     batchSetDepotModalFormOk(depotId) {
-      console.log('22222222222222222211')
-
       this.getAllTable()
         .then((tables) => {
           return getListData(this.form, tables)
@@ -471,7 +474,35 @@ export const BillModalMixin = {
         })
       }
     },
-
+    //根据【仓库名】带出对应的【仓位货架】
+    async setProPosition(barCode, depotId, event){
+      const { row, column, value, target } = event
+      const res = await getMaterialBySelect({
+        q: barCode,
+        page: 1,
+        rows: 20
+      })
+      let proDetail
+      if (res && res.rows) {
+        proDetail = res.rows[0]? res.rows[0] : {}
+      }
+      // 商品id
+      if(proDetail.mid){
+        const res2 = await getAction('/material/getPositionByDidAndMid', { mid: proDetail.mid, did: depotId })
+        console.log('getPositionByDidAndMid======',res2)
+        if (res2 && res2.code === 200) {
+          const msg = res2.msg
+          if(msg){
+            target.setValues([
+              {
+                rowKey: row.id,
+                values: { position: msg },
+              },
+            ])
+          }
+        }
+      }
+    },
     //单元值改变一个字符就触发一次
     onValueChange(event) {
       let that = this
@@ -483,6 +514,16 @@ export const BillModalMixin = {
           if (row.barCode) {
             that.getStockByDepotBarCode(row, target)
           }
+          console.log('row========', row)
+          // // 选择商品自动带出barCode、商品ID
+          if(row.depotId&&row.barCode){
+            // console.log('row.depotId========', row.depotId)
+            // // 根据仓库id自动带出仓位货架(若有)参数:商品id、仓库id
+            // getAction('/material/getPositionByDidAndMid',{mid:row.mid,did:row.depotId}).then((res) => {
+            //   console.log('res========', res)
+            // })
+            this.setProPosition(row.barCode, row.depotId, event)
+          }
           break
         case 'batchNumber':
           param = {
@@ -566,6 +607,58 @@ export const BillModalMixin = {
             }
           })
           break
+        case 'barCode':
+          param = {
+            barCode: value,
+            organId: this.form.getFieldValue('organId'),
+            mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
+            prefixNo: this.prefixNo,
+          }
+          getMaterialByBarCode(param).then((res) => {
+            if (res && res.code === 200) {
+              let mList = res.data
+              target.getValues((error, values) => {
+                const clickRowIndex = values.findIndex((item) => item.id === row.id) //获取当前行的索引
+                // values.pop() //移除最后一行数据
+                values.splice(clickRowIndex, 1) //移除当前行数据
+                let mArr = values // 新加的行
+                for (let i = 0; i < mList.length; i++) {
+                  let mInfo = mList[i]
+                  if (mInfo.unitId) {
+                    mInfo.unitList = JSON.stringify(mInfo.unitList)
+                  }
+                  this.changeColumnShow(mInfo)
+                  let mObj = this.parseInfoToObj(mInfo)
+                  mObj.depotId = mInfo.depotId
+                  mObj.stock = mInfo.stock
+                  mObj.inventory = mInfo.inventory
+                  mArr.push(mObj)
+                }
+                let allPriceTotal = 0
+                let taxLastMoneyTotal = 0
+                for (let j = 0; j < mArr.length; j++) {
+                  allPriceTotal += mArr[j].allPrice - 0
+                  taxLastMoneyTotal += mArr[j].taxLastMoney - 0
+                  //组合和拆分单据给商品类型进行重新赋值
+                  if (j === 0) {
+                    mArr[0].mType = '组合件'
+                  } else {
+                    mArr[j].mType = '普通子件'
+                  }
+                }
+                this.materialTable.dataSource = mArr
+                if (this.prefixNo === 'LSCK' || this.prefixNo === 'LSTH') {
+                  target.statisticsColumns.allPrice = allPriceTotal
+                } else {
+                  target.statisticsColumns.taxLastMoney = taxLastMoneyTotal
+                }
+                that.autoChangePrice(target)
+                //强制渲染
+                target.$forceUpdate()
+              })
+            }
+          })
+          break
         case 'snList':
           snList = value
           if (snList) {
@@ -751,6 +844,7 @@ export const BillModalMixin = {
         unitId: mInfo.unitId,
         unitList: mInfo.unitList,
         depotId: mInfo.depotId,
+        inventory: mInfo.inventory,
       }
     },
     //使得型号、颜色、扩展信息、sku等为隐藏

+ 1 - 1
jshERP-web/src/views/bill/modules/AllocationOutModal.vue

@@ -233,7 +233,7 @@ export default {
           { title: '品牌', key: 'brand', width: '9%', type: FormTypes.normal },
           { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
           { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'stock', width: '5%', type: FormTypes.normal },
+          { title: '库存', key: 'inventory', width: '5%', type: FormTypes.normal },
           {
             title: '调入仓库',
             key: 'anotherDepotId',

+ 56 - 43
jshERP-web/src/views/bill/modules/OtherInModal.vue

@@ -283,76 +283,89 @@ export default {
           // },
           // { title: '批次号', key: 'batchNumber', width: '9%', type: FormTypes.normal },
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
           // { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.normal },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '7%', type: FormTypes.normal },
+          {
+            title: '生产日期',
+            key: 'productionDate',
+            width: '200px',
+            type: FormTypes.datetime,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
+          },
+          { title: '保质期', key: 'expiryNum', width: '120px', type: FormTypes.inputNumber },
+          // { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.input },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '9%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '9%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'stock', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'stock', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'snAdd', multi: true },
-          { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.date },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
-          { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
-          { title: '已入库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
+          {
+            title: '销售价',
+            key: 'wholesaleDecimal',
+            width: '120px',
+            type: FormTypes.input,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
+          },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '序列号', key: 'snList', width: '120px', type: FormTypes.popupJsh, kind: 'snAdd', multi: true },
+          { title: '有效期', key: 'expirationDate', width: '120px', type: FormTypes.date },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
+          { title: '原数量', key: 'preNumber', width: '120px', type: FormTypes.normal },
+          { title: '已入库', key: 'finishNumber', width: '120px', type: FormTypes.normal },
           {
             title: '入库数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
           {
             title: '实际入库数量',
             key: 'actualQuantityInStorage',
-            width: '9%',
+            width: '120px',
             type: FormTypes.inputNumber,
             validateRules: [{ required: true, message: '实际入库数量不能为空' }],
           },
-          { title: '入库差异', key: 'warehousingVariance', width: '9%', type: FormTypes.input },
-          { title: '入库差异原因', key: 'reasonOfDifference', width: '9%', type: FormTypes.input },
+          { title: '入库差异', key: 'warehousingVariance', width: '120px', type: FormTypes.input },
+          { title: '入库差异原因', key: 'reasonOfDifference', width: '120px', type: FormTypes.input },
           {
             title: '入库人',
             key: 'warehousingUser',
-            width: '9%',
+            width: '120px',
             type: FormTypes.slot,
             slotName: 'warehousingUser',
             validateRules: [{ required: true, message: '入库人不能为空' }],
           },
-          { title: '入库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
-          { title: '备注', key: 'remark', width: '5%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '入库时间', key: 'warehousingTime', width: '200px', type: FormTypes.date },
+          { title: '备注', key: 'remark', width: '200px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,
@@ -394,10 +407,10 @@ export default {
         this.fileList = []
         this.imageList = []
       } else {
-        if (this.model.linkNumber) {
-          this.rowCanEdit = false
-          this.materialTable.columns[1].type = FormTypes.normal
-        }
+        // if (this.model.linkNumber) {
+        //   this.rowCanEdit = false
+        //   this.materialTable.columns[1].type = FormTypes.normal
+        // }
         this.model.operTime = this.model.operTimeStr
         this.fileList = this.model.fileName
         this.imageList = this.model.voucherPicture

+ 44 - 43
jshERP-web/src/views/bill/modules/OtherOutModal.vue

@@ -282,78 +282,79 @@ export default {
           //   validateRules: [{ required: true, message: '${title}不能为空' }],
           // },
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             newBatch: true,
 
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
           // { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal, disabled: true },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.select, disabled: true },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '7%', type: FormTypes.normal },
+          // { title: '生产日期', key: 'productionDate', width: '200px', type: FormTypes.normal, disabled: true },
+          // { title: '保质期', key: 'expiryNum', width: '120px', type: FormTypes.normal },
+          // { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.normal },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '9%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '9%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'stock', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'stock', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
-          { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.input, readonly: true },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
-          { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
-          { title: '已入库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
+          { title: '销售价', key: 'wholesaleDecimal', width: '120px', type: FormTypes.input },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '序列号', key: 'snList', width: '120px', type: FormTypes.popupJsh, kind: 'sn', multi: true },
+          // { title: '有效期', key: 'expirationDate', width: '120px', type: FormTypes.date, readonly: true },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
+          { title: '原数量', key: 'preNumber', width: '120px', type: FormTypes.normal },
+          { title: '已入库', key: 'finishNumber', width: '120px', type: FormTypes.normal },
           {
             title: '出库数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
           {
             title: '实际出库数量',
             key: 'actualQuantityInStorage',
-            width: '9%',
+            width: '120px',
             type: FormTypes.inputNumber,
             validateRules: [{ required: true, message: '实际入库数量不能为空' }],
           },
-          { title: '出库差异', key: 'warehousingVariance', width: '9%', type: FormTypes.input },
-          { title: '出库差异原因', key: 'reasonOfDifference', width: '9%', type: FormTypes.input },
+          { title: '出库差异', key: 'warehousingVariance', width: '120px', type: FormTypes.input },
+          { title: '出库差异原因', key: 'reasonOfDifference', width: '120px', type: FormTypes.input },
           {
             title: '出库人',
             key: 'warehousingUser',
-            width: '9%',
+            width: '120px',
             type: FormTypes.slot,
             slotName: 'warehousingUser',
             validateRules: [{ required: true, message: '出库人不能为空' }],
           },
-          { title: '出库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
-          { title: '备注', key: 'remark', width: '5%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '出库时间', key: 'warehousingTime', width: '200px', type: FormTypes.date },
+          { title: '备注', key: 'remark', width: '120px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,
@@ -395,10 +396,10 @@ export default {
         this.fileList = []
         this.imageList = []
       } else {
-        if (this.model.linkNumber) {
-          this.rowCanEdit = false
-          this.materialTable.columns[1].type = FormTypes.normal
-        }
+        // if (this.model.linkNumber) {
+        //   this.rowCanEdit = false
+        //   this.materialTable.columns[1].type = FormTypes.normal
+        // }
         this.model.operTime = this.model.operTimeStr
         this.fileList = this.model.fileName
         this.imageList = this.model.voucherPicture

+ 67 - 54
jshERP-web/src/views/bill/modules/PurchaseInModal.vue

@@ -102,7 +102,7 @@
           :loading="materialTable.loading"
           :columns="materialTable.columns"
           :dataSource="materialTable.dataSource"
-          :minWidth="minWidth"
+          :minWidth="1200"
           :maxHeight="300"
           :rowNumber="false"
           :rowSelection="rowCanEdit"
@@ -461,90 +461,103 @@ export default {
           //   validateRules: [{ required: true, message: '${title}不能为空' }],
           // },
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             newBatch: true,
 
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '9%', type: FormTypes.normal },
-          { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
+          { title: '规格', key: 'standard', width: '120px', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal, disabled: true },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.select, disabled: true },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '7%', type: FormTypes.normal },
+          {
+            title: '生产日期',
+            key: 'productionDate',
+            width: '200px',
+            type: FormTypes.datetime,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
+          },
+          { title: '保质期', key: 'expiryNum', width: '120px', type: FormTypes.inputNumber },
+          // { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.input },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '9%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '9%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'inventory', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'inventory', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
+          },
+          {
+            title: '销售价',
+            key: 'wholesaleDecima',
+            width: '120px',
+            type: FormTypes.input,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'snAdd', multi: true },
-          { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.date },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
-          { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
-          { title: '已入库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '序列号', key: 'snList', width: '120px', type: FormTypes.popupJsh, kind: 'snAdd', multi: true },
+          { title: '有效期', key: 'expirationDate', width: '120px', type: FormTypes.date },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
+          { title: '原数量', key: 'preNumber', width: '120px', type: FormTypes.normal },
+          { title: '已入库', key: 'finishNumber', width: '120px', type: FormTypes.normal },
           {
             title: '入库数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '4%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
-          { title: '税率', key: 'taxRate', width: '4%', type: FormTypes.inputNumber, placeholder: '%' },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
+          { title: '税率', key: 'taxRate', width: '120px', type: FormTypes.inputNumber, placeholder: '%' },
           {
             title: '税额',
             key: 'taxMoney',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             readonly: true,
             statistics: true,
           },
-          { title: '价税合计', key: 'taxLastMoney', width: '7%', type: FormTypes.inputNumber, statistics: true },
+          { title: '价税合计', key: 'taxLastMoney', width: '120px', type: FormTypes.inputNumber, statistics: true },
 
-          {
-            title: '实际入库数量',
-            key: 'actualQuantityInStorage',
-            width: '9%',
-            type: FormTypes.inputNumber,
-            validateRules: [{ required: true, message: '实际入库数量不能为空' }],
-          },
-          { title: '入库差异', key: 'warehousingVariance', width: '9%', type: FormTypes.input },
-          { title: '入库差异原因', key: 'reasonOfDifference', width: '9%', type: FormTypes.input },
+          // {
+          //   title: '实际入库数量',
+          //   key: 'actualQuantityInStorage',
+          //   width: '120px',
+          //   type: FormTypes.inputNumber,
+          //   validateRules: [{ required: true, message: '实际入库数量不能为空' }],
+          // },
+          { title: '入库差异', key: 'warehousingVariance', width: '120px', type: FormTypes.input },
+          { title: '入库差异原因', key: 'reasonOfDifference', width: '120px', type: FormTypes.input },
           {
             title: '入库人',
             key: 'warehousingUser',
-            width: '9%',
+            width: '120px',
             type: FormTypes.slot,
             slotName: 'warehousingUser',
             validateRules: [{ required: true, message: '入库人不能为空' }],
           },
-          { title: '入库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
+          { title: '入库时间', key: 'warehousingTime', width: '200px', type: FormTypes.date },
 
-          { title: '备注', key: 'remark', width: '6%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '备注', key: 'remark', width: '200px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,
@@ -597,10 +610,10 @@ export default {
           handleIntroJs(this.prefixNo, 1)
         })
       } else {
-        if (this.model.linkNumber) {
-          this.rowCanEdit = false
-          this.materialTable.columns[0].type = FormTypes.normal
-        }
+        // if (this.model.linkNumber) {
+        //   this.rowCanEdit = false
+        //   this.materialTable.columns[0].type = FormTypes.normal
+        // }
         this.model.operTime = this.model.operTimeStr
         if (this.model.deposit) {
           this.depositStatus = true

+ 58 - 46
jshERP-web/src/views/bill/modules/PurchaseOrderModal.vue

@@ -115,12 +115,11 @@
           </a-col>
         </a-row>
         <j-editable-table
-          id="billModal"
           :ref="refKeys[0]"
           :loading="materialTable.loading"
           :columns="materialTable.columns"
           :dataSource="materialTable.dataSource"
-          :minWidth="minWidth"
+          :minWidth="1200"
           :maxHeight="300"
           :rowNumber="false"
           :rowSelection="rowCanEdit"
@@ -166,7 +165,7 @@
               <a-button icon="import" @click="onImport(prefixNo)">导入明细</a-button>
             </a-row>
           </template>
-          <template #unit="{ handleChange, handleFocus, value }">
+          <!-- <template #unit="{ handleChange, handleFocus, value }">
             <a-select
               placeholder="请选择"
               v-decorator="['unit']"
@@ -182,7 +181,7 @@
                 {{ item.name }}
               </a-select-option>
             </a-select>
-          </template>
+          </template> -->
         </j-editable-table>
         <a-row class="form-row" :gutter="24">
           <a-col :lg="24" :md="24" :sm="24">
@@ -387,6 +386,7 @@ export default {
     },
   },
   data() {
+    const that = this
     return {
       title: '操作',
       width: '1600px',
@@ -419,56 +419,68 @@ export default {
         loading: false,
         dataSource: [],
         columns: [
-          { title: '', key: 'hiddenKey', width: '1%', type: FormTypes.hidden },
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '10%', type: FormTypes.normal },
-          { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
+          { title: '规格', key: 'standard', width: '120px', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '6%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.select, disabled: true },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '6%', type: FormTypes.normal },
+          {
+            title: '生产日期',
+            key: 'productionDate',
+            width: '200px',
+            type: FormTypes.datetime,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
+          },
+          { title: '保质期', key: 'expiryNum', width: '120px', type: FormTypes.inputNumber },
+          // { title: '商品条码', key: 'barCode', width: '120px', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.input },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '6%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'inventory', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'inventory', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
-          { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
-          { title: '已采购', key: 'finishNumber', width: '4%', type: FormTypes.normal },
+          {
+            title: '销售价',
+            key: 'wholesaleDecima',
+            width: '120px',
+            type: FormTypes.input,
+            validateRules: [{ required: true, message: '${title}不能为空' }],
+          },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
+          { title: '原数量', key: 'preNumber', width: '120px', type: FormTypes.normal },
+          { title: '已采购', key: 'finishNumber', width: '120px', type: FormTypes.normal },
           {
             title: '数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
 
           // {
           //   title: '实际入库数量',
@@ -488,18 +500,18 @@ export default {
           // },
           // { title: '入库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
 
-          { title: '税率', key: 'taxRate', width: '4%', type: FormTypes.inputNumber, placeholder: '%' },
+          { title: '税率', key: 'taxRate', width: '120px', type: FormTypes.inputNumber, placeholder: '%' },
           {
             title: '税额',
             key: 'taxMoney',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             readonly: true,
             statistics: true,
           },
-          { title: '价税合计', key: 'taxLastMoney', width: '7%', type: FormTypes.inputNumber, statistics: true },
-          { title: '备注', key: 'remark', width: '6%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '价税合计', key: 'taxLastMoney', width: '120px', type: FormTypes.inputNumber, statistics: true },
+          { title: '备注', key: 'remark', width: '200px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,
@@ -527,7 +539,7 @@ export default {
       this.billStatus = '0'
       this.currentSelectDepotId = ''
       this.rowCanEdit = true
-      this.materialTable.columns[1].type = FormTypes.popupJsh
+      // this.materialTable.columns[1].type = FormTypes.popupJsh
       this.changeColumnHide()
       this.changeFormTypes(this.materialTable.columns, 'preNumber', 0)
       this.changeFormTypes(this.materialTable.columns, 'finishNumber', 0)
@@ -539,10 +551,10 @@ export default {
           handleIntroJs(this.prefixNo, 1)
         })
       } else {
-        if (this.model.linkNumber) {
-          this.rowCanEdit = false
-          this.materialTable.columns[1].type = FormTypes.normal
-        }
+        // if (this.model.linkNumber) {
+        //   this.rowCanEdit = false
+        //   this.materialTable.columns[1].type = FormTypes.normal
+        // }
         this.model.operTime = this.model.operTimeStr
         if (this.model.accountId == null && this.model.accountIdList) {
           this.model.accountId = 0

+ 38 - 38
jshERP-web/src/views/bill/modules/SaleOrderModal.vue

@@ -146,7 +146,7 @@
               <a-button icon="import" @click="onImport(prefixNo)">导入明细</a-button>
             </a-row>
           </template>
-          <template #unit="{ handleChange, handleFocus, value }">
+          <!-- <template #unit="{ handleChange, handleFocus, value }">
             <a-select
               placeholder="请选择"
               v-decorator="['unit']"
@@ -162,7 +162,7 @@
                 {{ item.name }}
               </a-select-option>
             </a-select>
-          </template>
+          </template> -->
         </j-editable-table>
         <a-row class="form-row" :gutter="24">
           <a-col :lg="24" :md="24" :sm="24">
@@ -385,68 +385,68 @@ export default {
         loading: false,
         dataSource: [],
         columns: [
-          { title: '', key: 'hiddenKey', width: '1%', type: FormTypes.hidden },
+          // { title: '', key: 'hiddenKey', width: '1%', type: FormTypes.hidden },
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
           // { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '6%', type: FormTypes.normal },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '6%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.select, disabled: true },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '6%', type: FormTypes.normal },
+          // { title: '生产日期', key: 'productionDate', width: '6%', type: FormTypes.normal },
+          // { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
+          // { title: '商品条码', key: 'barCode', width: '6%', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.input },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '6%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'stock', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'stock', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
-          { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.input, readonly: true },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '序列号', key: 'snList', width: '120px', type: FormTypes.popupJsh, kind: 'sn', multi: true },
+          // { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.input, readonly: true },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
           // { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
           // { title: '已出库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
           {
             title: '出库数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '4%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
-          { title: '税率', key: 'taxRate', width: '4%', type: FormTypes.inputNumber, placeholder: '%' },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
+          { title: '税率', key: 'taxRate', width: '120px', type: FormTypes.inputNumber, placeholder: '%' },
           {
             title: '税额',
             key: 'taxMoney',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             readonly: true,
             statistics: true,
           },
-          { title: '价税合计', key: 'taxLastMoney', width: '7%', type: FormTypes.inputNumber, statistics: true },
+          { title: '价税合计', key: 'taxLastMoney', width: '120px', type: FormTypes.inputNumber, statistics: true },
 
           // {
           //   title: '实际出库数量',
@@ -466,8 +466,8 @@ export default {
           // },
           // { title: '出库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
 
-          { title: '备注', key: 'remark', width: '6%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '备注', key: 'remark', width: '200px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,

+ 46 - 46
jshERP-web/src/views/bill/modules/SaleOutModal.vue

@@ -486,90 +486,90 @@ export default {
         dataSource: [],
         columns: [
           {
-            title: '批次号',
-            key: 'batchNumber',
-            width: '12%',
+            title: '商品条码',
+            key: 'barCode',
+            width: '200px',
             type: FormTypes.popupJsh,
-            kind: 'material',
+            kind: 'material2',
             multi: true,
             newBatch: true,
 
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '名称', key: 'name', width: '9%', type: FormTypes.normal },
+          { title: '名称', key: 'name', width: '120px', type: FormTypes.normal },
           // { title: '规格', key: 'standard', width: '9%', type: FormTypes.normal },
 
-          { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal, disabled: true },
-          { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
-          { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
-          { title: '仓库名', key: 'depotId', width: '9%', type: FormTypes.select, disabled: true },
-          { title: '仓库货架', key: 'position', width: '6%', type: FormTypes.normal },
-          { title: '包装规格', key: 'unitName', width: '7%', type: FormTypes.normal },
+          // { title: '生产日期', key: 'productionDate', width: '9%', type: FormTypes.normal, disabled: true },
+          // { title: '保质期', key: 'expiryNum', width: '6%', type: FormTypes.normal },
+          // { title: '商品条码', key: 'barCode', width: '9%', type: FormTypes.normal },
+          { title: '仓库名', key: 'depotId', width: '120px', type: FormTypes.select },
+          { title: '仓库货架', key: 'position', width: '120px', type: FormTypes.input },
+          { title: '包装规格', key: 'unitName', width: '120px', type: FormTypes.normal },
 
-          { title: '型号', key: 'model', width: '9%', type: FormTypes.normal },
-          { title: '颜色', key: 'color', width: '9%', type: FormTypes.normal },
-          { title: '品牌', key: 'brand', width: '9%', type: FormTypes.normal },
-          { title: '制造商', key: 'mfrs', width: '6%', type: FormTypes.normal },
-          { title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
-          { title: '库存', key: 'stock', width: '5%', type: FormTypes.normal },
+          { title: '型号', key: 'model', width: '120px', type: FormTypes.normal },
+          { title: '颜色', key: 'color', width: '120px', type: FormTypes.normal },
+          { title: '品牌', key: 'brand', width: '120px', type: FormTypes.normal },
+          { title: '制造商', key: 'mfrs', width: '120px', type: FormTypes.normal },
+          { title: '扩展信息', key: 'materialOther', width: '120px', type: FormTypes.normal },
+          { title: '库存', key: 'stock', width: '120px', type: FormTypes.normal },
           {
             title: '单位',
             key: 'unit',
-            width: '6%',
-            type: FormTypes.slot,
-            options: [],
-            allowClear: false,
-            slotName: 'unit',
+            width: '120px',
+            type: FormTypes.normal,
+            // options: [],
+            // allowClear: false,
+            // slotName: 'unit',
           },
-          { title: '单位id', key: 'unitId', width: '4%', type: FormTypes.hidden },
-          { title: '单位列表', key: 'unitList', width: '5%', type: FormTypes.hidden },
-          { title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
-          { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.input, readonly: true },
-          { title: '多属性', key: 'sku', width: '9%', type: FormTypes.normal },
-          { title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
-          { title: '已出库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
+          { title: '单位id', key: 'unitId', width: '120px', type: FormTypes.hidden },
+          { title: '单位列表', key: 'unitList', width: '120px', type: FormTypes.hidden },
+          { title: '序列号', key: 'snList', width: '120px', type: FormTypes.popupJsh, kind: 'sn', multi: true },
+          // { title: '有效期', key: 'expirationDate', width: '7%', type: FormTypes.input, readonly: true },
+          { title: '多属性', key: 'sku', width: '120px', type: FormTypes.normal },
+          { title: '原数量', key: 'preNumber', width: '120px', type: FormTypes.normal },
+          { title: '已出库', key: 'finishNumber', width: '120px', type: FormTypes.normal },
           {
             title: '出库数量',
             key: 'operNumber',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             statistics: true,
             validateRules: [{ required: true, message: '${title}不能为空' }],
           },
-          { title: '单价', key: 'unitPrice', width: '4%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
-          { title: '税率', key: 'taxRate', width: '4%', type: FormTypes.inputNumber, placeholder: '%' },
+          { title: '单价', key: 'unitPrice', width: '120px', type: FormTypes.inputNumber },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
+          { title: '税率', key: 'taxRate', width: '120px', type: FormTypes.inputNumber, placeholder: '%' },
           {
             title: '税额',
             key: 'taxMoney',
-            width: '5%',
+            width: '120px',
             type: FormTypes.inputNumber,
             readonly: true,
             statistics: true,
           },
-          { title: '价税合计', key: 'taxLastMoney', width: '7%', type: FormTypes.inputNumber, statistics: true },
+          { title: '价税合计', key: 'taxLastMoney', width: '120px', type: FormTypes.inputNumber, statistics: true },
 
           {
             title: '实际出库数量',
             key: 'actualQuantityInStorage',
-            width: '9%',
+            width: '120px',
             type: FormTypes.inputNumber,
             validateRules: [{ required: true, message: '实际入库数量不能为空' }],
           },
-          { title: '出库差异', key: 'warehousingVariance', width: '9%', type: FormTypes.input },
-          { title: '出库差异原因', key: 'reasonOfDifference', width: '9%', type: FormTypes.input },
+          { title: '出库差异', key: 'warehousingVariance', width: '120px', type: FormTypes.input },
+          { title: '出库差异原因', key: 'reasonOfDifference', width: '120px', type: FormTypes.input },
           {
             title: '出库人',
             key: 'warehousingUser',
-            width: '9%',
+            width: '120px',
             type: FormTypes.slot,
             slotName: 'warehousingUser',
             validateRules: [{ required: true, message: '出库人不能为空' }],
           },
-          { title: '出库时间', key: 'warehousingTime', width: '9%', type: FormTypes.date },
+          { title: '出库时间', key: 'warehousingTime', width: '200px', type: FormTypes.date },
 
-          { title: '备注', key: 'remark', width: '6%', type: FormTypes.input },
-          { title: '关联id', key: 'linkId', width: '5%', type: FormTypes.hidden },
+          { title: '备注', key: 'remark', width: '200px', type: FormTypes.input },
+          { title: '关联id', key: 'linkId', width: '120px', type: FormTypes.hidden },
         ],
       },
       confirmLoading: false,
@@ -623,10 +623,10 @@ export default {
           handleIntroJs(this.prefixNo, 1)
         })
       } else {
-        if (this.model.linkNumber) {
-          this.rowCanEdit = false
-          this.materialTable.columns[1].type = FormTypes.normal
-        }
+        // if (this.model.linkNumber) {
+        //   this.rowCanEdit = false
+        //   this.materialTable.columns[1].type = FormTypes.normal
+        // }
         this.model.operTime = this.model.operTimeStr
         if (this.model.deposit) {
           this.depositStatus = true

+ 2 - 2
jshERP-web/src/views/material/MaterialList.vue

@@ -151,9 +151,9 @@
           <a-button v-if="btnEnableList.indexOf(1) > -1" @click="batchSetMaterialCurrentStock()" icon="stock"
             >修正库存</a-button
           >
-          <a-button v-if="btnEnableList.indexOf(1) > -1" @click="batchSetMaterialCurrentUnitPrice()" icon="fund"
+          <!-- <a-button v-if="btnEnableList.indexOf(1) > -1" @click="batchSetMaterialCurrentUnitPrice()" icon="fund"
             >修正成本</a-button
-          >
+          > -->
           <a-popover trigger="click" placement="right">
             <template slot="content">
               <a-checkbox-group @change="onColChange" v-model="settingDataIndex" :defaultValue="settingDataIndex">

+ 1 - 1
jshERP-web/src/views/material/modules/BatchSetStockModal.vue

@@ -63,7 +63,7 @@ export default {
   methods: {
     add(type) {
       this.batchType = type
-      if (type === 'initStock') {
+      if (type === 'currentStock') {
         this.title = '期初库存-批量设置'
       } else if (type === 'lowSafeStock') {
         this.title = '最低安全库存-批量设置'

File diff suppressed because it is too large
+ 194 - 590
jshERP-web/src/views/material/modules/MaterialModal.vue


+ 1 - 2
jshERP-web/src/views/stock/CheckList.vue

@@ -47,8 +47,7 @@
           <span slot="action" slot-scope="text, record">
             <a @click="addTask('detail', record)">查看</a>
             <a-divider type="vertical" />
-            <a :disabled="record.taskStatus !== 1" @click="addTask('edit', record)">编辑</a>
-            <a-divider type="vertical" />
+            <a :disabled="record.taskStatus > 3" @click="addTask('edit', record)">编辑</a>
             <!-- <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
               <a :disabled="record.taskStatus !== 1 || record.taskStatus !== 4">删除</a>
             </a-popconfirm> -->

+ 3 - 3
jshERP-web/src/views/stock/TaskList.vue

@@ -96,10 +96,10 @@ export default {
       // 权限按钮集合
       btnEnableList: [1, 1, 1],
       queryParam: {
-        taskStatus: '',
+        taskStatus: undefined,
         number: '',
-        depotId: '',
-        createBy: '',
+        depotId: undefined,
+        createBy: undefined,
       },
       // stockTable: {
       //   loading: false,

+ 1 - 1
jshERP-web/src/views/stock/components/FilterForm.vue

@@ -5,7 +5,7 @@
       <a-row :gutter="24">
         <a-col :md="4" :sm="24">
           <a-form-item label="盘点状态" :labelCol="labelCol" :wrapperCol="wrapperCol">
-            <a-select placeholder="请选择供应商" showSearch :options="taskStatusList" v-model="queryParam.taskStatus">
+            <a-select placeholder="请选择盘点状态" showSearch :options="taskStatusList" v-model="queryParam.taskStatus">
             </a-select>
           </a-form-item>
         </a-col>

+ 58 - 23
jshERP-web/src/views/stock/components/checkModal.vue

@@ -105,26 +105,41 @@
       :isStock="true"
     ></j-select-material-modal>
     <a-modal @cancel="editVisible = false" @ok="onSubmitGoods" :visible="editVisible" title="编辑" width="50%">
-      <a-form :form="editForm">
-        <a-form-item label="盘点任务名称" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
+      <a-form-model :model="editForm" :rules="editFormRules" ref="editFormModel">
+        <a-form-model-item label="盘点任务名称" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="name">
           <a-input disabled v-model="editForm.name" placeholder="请输入"></a-input>
-        </a-form-item>
-        <a-form-item label="批次号" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
+        </a-form-model-item>
+        <a-form-model-item label="批次号" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="batchNumber">
           <a-input disabled v-model="editForm.batchNumber" placeholder="请输入"></a-input>
-        </a-form-item>
-        <a-form-item label="实际库存" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
-          <a-input v-model="editForm.newInventory" placeholder="请输入"></a-input>
-        </a-form-item>
-        <a-form-item label="实际仓位货架" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
+        </a-form-model-item>
+        <a-form-model-item label="实际库存" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="newInventory">
+          <a-input-number
+            placeholder="请输入"
+            v-model="editForm.newInventory"
+            @change="handleChangeNewInventory"
+            :min="0"
+            style="width: 100%"
+          />
+        </a-form-model-item>
+        <a-form-model-item label="实际仓位货架" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="newPosition">
           <a-input v-model="editForm.newPosition" placeholder="请输入"></a-input>
-        </a-form-item>
-        <a-form-item label="差异数量" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
-          <a-input v-model="editForm.differenceCount" placeholder="请输入"></a-input>
-        </a-form-item>
-        <a-form-item label="差异原因" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }">
+        </a-form-model-item>
+        <a-form-model-item :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="differenceCount">
+          <template slot="label">
+            差异数量
+            <span>
+              <a-tooltip>
+                <template slot="title"> 盘盈是正数,盘亏是负数 </template>
+                <a-icon type="question-circle" />
+              </a-tooltip>
+            </span>
+          </template>
+          <span :class="editForm.differenceCount !== 0 ? 'red-num' : ''">{{ editForm.differenceCount }}</span>
+        </a-form-model-item>
+        <a-form-model-item label="差异原因" :labelCol="{ span: 4 }" :wrapperCol="{ span: 14 }" prop="differenceReason">
           <a-input v-model="editForm.differenceReason" placeholder="请输入"></a-input>
-        </a-form-item>
-      </a-form>
+        </a-form-model-item>
+      </a-form-model>
     </a-modal>
   </div>
 </template>
@@ -221,6 +236,12 @@ export default {
       },
       editForm: {},
       editVisible: false,
+      editFormRules: {
+        newInventory: [
+          { required: true, message: '请输入实际库存' },
+          { pattern: /^[0-9]*$/, message: '只能输入数字' },
+        ],
+      },
     }
   },
   watch: {
@@ -249,10 +270,8 @@ export default {
   },
   computed: {
     isShowBtn() {
-      console.log('==================', this.form.taskStatus)
-
       if (this.openType === 'detail') return false
-      if (this.form.taskStatus !== 1) return false
+      if (this.form.taskStatus > 3) return false
 
       return true
     },
@@ -261,11 +280,18 @@ export default {
     handleEdit(data) {
       this.editForm = { ...data }
       this.editVisible = true
+      this.handleChangeNewInventory(data.newInventory)
     },
     onSubmitGoods() {
-      postAction(this.url.edit, this.editForm).then((res) => {
-        this.$message.success('操作成功')
-        this.editVisible = false
+      this.$refs.editFormModel.validate((valid) => {
+        if (valid) {
+          postAction(this.url.edit, this.editForm).then((res) => {
+            this.$message.success('操作成功')
+            this.editVisible = false
+          })
+        } else {
+          return false
+        }
       })
     },
     loadCategoryTreeData() {
@@ -425,8 +451,17 @@ export default {
         this.findAllSelect()
       }
     },
+
+    handleChangeNewInventory(val) {
+      const inventory = this.editForm.inventory ? Number(this.editForm.inventory) : 0
+      this.editForm.differenceCount = val - inventory
+    },
   },
 }
 </script>
 
-<style></style>
+<style>
+.red-num {
+  color: #f5222d;
+}
+</style>

+ 6 - 2
jshERP-web/src/views/stock/components/stockModal.vue

@@ -167,8 +167,12 @@ export default {
           }
           const url = this.openType === 'add' ? this.url.add : this.url.update
           postAction(url, params).then((res) => {
-            this.$message.success('操作成功')
-            this.handleCancel()
+            if (res.code === 200) {
+              this.$message.success('操作成功')
+              this.handleCancel()
+            } else {
+              this.$message.error(res.msg)
+            }
           })
         }
       })

+ 87 - 0
jshERP-web/src/views/system/AppVersionList.vue

@@ -0,0 +1,87 @@
+<template>
+  <a-row :gutter="24">
+    <a-col :md="24">
+      <a-card :style="cardStyle" :bordered="false">
+        <!-- 操作按钮区域 -->
+        <div class="table-operator" style="margin-top: 5px">
+          <a-button @click="handleAdd" type="primary" icon="plus">发布新版本</a-button>
+        </div>
+        <!-- table区域-begin -->
+        <div>
+          <a-table
+            ref="table"
+            size="middle"
+            bordered
+            rowKey="id"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="ipagination"
+            :scroll="scroll"
+            :loading="loading"
+            @change="handleTableChange"
+          >
+          </a-table>
+        </div>
+        <!-- table区域-end -->
+        <!-- 表单区域 -->
+        <app-version-modal ref="modalForm" @ok="modalFormOk"></app-version-modal>
+      </a-card>
+    </a-col>
+  </a-row>
+</template>
+<script>
+import AppVersionModal from './modules/AppVersionModal'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import { postAction } from '@/api/manage'
+
+export default {
+  name: 'AppVersionList',
+  mixins: [JeecgListMixin],
+  components: {
+    AppVersionModal,
+  },
+  data() {
+    return {
+      // 表头
+      columns: [
+        { title: '版本号', dataIndex: 'version', },
+        { title: '发布时间', dataIndex: 'createTime', },
+        { title: '文件路径', dataIndex: 'url',},
+      ],
+      url: {
+        list: '/apkVersion/list',
+      },
+    }
+  },
+  computed: {},
+  methods: {
+    loadData(arg) {
+      if (!this.url.list) {
+        this.$message.error('请设置url.list属性!')
+        return
+      }
+      //加载数据 若传入参数1则加载第一页的内容
+      if (arg === 1) {
+        this.ipagination.current = 1
+      }
+      this.loading = true
+      postAction(this.url.list, {}).then((res) => {
+        if (res.code === 200) {
+          this.dataSource = res.data.rows
+          this.ipagination.total = Number(res.data.total)
+          this.tableAddTotalRow(this.columns, this.dataSource)
+        } else if (res.code === 510) {
+          this.$message.warning(res.data)
+        } else {
+          this.$message.warning(res.data.message)
+        }
+        this.loading = false
+        this.onClearSelected()
+      })
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

+ 293 - 0
jshERP-web/src/views/system/modules/AppVersionModal.vue

@@ -0,0 +1,293 @@
+<template>
+  <div ref="container">
+    <a-modal
+      title="发布新版本"
+      :visible="visible"
+      :confirmLoading="confirmLoading"
+      :getContainer="() => $refs.container"
+      :maskStyle="{ top: '93px', left: '154px' }"
+      :wrapClassName="wrapClassNameInfo()"
+      :mask="isDesktop()"
+      :maskClosable="false"
+      @cancel="handleCancel"
+      :footer="null"
+      width="500px"
+      style="top: 5%"
+    >
+      <a-spin :spinning="confirmLoading">
+        <a-form :form="form" class="form-content" id="appVersionModal">
+          <a-form-item label="版本号" :labelCol="labelCol" :wrapperCol="wrapperCol">
+            <a-input placeholder="请输入" allowClear v-decorator="['version', validatorRules.version]" />
+          </a-form-item>
+          
+          <a-form-item label="上传文件" :labelCol="labelCol" :wrapperCol="wrapperCol">
+            <div class="upload-container">
+              <a-upload
+                name="file"
+                :data="uploadOpts.data"
+                :showUploadList="true"
+                :multiple="false"
+                :headers="uploadOpts.headers"
+                :action="uploadOpts.action"
+                :method="uploadOpts.method"
+                :accept="uploadOpts.accept"
+                :fileList="fileList"
+                @change="handleChange"
+                :beforeUpload="beforeUpload"
+                @reject="handleReject"
+              >
+                <div class="upload-content">
+                  <div class="upload-icon">
+                    <a-icon type="folder-open" style="color: #4e73f8; font-size: 32px;" />
+                  </div>
+                  <a-button type="primary" class="upload-button">上传文件</a-button>
+                </div>
+              </a-upload>
+            </div>
+          </a-form-item>
+          
+          <div class="form-actions">
+            <a-button @click="handleCancel" class="cancel-button">取消</a-button>
+            <a-button type="primary" @click="handleOk" :loading="confirmLoading" class="confirm-button">确定发布新版本</a-button>
+          </div>
+        </a-form>
+      </a-spin>
+    </a-modal>
+  </div>
+</template>
+<script>
+import Vue from 'vue'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import pick from 'lodash.pick'
+import { autoJumpNextInput } from '@/utils/util'
+import { mixinDevice } from '@/utils/mixin'
+import { postAction } from '@/api/manage'
+
+export default {
+  name: 'AppVersionModal',
+  mixins: [mixinDevice],
+  data() {
+    return {
+      visible: false,
+      confirmLoading: false,
+      labelCol: { span: 4 },
+      wrapperCol: { span: 20 },
+      fileList: [],
+      validatorRules: {
+        version: {
+          rules: [
+            { required: true, message: '请输入版本号!' },
+            { pattern: /^\d+\.\d+\.\d+$/, message: '版本号格式不正确!' }
+          ]
+        },
+        url: {
+          rules: [
+            { required: true, message: '请上传.apk文件!' }
+          ]
+        }
+      },
+      form: this.$form.createForm(this),
+      model: {},
+      uploadOpts:{
+        headers: {
+          'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)
+        },
+        method: 'POST',
+        action: window._CONFIG['domianURL'] + '/apkVersion/upload',
+        accept: '.apk',
+        data:{
+          biz: 'bill' 
+        }
+      },
+    }
+  },
+  methods: {
+    add() {
+      this.edit({})
+    },
+    edit(record) {
+      this.form.resetFields()
+      this.model = Object.assign({}, record)
+      this.fileList = []
+      this.visible = true
+      this.$nextTick(() => {
+        this.form.setFieldsValue(
+          pick(
+            this.model,
+            'url',
+            'version'
+          )
+        )
+        autoJumpNextInput('appVersionModal')
+      })
+    },
+    beforeUpload(file) {
+      // 检查文件类型
+      const isAPK = file.type === 'application/vnd.android.package-archive' || file.name.endsWith('.apk')
+      if (!isAPK) {
+        this.$message.error('只能上传APK文件!')
+        return false
+      }
+      
+      // 阻止自动上传
+      return true
+    },
+    handleChange(info) {
+      this.fileList = [info.file]
+      console.log('文件列表:', this.fileList)
+      if (info.file.status === 'uploading') {
+        console.log(info.file, info.fileList)
+        this.confirmLoading = true
+      }else if(info.file.status === 'removed'){
+        this.fileList = []
+        this.model.url = ''
+      }else if (info.file.status === 'done') {
+        this.confirmLoading = false
+        console.log('model=====', this.model)
+        if (info.file.response) {
+          if (info.file.response.code === 200) {
+            info.file.name = info.file.response.data
+            this.model.url = info.file.response.data
+          } else {
+            this.$message.warning(info.file.response.data, 8)
+          }
+        } else {
+          this.$message.error(`${info.file.name} ${info.file.response.data}.`)
+        }
+      } else if (info.file.status === 'error') {
+        this.confirmLoading = false
+        this.$message.error(`文件上传失败: ${info.file.msg} `)
+      }
+    },
+    handleReject(file) {
+      console.log('文件类型不正确:', file)
+      this.$message.error('文件类型不正确,请上传.apk文件!')
+    },
+    handleOk() {
+      this.form.validateFields((err, values) => {
+        if (err) return
+        console.log('values======',values)
+        if (this.fileList.length === 0) {
+          this.$message.error('请上传.apk类型文件!')
+          return
+        }
+        
+        const formData = {
+          version: values.version,
+          url: this.fileList[0].name // 实际应用中这里应该是上传后的URL
+        }
+        
+        this.confirmLoading = true
+        
+        postAction('/apkVersion/add', formData).then(res => {
+          if (res.code === 200) {
+            this.$message.success(res.msg)
+            this.visible = false
+            this.$emit('ok', formData)
+          } else {
+            this.$message.error(res.data||'操作失败')
+          }
+        }).catch(err => {
+          console.error(err)
+        }).finally(() => {
+          this.confirmLoading = false
+        })
+      })
+    },
+    handleCancel() {
+      this.visible = false
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+.form-content {
+  padding: 0 10px;
+}
+
+.upload-container {
+  border: 1px dashed #d9d9d9;
+  border-radius: 4px;
+  padding: 24px;
+  background-color: #fafafa;
+}
+
+.upload-content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 10px 0;
+}
+
+.upload-icon {
+  margin-bottom: 16px;
+}
+
+.upload-button {
+  height: 32px;
+  font-size: 14px;
+  border-radius: 4px;
+  background-color: #4e73f8;
+  border-color: #4e73f8;
+}
+
+.reupload-button {
+  background-color: #4e73f8;
+  border-color: #4e73f8;
+}
+
+.form-actions {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 24px;
+  
+  .cancel-button {
+    margin-right: 12px;
+    min-width: 80px;
+    height: 32px;
+  }
+  
+  .confirm-button {
+    background-color: #4e73f8;
+    border-color: #4e73f8;
+    min-width: 120px;
+    height: 32px;
+  }
+}
+
+/deep/ .ant-upload.ant-upload-select {
+  display: block;
+}
+
+/deep/ .ant-upload-list-item {
+  margin-top: 8px;
+}
+
+/deep/ .ant-form-item-label {
+  text-align: left;
+  line-height: 32px;
+}
+
+/deep/ .ant-form-item {
+  margin-bottom: 24px;
+}
+
+/deep/ .ant-modal-close-x {
+  width: 46px;
+  height: 46px;
+  line-height: 46px;
+}
+
+/deep/ .ant-modal-body {
+  padding: 16px 24px 24px;
+}
+
+/deep/ .ant-form-item-control {
+  line-height: 32px;
+}
+
+/deep/ .ant-input {
+  height: 32px;
+}
+</style>

+ 22 - 5
jshERP-web/src/views/system/modules/VendorModal.vue

@@ -14,7 +14,7 @@
       @cancel="handleCancel"
       cancelText="取消"
       okText="保存"
-      style="top: 10%; height: 80%"
+      style="top: 10%"
     >
       <template slot="footer">
         <a-button key="back" v-if="isReadOnly" @click="handleCancel"> 取消 </a-button>
@@ -87,7 +87,11 @@
             </a-col>
             <a-col :span="24 / 2">
               <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="排序">
-                <a-input placeholder="请输入排序" v-decorator.trim="['sort']" />
+                <a-input
+                  placeholder="请输入排序"
+                  oninput="value=value.replace(/[^\d]/g, '')"
+                  v-decorator.trim="['sort']"
+                />
               </a-form-item>
             </a-col>
             <a-col :span="24 / 2">
@@ -106,7 +110,11 @@
             </a-col>
             <a-col :span="24 / 2">
               <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="账单周期">
-                <a-input placeholder="请输入账单周期" v-decorator.trim="['billingCycleDays']" />
+                <a-input
+                  placeholder="请输入账单周期"
+                  oninput="value=value.replace(/[^\d]/g, '')"
+                  v-decorator.trim="['billingCycleDays']"
+                />
               </a-form-item>
             </a-col>
             <a-col :span="24 / 2">
@@ -116,7 +124,11 @@
             </a-col>
             <a-col :span="24 / 2">
               <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="到货天数">
-                <a-input placeholder="请输入到货天数" v-decorator.trim="['deliveryDays']" />
+                <a-input
+                  placeholder="请输入到货天数"
+                  oninput="value=value.replace(/[^\d]/g, '')"
+                  v-decorator.trim="['deliveryDays']"
+                />
               </a-form-item>
             </a-col>
             <a-col :span="24 / 2">
@@ -130,7 +142,12 @@
             </a-col>
             <a-col :span="24 / 2">
               <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="税率(%)">
-                <a-input-number style="width: 100%" placeholder="请输入税率" v-decorator.trim="['taxRate']" />
+                <a-input-number
+                  style="width: 100%"
+                  oninput="value=value.replace(/[^\d.]/g, '')"
+                  placeholder="请输入税率"
+                  v-decorator.trim="['taxRate']"
+                />
               </a-form-item>
             </a-col>
             <a-col :span="24 / 2">

+ 2 - 1
jshERP-web/vue.config.js

@@ -54,7 +54,8 @@ module.exports = {
     open: true,
     proxy: {
       [process.env.VUE_APP_BASE_API]: {
-        target: 'http://localhost:8080', // 请求本地 需要jshERP-boot后台项目
+        // target: 'https://test-erp.xianglitech.com.cn/stage-api', // 请求本地 需要jshERP-boot后台项目
+        target: 'http://192.168.2.112:8080', // 请求本地 需要jshERP-boot后台项目
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: '',

+ 2 - 1
src/main/java/com/jsh/erp/controller/DepotController.java

@@ -258,10 +258,11 @@ public class DepotController extends BaseController {
                     BigDecimal initStock = materialService.getInitStock(mId, depot.getId());
                     BigDecimal currentStock = materialService.getCurrentStockByMaterialIdAndDepotId(mId, depot.getId());
                     de.setInitStock(initStock);
-                    de.setCurrentStock(currentStock);
+                    de.setCurrentStock(currentStock == null ? BigDecimal.ZERO : currentStock);
                     MaterialInitialStock materialInitialStock = materialService.getSafeStock(mId, depot.getId());
                     de.setLowSafeStock(materialInitialStock.getLowSafeStock());
                     de.setHighSafeStock(materialInitialStock.getHighSafeStock());
+                    de.setPosition(materialInitialStock.getPosition());
                 } else {
                     de.setInitStock(BigDecimal.ZERO);
                     de.setCurrentStock(BigDecimal.ZERO);

+ 16 - 13
src/main/java/com/jsh/erp/controller/DepotItemController.java

@@ -273,11 +273,12 @@ public class DepotItemController {
                     item.put("anotherDepotName", diEx.getAnotherDepotId() == null ? "" : diEx.getAnotherDepotName());
                     item.put("mType", diEx.getMaterialType());
                     item.put("op", 1);
-                    item.put("productionDate",diEx.getProductionDate());
+                    String productionDate = diEx.getProductionDate() == null ? null : DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",diEx.getProductionDate());
+                    item.put("productionDate",productionDate);
                     item.put("expiryNum",diEx.getExpiryNum());
                     item.put("supplierId",diEx.getSupplierId());
                     item.put("batchNumber",diEx.getBatchNumber());
-                    item.put("inventory",diEx.getInventory());
+                    item.put("inventory",materialService.getMaterialStockByMid(diEx.getMaterialId()));
                     item.put("supplierName",diEx.getSupplierName());
                     item.put("unitId",diEx.getUnitId());
                     item.put("unitList",diEx.getUnitId() == null ? null : unitService.getUnitListByID(diEx.getUnitId()));
@@ -287,6 +288,8 @@ public class DepotItemController {
                     item.put("reasonOfDifference",diEx.getReasonOfDifference());
                     item.put("warehousingUser",diEx.getWarehousingUser());
                     item.put("warehousingTime",diEx.getWarehousingTime());
+                    item.put("warehousingUserName",diEx.getWarehousingUserName());
+                    item.put("wholesaleDecimal",diEx.getWholesaleDecimal());
                     dataArray.add(item);
                     //合计数据汇总
                     totalOperNumber = totalOperNumber.add(diEx.getOperNumber()==null?BigDecimal.ZERO:diEx.getOperNumber());
@@ -1000,7 +1003,7 @@ public class DepotItemController {
         Map<String, Object> data = new HashMap<>();
         String message = "";
         try {
-            String batchNumbers = "";
+            String barCodes = "";
             //文件合法性校验
             Sheet src = null;
             try {
@@ -1020,14 +1023,14 @@ public class DepotItemController {
             } else {
                 List<Map<String, String>> detailList = new ArrayList<>();
                 for (int i = 2; i < src.getRows(); i++) {
-                    String depotName = "", batchNumber = "", num = "", unitPrice = "", taxRate = "", remark = "";
+                    String depotName = "", barCode = "", num = "", unitPrice = "", taxRate = "", remark = "";
                     if("QGD".equals(prefixNo)) {
-                        batchNumber = ExcelUtils.getContent(src, i, 0);
+                        barCode = ExcelUtils.getContent(src, i, 0);
                         num = ExcelUtils.getContent(src, i, 2);
                         remark = ExcelUtils.getContent(src, i, 3);
                     }
                     if("CGDD".equals(prefixNo) || "XSDD".equals(prefixNo)) {
-                        batchNumber = ExcelUtils.getContent(src, i, 0);
+                        barCode = ExcelUtils.getContent(src, i, 0);
                         num = ExcelUtils.getContent(src, i, 2);
                         unitPrice = ExcelUtils.getContent(src, i, 3);
                         taxRate = ExcelUtils.getContent(src, i, 4);
@@ -1036,7 +1039,7 @@ public class DepotItemController {
                     if("CGRK".equals(prefixNo) || "XSCK".equals(prefixNo)) {
                         //采购入库
                         depotName = ExcelUtils.getContent(src, i, 0);
-                        batchNumber = ExcelUtils.getContent(src, i, 1);
+                        barCode = ExcelUtils.getContent(src, i, 1);
                         num = ExcelUtils.getContent(src, i, 3);
                         unitPrice = ExcelUtils.getContent(src, i, 4);
                         taxRate = ExcelUtils.getContent(src, i, 5);
@@ -1044,25 +1047,25 @@ public class DepotItemController {
                     }
                     if("QTRK".equals(prefixNo) || "QTCK".equals(prefixNo)) {
                         depotName = ExcelUtils.getContent(src, i, 0);
-                        batchNumber = ExcelUtils.getContent(src, i, 1);
+                        barCode = ExcelUtils.getContent(src, i, 1);
                         num = ExcelUtils.getContent(src, i, 3);
                         unitPrice = ExcelUtils.getContent(src, i, 4);
                         remark = ExcelUtils.getContent(src, i, 5);
                     }
                     Map<String, String> materialMap = new HashMap<>();
                     materialMap.put("depotName", depotName);
-                    materialMap.put("batchNumber", batchNumber);
+                    materialMap.put("barCode", barCode);
                     materialMap.put("num", num);
                     materialMap.put("unitPrice", unitPrice);
                     materialMap.put("taxRate", taxRate);
                     materialMap.put("remark", remark);
                     detailList.add(materialMap);
-                    batchNumbers += "'" + batchNumber + "',";
+                    barCodes += "'" + barCode + "',";
                 }
-                if (StringUtil.isNotEmpty(batchNumbers)) {
-                    batchNumbers = batchNumbers.substring(0, batchNumbers.length() - 1);
+                if (StringUtil.isNotEmpty(barCodes)) {
+                    barCodes = barCodes.substring(0, barCodes.length() - 1);
                 }
-                JSONObject map = depotItemService.parseMapByExcelData(batchNumbers, detailList, prefixNo);
+                JSONObject map = depotItemService.parseMapByExcelData(barCodes, detailList, prefixNo);
                 if (map != null) {
                     res.code = 200;
                 } else {

+ 17 - 14
src/main/java/com/jsh/erp/controller/MaterialController.java

@@ -2,12 +2,11 @@ package com.jsh.erp.controller;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.jsh.erp.base.AjaxResult;
 import com.jsh.erp.base.BaseController;
 import com.jsh.erp.base.TableDataInfo;
-import com.jsh.erp.datasource.entities.Material;
-import com.jsh.erp.datasource.entities.MaterialExtend;
-import com.jsh.erp.datasource.entities.MaterialVo4Unit;
-import com.jsh.erp.datasource.entities.Unit;
+import com.jsh.erp.datasource.dto.MaterialDto;
+import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import io.swagger.annotations.Api;
@@ -22,10 +21,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import static com.jsh.erp.utils.ResponseJsonUtil.returnJson;
 import static com.jsh.erp.utils.ResponseJsonUtil.returnStr;
@@ -104,7 +100,7 @@ public class MaterialController extends BaseController {
 
     @PostMapping(value = "/add")
     @ApiOperation(value = "新增")
-    public String addResource(@RequestBody JSONObject obj, HttpServletRequest request)throws Exception {
+    public String addResource(@RequestBody MaterialDto obj, HttpServletRequest request)throws Exception {
         Map<String, Object> objectMap = new HashMap<>();
         int insert = materialService.insertMaterial(obj, request);
         return returnStr(objectMap, insert);
@@ -112,7 +108,7 @@ public class MaterialController extends BaseController {
 
     @PutMapping(value = "/update")
     @ApiOperation(value = "修改")
-    public String updateResource(@RequestBody JSONObject obj, HttpServletRequest request)throws Exception {
+    public String updateResource(@RequestBody MaterialDto obj, HttpServletRequest request)throws Exception {
         Map<String, Object> objectMap = new HashMap<>();
         int update = materialService.updateMaterial(obj, request);
         return returnStr(objectMap, update);
@@ -365,7 +361,7 @@ public class MaterialController extends BaseController {
                     item.put("depotId",material.getDepotId());
                     item.put("depotName",material.getDepotName());
                     item.put("unitId",material.getUnitId());
-                    item.put("inventory",material.getInventory());
+                    item.put("inventory",materialService.getMaterialStockByMid(material.getId()));
                     BigDecimal stock;
                     if(StringUtil.isNotEmpty(material.getSku())){
                         stock = depotItemService.getSkuStockByParam(depotId,material.getMeId(),null,null);
@@ -929,9 +925,6 @@ public class MaterialController extends BaseController {
         return res;
     }
 
-    /**
-     * 商品信息全选获取批次号
-     */
     @GetMapping(value = "/findBatchNumbersBySelect")
     @ApiOperation(value = "商品选择全选获取商品批次号")
     public BaseResponseInfo findBatchNumberSBySelect(@RequestParam(value = "categoryId", required = false) Long categoryId,
@@ -967,4 +960,14 @@ public class MaterialController extends BaseController {
     }
 
 
+
+
+    @GetMapping(value = "/getPositionByDidAndMid")
+    @ApiOperation(value = "获取商品仓库库位")
+    public AjaxResult getPositionByDidAndMid(@RequestParam(value = "did") Long did,
+                                             @RequestParam(value = "mid") Long mid){
+        return AjaxResult.success(materialService.getPositionByDidAndMid(did,mid));
+    }
+
+
 }

+ 1 - 0
src/main/java/com/jsh/erp/controller/MaterialExtendController.java

@@ -117,6 +117,7 @@ public class MaterialExtendController {
                     item.put("inventory",md.getInventory());
                     item.put("depotId",md.getDepotId());
                     item.put("position",md.getPosition());
+                    item.put("ratio",md.getRatio());
                     dataArray.add(item);
                 }
             }

+ 50 - 3
src/main/java/com/jsh/erp/controller/apkVersion/apkVersionController.java

@@ -4,19 +4,24 @@ package com.jsh.erp.controller.apkVersion;
 import com.jsh.erp.base.AjaxResult;
 import com.jsh.erp.base.BaseController;
 import com.jsh.erp.base.TableDataInfo;
-import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
-import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
 import com.jsh.erp.datasource.entities.ApkVersion;
-import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.service.ApkVersionService;
+import com.jsh.erp.service.SystemConfigService;
+import com.jsh.erp.utils.BaseResponseInfo;
+import com.jsh.erp.utils.StringUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.Date;
 import java.util.List;
 
@@ -28,6 +33,12 @@ public class apkVersionController extends BaseController {
     @Resource
     private ApkVersionService apkVersionService;
 
+    @Resource
+    private SystemConfigService systemConfigService;
+
+    @Value(value="${file.path}")
+    private String filePath;
+
     @ApiOperation("apk版本列表")
     @PostMapping("/list")
     public TableDataInfo list(){
@@ -47,4 +58,40 @@ public class apkVersionController extends BaseController {
         return AjaxResult.success();
     }
 
+    /**
+     * apk文件上传方法
+     * @param request
+     * @param response
+     * @return
+     */
+    @PostMapping(value = "/upload")
+    @ApiOperation(value = "apk文件上传方法")
+    public BaseResponseInfo upload(HttpServletRequest request, HttpServletResponse response) {
+        BaseResponseInfo res = new BaseResponseInfo();
+        try {
+            String savePath = "";
+            String bizPath = request.getParameter("biz");
+            if ("bill".equals(bizPath) || "financial".equals(bizPath) || "material".equals(bizPath)) {
+                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+                MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
+                savePath = systemConfigService.uploadLocal(file, bizPath, request);
+                if(StringUtil.isNotEmpty(savePath)){
+                    res.code = 200;
+                    res.data = filePath + "/" +savePath;
+                }else {
+                    res.code = 500;
+                    res.data = "上传失败!";
+                }
+            } else {
+                res.code = 505;
+                res.data = "文件分类错误!";
+            }
+        } catch (Exception e) {
+            logger.error(e.getMessage(), e);
+            res.code = 500;
+            res.data = "上传失败!";
+        }
+        return res;
+    }
+
 }

+ 45 - 0
src/main/java/com/jsh/erp/controller/materialBatch/MaterialBatchController.java

@@ -0,0 +1,45 @@
+package com.jsh.erp.controller.materialBatch;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jsh.erp.base.BaseController;
+import com.jsh.erp.base.TableDataInfo;
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import com.jsh.erp.datasource.vo.MaterialExtendVo4List;
+import com.jsh.erp.query.LambdaQueryWrapperX;
+import com.jsh.erp.query.QueryWrapperX;
+import com.jsh.erp.service.MaterialBatchService;
+import com.jsh.erp.utils.BaseResponseInfo;
+import com.jsh.erp.utils.DateUtils;
+import com.jsh.erp.utils.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/materialBatch")
+@Api(tags = {"商品批次信息管理"})
+public class MaterialBatchController extends BaseController {
+
+    @Resource
+    private MaterialBatchService materialBatchService;
+
+    @GetMapping(value = "/getDetailList")
+    @ApiOperation(value = "商品批次信息管理")
+    public TableDataInfo getDetailList(@RequestParam("materialId") Long materialId,
+                                       HttpServletRequest request)throws Exception {
+        startPage();
+        List<MaterialBatch> list = materialBatchService.list(new LambdaQueryWrapperX<MaterialBatch>().eq(MaterialBatch::getMaterialId,materialId).eq(MaterialBatch::getDeleteFlag,"0"));
+        return getDataTable(list);
+    }
+
+}

+ 3 - 1
src/main/java/com/jsh/erp/controller/pda/PdaController.java

@@ -144,7 +144,7 @@ public class PdaController extends BaseController {
     @GetMapping("/materialDepotDetail/{type}/{materialId}")
     public TableDataInfo materialDepotDetail(@PathVariable("type") String type, @PathVariable("materialId") Long materialId) {
         startPage();
-        if ("out".equals(type)) {
+        if ("in".equals(type)) {
             type = "入库";
         } else {
             type = "出库";
@@ -351,4 +351,6 @@ public class PdaController extends BaseController {
         return AjaxResult.success(apkVersion);
     }
 
+
+
 }

+ 1 - 1
src/main/java/com/jsh/erp/controller/stocktaking/StocktakingController.java

@@ -184,7 +184,7 @@ public class StocktakingController extends BaseController {
                 MaterialExtend materialExtend = materialExtendService.getMaterialExtend(taskStocktakingItem.getMaterialItemId());
                 materialExtend.setInventory(taskStocktakingItem.getNewInventory());
                 materialExtend.setPosition(taskStocktakingItem.getNewPosition());
-                materialExtendService.updateInventory("盘点",taskStocktakingItem.getId(),materialExtend);
+                //materialExtendService.updateInventory("盘点",taskStocktakingItem.getId(),materialExtend);
             }
         }
         return AjaxResult.success();

+ 26 - 0
src/main/java/com/jsh/erp/datasource/dto/DepotHeadDto.java

@@ -0,0 +1,26 @@
+package com.jsh.erp.datasource.dto;
+
+
+import com.jsh.erp.datasource.entities.DepotHead;
+import com.jsh.erp.datasource.entities.DepotItem;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 单据信息
+ */
+@Data
+public class DepotHeadDto {
+
+    @ApiModelProperty("单据主表信息")
+    private DepotHead info;
+
+    @ApiModelProperty("单据子表信息")
+    private List<DepotItem> rows;
+
+    private BigDecimal preTotalPrice;
+
+}

+ 29 - 0
src/main/java/com/jsh/erp/datasource/dto/MaterialDto.java

@@ -0,0 +1,29 @@
+package com.jsh.erp.datasource.dto;
+
+import com.alibaba.fastjson.JSONArray;
+import com.jsh.erp.datasource.entities.Material;
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import com.jsh.erp.datasource.entities.MaterialExtend;
+import com.jsh.erp.datasource.entities.MaterialInitialStock;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 商品信息
+ */
+@Data
+public class MaterialDto extends Material {
+
+    @ApiModelProperty("商品条码信息")
+    private List<MaterialExtend> mbList;
+
+    @ApiModelProperty("商品库存信息")
+    private List<MaterialInitialStock> stock;
+
+    private JSONArray sortList;
+
+
+
+}

+ 2 - 0
src/main/java/com/jsh/erp/datasource/entities/ApkVersion.java

@@ -1,5 +1,6 @@
 package com.jsh.erp.datasource.entities;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -21,6 +22,7 @@ public class ApkVersion {
     private String name;
 
     @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     @ApiModelProperty(value = "是否删除")

+ 4 - 0
src/main/java/com/jsh/erp/datasource/entities/DepotEx.java

@@ -1,5 +1,6 @@
 package com.jsh.erp.datasource.entities;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -23,4 +24,7 @@ public class DepotEx extends Depot{
 
     private BigDecimal highSafeStock;
 
+    @ApiModelProperty("仓位货架")
+    private String position;
+
 }

+ 6 - 2
src/main/java/com/jsh/erp/datasource/entities/DepotHead.java

@@ -35,8 +35,8 @@ public class DepotHead {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
-    @ApiModelProperty("出入库时间")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty("单据时间")
+    @JsonFormat(pattern = "yyyy-MM-dd")
     private Date operTime;
 
     @ApiModelProperty("供应商id")
@@ -153,6 +153,10 @@ public class DepotHead {
     @ApiModelProperty("操作人")
     private Long operId;
 
+    @ApiModelProperty("提交时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date submitTime;
+
 
     public Long getId() {
         return id;

+ 21 - 0
src/main/java/com/jsh/erp/datasource/entities/DepotItem.java

@@ -108,6 +108,19 @@ public class DepotItem {
     @ApiModelProperty("创建时间")
     private Date createTime;
 
+    @ApiModelProperty("生产日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date productionDate;
+
+    @ApiModelProperty("保质期天数")
+    private Integer expiryNum;
+
+    @ApiModelProperty("仓位货架")
+    private String position;
+
+    @ApiModelProperty("销售价")
+    private BigDecimal wholesaleDecimal;
+
     public Long getId() {
         return id;
     }
@@ -307,4 +320,12 @@ public class DepotItem {
     public void setDeleteFlag(String deleteFlag) {
         this.deleteFlag = deleteFlag == null ? null : deleteFlag.trim();
     }
+
+    public Date getProductionDate() {
+        return productionDate;
+    }
+
+    public void setProductionDate(Date productionDate) {
+        this.productionDate = productionDate;
+    }
 }

+ 5 - 1
src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4WithInfoEx.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.Date;
 
 @Data
 public class DepotItemVo4WithInfoEx extends DepotItem{
@@ -59,7 +60,7 @@ public class DepotItemVo4WithInfoEx extends DepotItem{
     private String brand;
 
     @ApiModelProperty("生产日期")
-    private String productionDate;
+    private Date productionDate;
 
     @ApiModelProperty("保质期天数")
     private Integer expiryNum;
@@ -82,6 +83,9 @@ public class DepotItemVo4WithInfoEx extends DepotItem{
     @ApiModelProperty("供应商名称")
     private String supplierName;
 
+    @ApiModelProperty("入库人名称")
+    private String warehousingUserName;
+
     public Long getMId() {
         return MId;
     }

+ 90 - 0
src/main/java/com/jsh/erp/datasource/entities/MaterialBatch.java

@@ -0,0 +1,90 @@
+package com.jsh.erp.datasource.entities;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 商品批次表实体类
+ */
+@Data
+public class MaterialBatch {
+
+    @ApiModelProperty("主键id")
+    private Long id;
+
+    @ApiModelProperty("商品id")
+    private Long materialId;
+
+    @ApiModelProperty("商品单位")
+    private String commodityUnit;
+
+    @ApiModelProperty("商品属性")
+    private String sku;
+
+    @ApiModelProperty("采购价格")
+    private BigDecimal purchaseDecimal;
+
+    @ApiModelProperty("零售价格")
+    private BigDecimal commodityDecimal;
+
+    @ApiModelProperty("销售价格")
+    private BigDecimal wholesaleDecimal;
+
+    @ApiModelProperty("最低售价")
+    private BigDecimal lowDecimal;
+
+    @ApiModelProperty("是否为默认单位,1是,0否")
+    private String defaultFlag;
+
+    @ApiModelProperty("创建日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @ApiModelProperty("创建人编码")
+    private String createSerial;
+
+    @ApiModelProperty("更新人编码")
+    private String updateSerial;
+
+    @ApiModelProperty("更新时间戳")
+    private Date updateTime;
+
+    @ApiModelProperty("租户id")
+    private Long tenantId;
+
+    @ApiModelProperty("删除标记,0未删除,1删除")
+    private String deleteFlag;
+
+    @ApiModelProperty("生产日期")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date productionDate;
+
+    @ApiModelProperty("保质期天数")
+    private Integer expiryNum;
+
+    @ApiModelProperty("供应商id")
+    private Long supplierId;
+
+    @ApiModelProperty("商品条码")
+    private String barCode;
+
+    @ApiModelProperty("批次号")
+    private String batchNumber;
+
+    @ApiModelProperty("库存")
+    private BigDecimal inventory;
+
+    @ApiModelProperty("仓库id")
+    private Long depotId;
+
+    @ApiModelProperty("仓位货架")
+    private String position;
+
+    @ApiModelProperty("单据id")
+    private Long depotItemId;
+
+}

+ 9 - 0
src/main/java/com/jsh/erp/datasource/entities/MaterialCurrentStock.java

@@ -1,6 +1,7 @@
 package com.jsh.erp.datasource.entities;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
 
@@ -13,18 +14,26 @@ import java.math.BigDecimal;
 @Accessors(chain = true)
 @TableName("jsh_material_current_stock")
 public class MaterialCurrentStock {
+
+    @ApiModelProperty("主键id")
     private Long id;
 
+    @ApiModelProperty("产品id")
     private Long materialId;
 
+    @ApiModelProperty("仓库id")
     private Long depotId;
 
+    @ApiModelProperty("当前库存数量")
     private BigDecimal currentNumber;
 
+    @ApiModelProperty("当前价格")
     private BigDecimal currentUnitPrice;
 
+    @ApiModelProperty("租户id")
     private Long tenantId;
 
+    @ApiModelProperty("删除标记,0未删除,1删除")
     private String deleteFlag;
 
     public Long getId() {

+ 3 - 0
src/main/java/com/jsh/erp/datasource/entities/MaterialExtend.java

@@ -88,6 +88,9 @@ public class MaterialExtend {
     @ApiModelProperty("仓位货架")
     private String position;
 
+    @ApiModelProperty("单位比例")
+    private Integer ratio;
+
     public void setBarCode(String barCode) {
         this.barCode = barCode == null ? null : barCode.trim();
     }

+ 5 - 0
src/main/java/com/jsh/erp/datasource/entities/MaterialInitialStock.java

@@ -1,5 +1,6 @@
 package com.jsh.erp.datasource.entities;
 
+import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -11,6 +12,7 @@ import java.math.BigDecimal;
  */
 @Data
 @Accessors(chain = true)
+@TableName("jsh_material_initial_stock")
 public class MaterialInitialStock {
 
     @ApiModelProperty("主键id")
@@ -37,6 +39,9 @@ public class MaterialInitialStock {
     @ApiModelProperty("删除标记,0未删除,1删除")
     private String deleteFlag;
 
+    @ApiModelProperty("仓位货架")
+    private String position;
+
     public Long getId() {
         return id;
     }

+ 1 - 1
src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapperEx.java

@@ -249,7 +249,7 @@ public interface DepotItemMapperEx {
             @Param("batchNumber") String batchNumber);
 
     List<MaterialVo4Unit> getBillItemByParam(
-            @Param("batchNumbers") String batchNumbers);
+            @Param("barCodes") String barCodes);
 
     BigDecimal getCurrentStockByParam(
             @Param("depotId") Long depotId,

+ 27 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialBatchMapper.java

@@ -0,0 +1,27 @@
+package com.jsh.erp.datasource.mappers;
+
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface MaterialBatchMapper extends BaseMapperX<MaterialBatch> {
+
+
+    /**
+     * 根据商品id获取商品批次库存不为0的数据
+     * 按生产日期顺序排序
+     * @param mid 商品id
+     */
+    List<MaterialBatch> getMaterialBatchByMaterialId(Long mid);
+
+    /**
+     * 根据仓库id和商品id查询商品批次库存
+     * @param depotList 仓库id
+     * @param mid   商品id
+     */
+    BigDecimal getInventorySumByDepotAndMid(@Param("depotList") List<Long> depotList,
+                                            @Param("mid") Long mid);
+
+}

+ 3 - 0
src/main/java/com/jsh/erp/datasource/pda/dto/PDADepotHeadDTO.java

@@ -38,6 +38,9 @@ public class PDADepotHeadDTO {
     @ApiModelProperty("订单商品数据")
     private List<PDADepotMaterialDto> materials;
 
+    @ApiModelProperty("仓库id")
+    private Long depotId;
+
 
 
 }

+ 3 - 0
src/main/java/com/jsh/erp/datasource/pda/vo/PDADepotHeadVO.java

@@ -36,4 +36,7 @@ public class PDADepotHeadVO {
     @ApiModelProperty("订单状态")
     private String status;
 
+    @ApiModelProperty("出入库时间")
+    private Date warehousingTime;
+
 }

+ 6 - 0
src/main/java/com/jsh/erp/datasource/vo/MaterialCountVo.java

@@ -1,11 +1,17 @@
 package com.jsh.erp.datasource.vo;
 
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
 import java.math.BigDecimal;
 
+@Data
 public class MaterialCountVo {
 
+    @ApiModelProperty("单据主表ID")
     private Long headerId;
 
+    @ApiModelProperty("商品数量")
     private BigDecimal materialCount;
 
     public Long getHeaderId() {

+ 6 - 2
src/main/java/com/jsh/erp/service/DepotItemService.java

@@ -67,6 +67,10 @@ public interface DepotItemService extends IService<DepotItem> {
     Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
                                                 String number, String beginTime, String endTime, Long mId)throws Exception;
 
+    /**
+     * 插入单据子表
+     * @param depotItem 单据子表
+     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     int insertDepotItemWithObj(DepotItem depotItem)throws Exception;
 
@@ -175,11 +179,11 @@ public interface DepotItemService extends IService<DepotItem> {
 
     /**
      * 解析excel表格数据
-     * @param batchNumbers 批次号
+     * @param barCodes 批次号
      * @param detailList    数据明细
      * @param prefixNo  单据类型
      */
-    JSONObject parseMapByExcelData(String batchNumbers, List<Map<String, String>> detailList, String prefixNo) throws Exception;
+    JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception;
 
     BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo);
 

+ 44 - 0
src/main/java/com/jsh/erp/service/MaterialBatchService.java

@@ -0,0 +1,44 @@
+package com.jsh.erp.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import com.jsh.erp.datasource.entities.MaterialExtend;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface MaterialBatchService extends IService<MaterialBatch> {
+
+
+    /**
+     * 根据单据子表id生成商品批次数据
+     * @param diId 单据子表id
+     */
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    void generateMaterialBatchByDepotItemId(Long diId) throws Exception;
+
+    /**
+     * 根据单据子表id处理商品批次数据
+     * @param diId 单据子表id
+     */
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    void handleMaterialBatchByDepotItemId(Long diId) throws Exception;
+
+    /**
+     * 修改商品批次库存
+     * @param type 操作记录
+     * @param diId 单据子表id
+     * @param materialBatch 商品批次信息
+     */
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    void updateInventory(String type, Long diId, MaterialBatch materialBatch) throws Exception;
+
+    /**
+     * 根据仓库id和商品id查询商品批次库存
+     * @param depotList 仓库id
+     * @param mid   商品id
+     */
+    BigDecimal getInventorySumByDepotAndMid(List<Long> depotList, Long mid);
+}

+ 3 - 6
src/main/java/com/jsh/erp/service/MaterialExtendService.java

@@ -2,7 +2,9 @@ package com.jsh.erp.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.jsh.erp.datasource.dto.MaterialDto;
 import com.jsh.erp.datasource.entities.Log;
+import com.jsh.erp.datasource.entities.MaterialBatch;
 import com.jsh.erp.datasource.entities.MaterialExtend;
 import com.jsh.erp.datasource.vo.MaterialExtendVo4List;
 import org.springframework.transaction.annotation.Transactional;
@@ -18,7 +20,7 @@ public interface MaterialExtendService extends IService<MaterialExtend> {
     List<MaterialExtend> getListByMIds(List<Long> idList);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    String saveDetials(JSONObject obj, String sortList, Long materialId, String type) throws Exception;
+    String saveDetails(List<MaterialExtend> materialExtends, String sortList, Long materialId, String type) throws Exception;
 
     /**
      *  添加商品子信息
@@ -58,9 +60,4 @@ public interface MaterialExtendService extends IService<MaterialExtend> {
     int getCountByManyBarCodeWithoutUs(String manyBarCode, String barCode);
 
     MaterialExtend getInfoByBatchNumber(String batchNumber)throws Exception;
-
-    /**
-     * 修改子商品库存
-     */
-    void updateInventory(String type, Long id,MaterialExtend materialExtend) throws Exception;
 }

+ 27 - 4
src/main/java/com/jsh/erp/service/MaterialService.java

@@ -4,6 +4,7 @@ package com.jsh.erp.service;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.jsh.erp.datasource.dto.MaterialDto;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
@@ -27,6 +28,9 @@ public interface MaterialService extends IService<Material> {
 
     List<Material> getMaterial() throws Exception;
 
+    /**
+     * 查询商品管理-商品信息列表查询
+     */
     List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
                                  String materialOther, String weight, String expiryNum, String enableSerialNumber,
                                  String enableBatchNumber, String position, String enabled, String remark, String categoryId,
@@ -38,14 +42,14 @@ public interface MaterialService extends IService<Material> {
      * @param obj
      */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    int insertMaterial(JSONObject obj, HttpServletRequest request)throws Exception;
+    int insertMaterial(MaterialDto obj, HttpServletRequest request)throws Exception;
 
     /**
      * 修改商品
      * @param obj
      */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    int updateMaterial(JSONObject obj, HttpServletRequest request) throws Exception;
+    int updateMaterial(MaterialDto obj, HttpServletRequest request) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     int deleteMaterial(Long id, HttpServletRequest request)throws Exception;
@@ -103,8 +107,6 @@ public interface MaterialService extends IService<Material> {
 
     List<Material> getMaterialListByParam(String name, String standard, String model, String color, String unit, Long unitId, String basicBarCode) throws Exception;
 
-    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     void insertCurrentStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock);
@@ -133,6 +135,12 @@ public interface MaterialService extends IService<Material> {
 
     Map<Long,BigDecimal> getCurrentStockMapByMaterialList(List<MaterialVo4Unit> list);
 
+    /**
+     * 根据商品和仓库获取安全库存信息
+     * @param materialId 商品id
+     * @param depotId 仓库id
+     * @return
+     */
     MaterialInitialStock getSafeStock(Long materialId, Long depotId);
 
     List<MaterialVo4Unit> getMaterialByMeId(Long meId);
@@ -203,4 +211,19 @@ public interface MaterialService extends IService<Material> {
      * 查询库位树
      */
     List<PDATypeTree> selectPosition();
+
+    /**
+     * 获取仓库id、商品id获取商品库位信息
+     * @param did 仓库id
+     * @param mid 商品id
+     * @return 库位
+     */
+    String getPositionByDidAndMid(Long did, Long mid);
+
+    /**
+     * 根据商品id查询商品库存
+     * @param mid 商品id
+     * @return 商品库存
+     */
+    BigDecimal getMaterialStockByMid(Long mid);
 }

+ 1 - 1
src/main/java/com/jsh/erp/service/SystemConfigService.java

@@ -208,7 +208,7 @@ public class SystemConfigService {
 
             // Validate file extension to allow only specific types
             String[] allowedExtensions = {".gif", ".jpg", ".jpeg", ".png", ".pdf", ".txt",".doc",".docx",".xls",".xlsx",
-                    ".ppt",".pptx",".zip",".rar",".mp3",".mp4",".avi"};
+                    ".ppt",".pptx",".zip",".rar",".mp3",".mp4",".avi",".apk"};
             boolean isValidExtension = false;
             for (String ext : allowedExtensions) {
                 if (orgName.toLowerCase().endsWith(ext)) {

+ 47 - 25
src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java

@@ -99,6 +99,8 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
     private MaterialExtendService materialExtendService;
     @Resource
     private SyncTescoSystemService syncTescoSystemService;
+    @Resource
+    private MaterialBatchService materialBatchService;
 
     /**
      * PDA查询订单
@@ -732,6 +734,10 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         return materialsListMap;
     }
 
+    /**
+     * 根据单据主表id获取商品数量
+     * @param idList 单据主表id集合
+     */
     @Override
     public Map<Long,BigDecimal> getMaterialCountListMapByHeaderIdList(List<Long> idList)throws Exception {
         Map<Long,BigDecimal> materialCountListMap = new HashMap<>();
@@ -1123,12 +1129,17 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         }
         //判断用户是否已经登录过,登录过不再处理
         User userInfo=userService.getCurrentUser();
+        //创建人
         depotHead.setCreator(userInfo==null?null:userInfo.getId());
+        //创建时间
         depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        //订单状态
         if(StringUtil.isEmpty(depotHead.getStatus())) {
             depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
         }
+        //采购状态
         depotHead.setPurchaseStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
+        //付款类型
         depotHead.setPayType(depotHead.getPayType()==null?"现付":depotHead.getPayType());
         if(StringUtil.isNotEmpty(depotHead.getAccountIdList())){
             depotHead.setAccountIdList(depotHead.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", ""));
@@ -1198,8 +1209,10 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             Long headId = list.get(0).getId();
             /**入库和出库处理单据子表信息*/
             depotItemService.saveDetials(rows,headId, "add",request);
-            if (!list.get(0).getSubType().equals("其它") || !list.get(0).getSubType().equals("零售"))
-            updateTotalPriceById(list.get(0));
+            //处理实际入库数量价格总额
+//            if (list.get(0).getSubType().equals("采购") || !list.get(0).getSubType().equals("销售")){
+//                updateTotalPriceById(list.get(0));
+//            }
         }
         logService.insertLog("单据",
                 new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(depotHead.getNumber()).toString(),
@@ -1317,7 +1330,10 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         }
         /**入库和出库处理单据子表信息*/
         depotItemService.saveDetials(rows,depotHead.getId(), "update",request);
-        updateTotalPriceById(depotHead);
+        //处理实际入库数量价格总额
+//        if (depotHead.getSubType().equals("采购") || depotHead.getSubType().equals("销售")){
+//            updateTotalPriceById(depotHead);
+//        }
         logService.insertLog("单据",
                 new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(depotHead.getNumber()).toString(),
                 ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
@@ -1933,9 +1949,13 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         }
         //判断用户是否已经登录过,登录过不再处理
         User userInfo = userService.getCurrentUser();
+        //创建人
         depotHead.setCreator(userInfo==null?null:userInfo.getId());
+        //创建时间
         depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        //操作人
         depotHead.setOperId(userInfo==null?null:userInfo.getId());
+        //单据时间
         depotHead.setOperTime(new Timestamp(System.currentTimeMillis()));
         if(StringUtil.isEmpty(depotHead.getStatus())) {
             depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
@@ -1978,8 +1998,6 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         //设置凭证图片、备注
         depotHead.setVoucherPicture(pdaDepotHeadDTO.getVoucherPicture());
         depotHead.setRemark(pdaDepotHeadDTO.getRemark());
-        User user = userService.getCurrentUser();
-        depotHead.setTenantId(user.getId());
         depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
         depotHead.setStatus("2");
         //添加主表
@@ -1993,15 +2011,15 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             //获取子表单批次号
             String batchNumber = materialExtend.getBatchNumber();
             //修改原先采购订单实际入库数量
-            depotItemService.update(new UpdateWrapper<DepotItem>().set("actual_quantity_in_storage", materialMap.get(batchNumber).getMaterialNumber()).eq("id", depotItem.getId()));
+            //depotItemService.update(new UpdateWrapper<DepotItem>().set("actual_quantity_in_storage", materialMap.get(batchNumber).getMaterialNumber()).eq("id", depotItem.getId()));
             //设置单据主表id
             depotItem.setHeaderId(id);
             depotItem.setId(null);
             //设置实际入库数量
-            depotItem.setActualQuantityInStorage(materialMap.get(batchNumber).getMaterialNumber());
+            depotItem.setOperNumber(materialMap.get(batchNumber).getMaterialNumber());
             //以下进行单位换算
             Unit unitInfo = materialService.findUnit(depotItem.getMaterialId()); //查询多单位信息
-            if (StringUtil.isExist(depotItem.getActualQuantityInStorage())) {
+            if (StringUtil.isExist(depotItem.getOperNumber())) {
                 //获取子表单商品单位
                 String unit =depotItem.getMaterialUnit();
                 BigDecimal oNumber = depotItem.getActualQuantityInStorage();
@@ -2023,6 +2041,7 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
                     depotItem.setBasicNumber(oNumber); //其他情况
                 }
             }
+            User user = userService.getCurrentUser();
             depotItem.setWarehousingUser(user.getId());
             //基本单位数量*单价
             depotItem.setAllPrice(depotItem.getBasicNumber().multiply(depotItem.getUnitPrice()));
@@ -2031,13 +2050,12 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             //添加单据子表
             depotItemService.insertDepotItemWithObj(depotItem);
             if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
-                //表单入库,修改商品库存
-                materialExtend.setInventory(materialExtend.getInventory().add(depotItem.getBasicNumber()));
-                materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
+                //表单入库,新增批次商品信息
+                materialBatchService.generateMaterialBatchByDepotItemId(depotItem.getId());
             }else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                //表单库,修改商品库存
-                materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
-                materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
+                //表单库,修改商品库存
+                //materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
+                materialBatchService.handleMaterialBatchByDepotItemId(depotItem.getId());
             }
             //更新当前库存
             depotItemService.updateCurrentStock(depotItem);
@@ -2045,10 +2063,12 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             depotItemService.updateCurrentUnitPrice(depotItem);
             //修改商品生产日期
             materialExtendService.update(new UpdateWrapper<MaterialExtend>().set("production_date",materialMap.get(batchNumber).getProductionDate()).eq("id", materialExtend.getId()));
+            //修改订单总额
             updateTotalPriceById(depotHead);
         }
-        //修改采购订单状态完成
-        this.update(new UpdateWrapper<DepotHead>().set("status", "2").eq("id", pdaDepotHeadDTO.getId()));
+        //修改采购订单状态、操作人、操作时间
+        this.update(new UpdateWrapper<DepotHead>().set("status", "2").set("oper_id",userInfo.getId()).set("submit_time",new Date()).eq("id", pdaDepotHeadDTO.getId()));
+
         return true;
     }
 
@@ -2057,16 +2077,18 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
      */
     private void updateTotalPriceById(DepotHead depotHead) throws Exception {
         BigDecimal sum = BigDecimal.ZERO;
-        //获取单据子表
-        List<DepotItem> list = depotItemService.getListByHeaderId(depotHead.getId());
-        for (DepotItem depotItem : list) {
-            sum = sum.add(depotItem.getTaxLastMoney());
-        }
-        BigDecimal totalPrice = sum;
-        if (depotHead.getTotalPrice().compareTo(BigDecimal.ZERO) < 0){
-            totalPrice = totalPrice.negate();
+        if (depotHead.getSubType().equals("采购") || depotHead.getSubType().equals("销售") ){
+            //获取单据子表
+            List<DepotItem> list = depotItemService.getListByHeaderId(depotHead.getId());
+            for (DepotItem depotItem : list) {
+                sum = sum.add(depotItem.getTaxLastMoney());
+            }
+            BigDecimal totalPrice = sum;
+            if (depotHead.getTotalPrice().compareTo(BigDecimal.ZERO) < 0){
+                totalPrice = totalPrice.negate();
+            }
+            update(new UpdateWrapper<DepotHead>().set("total_price",totalPrice).set("change_amount",totalPrice).set("discount_last_money",sum).eq("id",list.get(0).getId()));
         }
-        update(new UpdateWrapper<DepotHead>().set("total_price",totalPrice).set("change_amount",totalPrice).set("discount_last_money",sum).eq("id",list.get(0).getId()));
     }
 
 }

+ 55 - 55
src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java

@@ -80,13 +80,20 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
     @Resource
     private SyncTescoSystemService syncTescoSystemService;
 
+    @Resource
+    private MaterialBatchService materialBatchService;
+
     /**
      * pda根据订单信息查询商品列表
      * @return
      */
     @Override
     public List<PDADepotItemVO> pdaList(Long id) {
-        return depotItemMapper.pdaList(id);
+        List<PDADepotItemVO> list = depotItemMapper.pdaList(id);
+        for (PDADepotItemVO pdaDepotItemVO : list) {
+            pdaDepotItemVO.setInventory(materialService.getMaterialStockByMid(pdaDepotItemVO.getMaterialId()).toString());
+        }
+        return list;
     }
 
     /**
@@ -257,16 +264,12 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         return result;
     }
 
-    /**
-     * 插入单据子表
-     * @param depotItem 单据子表
-     */
     @Override
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     public int insertDepotItemWithObj(DepotItem depotItem)throws Exception {
         User user = userService.getCurrentUser();
+        //创建时间
         depotItem.setCreateTime(new Date());
-        depotItem.setTenantId(user.getId());
         int result =0;
         try{
             result = depotItemMapper.insertSelective(depotItem);
@@ -489,23 +492,43 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
             //针对组装单、拆卸单校验是否存在组合件和普通子件
             checkAssembleWithMaterialType(rowArr, depotHead.getSubType());
             for (int i = 0; i < rowArr.size(); i++) {
-                DepotItem depotItem = new DepotItem();
                 JSONObject rowObj = JSONObject.parseObject(rowArr.getString(i));
-                depotItem.setHeaderId(headerId);
-                String batchNumber = rowObj.getString("batchNumber");
-                MaterialExtend materialExtend = materialExtendService.getInfoByBatchNumber(batchNumber);
+                String batchNumber = rowObj.getString("barCode");
+                //根据条码获取商品信息
+                MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(batchNumber);
                 if(materialExtend == null) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
                             String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, batchNumber));
                 }
+                //设置单据子表属性
+                DepotItem depotItem = new DepotItem();
+                //主表id
+                depotItem.setHeaderId(headerId);
+                //商品id
                 depotItem.setMaterialId(materialExtend.getMaterialId());
+                //商品条码id
                 depotItem.setMaterialExtendId(materialExtend.getId());
+                //商品单位
                 depotItem.setMaterialUnit(rowObj.getString("unit"));
+                //实际出入库数量
                 depotItem.setActualQuantityInStorage(rowObj.getBigDecimal("actualQuantityInStorage"));
+                //出入库差异
                 depotItem.setWarehousingVariance(rowObj.getBigDecimal("warehousingVariance"));
+                //出入库差异原因
                 depotItem.setReasonOfDifference(rowObj.getString("reasonOfDifference"));
+                //出入库用户
                 depotItem.setWarehousingUser(rowObj.getLong("warehousingUser"));
+                //warehousingTime
                 depotItem.setWarehousingTime(rowObj.getString("warehousingTime"));
+                //生产日期
+                depotItem.setProductionDate(rowObj.getDate("productionDate"));
+                //保质期天数
+                depotItem.setExpiryNum(rowObj.getInteger("expiryNum"));
+                //仓位货架
+                depotItem.setPosition(rowObj.getString("position"));
+                //销售价
+                depotItem.setWholesaleDecimal(rowObj.getBigDecimal("wholesaleDecimal"));
+                //获取商品信息
                 Material material= materialService.getMaterial(depotItem.getMaterialId());
                 if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber()) ||
                         BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
@@ -566,6 +589,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                     }
                 }
                 if (StringUtil.isExist(rowObj.get("batchNumber"))) {
+                    //设置基础单位数量
                     depotItem.setBatchNumber(rowObj.getString("batchNumber"));
                 } else {
                     //入库或出库
@@ -587,24 +611,26 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         }
                     }
                 }
+                //设置有效期
                 if (StringUtil.isExist(rowObj.get("expirationDate"))) {
                     depotItem.setExpirationDate(rowObj.getDate("expirationDate"));
                 }
+                //设置sku属性
                 if (StringUtil.isExist(rowObj.get("sku"))) {
                     depotItem.setSku(rowObj.getString("sku"));
                 }
+                //设置关联明细id
                 if (StringUtil.isExist(rowObj.get("linkId"))) {
                     depotItem.setLinkId(rowObj.getLong("linkId"));
                 }
                 //以下进行单位换算
                 Unit unitInfo = materialService.findUnit(materialExtend.getMaterialId()); //查询多单位信息
                 if (StringUtil.isExist(rowObj.get("operNumber"))) {
-                    //获取子表单商品数量
+                    //设置子表单商品数量
                     depotItem.setOperNumber(rowObj.getBigDecimal("operNumber"));
                     //获取子表单商品单位
                     String unit = rowObj.get("unit") == null ? "" :rowObj.get("unit").toString();
-                    //获取实际出入库数量
-                    BigDecimal oNumber = rowObj.getBigDecimal("actualQuantityInStorage");
+                    BigDecimal oNumber = depotItem.getOperNumber();
                     if (StringUtil.isNotEmpty(unitInfo.getName())) {
                         String basicUnit = unitInfo.getBasicUnit(); //基本单位
                         if (unit.equals(basicUnit)) { //如果等于基本单位
@@ -693,12 +719,8 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                 }
                 //总金额,不含税
                 if (StringUtil.isExist(rowObj.get("allPrice"))) {
-                    if (depotItem.getActualQuantityInStorage() == null || depotItem.getActualQuantityInStorage().equals(BigDecimal.ZERO)){
-                        depotItem.setAllPrice(rowObj.getBigDecimal("allPrice"));
-                    }else {
-                        //基本单位数量*单价
-                        depotItem.setAllPrice(depotItem.getBasicNumber().multiply(depotItem.getUnitPrice()));
-                    }
+                    //基本单位数量*单价
+                    depotItem.setAllPrice(depotItem.getBasicNumber().multiply(depotItem.getUnitPrice()));
                 }
                 if (StringUtil.isExist(rowObj.get("depotId"))) {
                     depotItem.setDepotId(rowObj.getLong("depotId"));
@@ -729,18 +751,12 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                 }
                 //税额
                 if (StringUtil.isExist(rowObj.get("taxMoney"))) {
-                    if (depotItem.getActualQuantityInStorage() == null || depotItem.getActualQuantityInStorage().equals(BigDecimal.ZERO)){
-                        depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
-                    }else {
-                        //单价总金额*税率
-                        depotItem.setTaxMoney(depotItem.getAllPrice().multiply(depotItem.getTaxRate()));
-                    }
+                    depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
                 }
                 //价税合计
                 if (StringUtil.isExist(rowObj.get("taxLastMoney"))) {
                     //单价总额 + 税额
-                    depotItem.setTaxLastMoney(depotItem.getAllPrice().add(depotItem.getTaxMoney()));
-                    //depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
+                    depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
                 }
                 if (StringUtil.isExist(rowObj.get("mType"))) {
                     depotItem.setMaterialType(rowObj.getString("mType"));
@@ -789,16 +805,15 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         }
                     }
                 }
+                this.insertDepotItemWithObj(depotItem);
                 if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
-                    //表单入库,修改商品库存
-                    materialExtend.setInventory(materialExtend.getInventory().add(depotItem.getBasicNumber()));
-                    materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
+                    //表单入库,新增批次商品信息
+                    materialBatchService.generateMaterialBatchByDepotItemId(depotItem.getId());
                 }else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                    //表单库,修改商品库存
-                    materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
-                    materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
+                    //表单库,修改商品库存
+                    //materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
+                    materialBatchService.handleMaterialBatchByDepotItemId(depotItem.getId());
                 }
-                this.insertDepotItemWithObj(depotItem);
                 //更新当前库存
                 updateCurrentStock(depotItem);
                 //更新当前成本价
@@ -1184,7 +1199,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
         BigDecimal stockSum = BigDecimal.ZERO;
         //获取商品子表单的库存总数
-        BigDecimal inventory = materialExtendMapper.getInventorySumByDepotAndMid(depotList,mId);
+        BigDecimal inventory = materialBatchService.getInventorySumByDepotAndMid(depotList,mId);
         if(stockObj!=null) {
             BigDecimal inTotal = stockObj.getInTotal();
             BigDecimal transfInTotal = stockObj.getTransfInTotal();
@@ -1491,32 +1506,17 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
 
 
     @Override
-    public JSONObject parseMapByExcelData(String batchNumbers, List<Map<String, String>> detailList, String prefixNo) throws Exception {
+    public JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception {
         JSONObject map = new JSONObject();
         JSONArray arr = new JSONArray();
         //根据批次号获取商品数据
-        List<MaterialVo4Unit> list = new ArrayList<>();
-        if ("XSDD".equals(prefixNo)){ //销售订单导入
-            String systemSku = batchNumbers.replace("'","");
-            List<String> strings = Arrays.asList(systemSku.split(","));
-            //根据系统sku查询商品
-            for (String str : strings) {
-                MaterialVo4Unit materialVo4Unit = depotItemMapperEx.getDepotMaterialBySystemSku(str);
-                list.add(materialVo4Unit);
-            }
-        }else {
-            list = depotItemMapperEx.getBillItemByParam(batchNumbers);
-        }
+        List<MaterialVo4Unit> list = depotItemMapperEx.getBillItemByParam(barCodes);
         //商品数据集合
         Map<String, MaterialVo4Unit> materialMap = new HashMap<>();
         //仓库集合
         Map<String, Long> depotMap = new HashMap<>();
         for (MaterialVo4Unit material: list) {
-            if ("XSDD".equals(prefixNo)){
-                materialMap.put(material.getSystemSku(), material);
-            }else {
-                materialMap.put(material.getBatchNumber(), material);
-            }
+            materialMap.put(material.getBarCode(), material);
         }
         //获取当前用户所有仓库
         JSONArray depotArr = depotService.findDepotByCurrentUser();
@@ -1528,7 +1528,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         }
         for (Map<String, String> detailMap: detailList) {
             JSONObject item = new JSONObject();
-            String barCode = detailMap.get("batchNumber");
+            String barCode = detailMap.get("barCode");
             if(StringUtil.isNotEmpty(barCode)) {
                 MaterialVo4Unit m = materialMap.get(barCode);
                 if(m!=null) {
@@ -1543,7 +1543,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                                     String.format(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_MSG, depotName));
                         }
                     }
-                    item.put("batchNumber", barCode);
+                    item.put("barCode", barCode);
                     item.put("name", m.getName());
                     item.put("standard", m.getStandard());
                     if(StringUtil.isNotEmpty(m.getModel())) {

+ 130 - 0
src/main/java/com/jsh/erp/service/impl/MaterialBatchServiceImpl.java

@@ -0,0 +1,130 @@
+package com.jsh.erp.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jsh.erp.datasource.entities.*;
+import com.jsh.erp.datasource.mappers.MaterialBatchMapper;
+import com.jsh.erp.service.*;
+import com.jsh.erp.utils.DateUtils;
+import com.jsh.erp.utils.RandomHelper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class MaterialBatchServiceImpl extends ServiceImpl<MaterialBatchMapper,MaterialBatch> implements MaterialBatchService {
+
+
+    @Resource
+    private MaterialBatchMapper materialBatchMapper;
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private DepotItemService depotItemService;
+
+    @Resource
+    private MaterialExtendService materialExtendService;
+
+    @Resource
+    private InventoryLogService inventoryLogService;
+
+
+    @Override
+    public void generateMaterialBatchByDepotItemId(Long diId) throws Exception {
+        //获取单据子表信息
+        DepotItem depotItem = depotItemService.getDepotItem(diId);
+        //获取条码信息
+        MaterialExtend materialExtend = materialExtendService.getMaterialExtend(depotItem.getMaterialExtendId());
+        //创建批次信息
+        MaterialBatch materialBatch = new MaterialBatch();
+        //设置单据id
+        materialBatch.setDepotItemId(diId);
+        //设置商品id
+        materialBatch.setMaterialId(depotItem.getMaterialId());
+        //设置商品单位
+        materialBatch.setCommodityUnit(depotItem.getMaterialUnit());
+        User user = userService.getCurrentUser();
+        //创建人编码
+        materialBatch.setCreateSerial(user.getLoginName());
+        //创建日期
+        materialBatch.setCreateTime(new Date());
+        //生产日期
+        materialBatch.setProductionDate(depotItem.getProductionDate());
+        //保质期天数
+        materialBatch.setExpiryNum(depotItem.getExpiryNum());
+        //批次号
+        String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
+        materialBatch.setBatchNumber(batchNumber);
+        //设置库存(订单基础单位数量)
+        materialBatch.setInventory(depotItem.getBasicNumber());
+        //仓库id
+        materialBatch.setDepotId(depotItem.getDepotId());
+        //仓位货架
+        materialBatch.setPosition(depotItem.getPosition());
+        materialBatchMapper.insert(materialBatch);
+    }
+
+    @Override
+    public synchronized void handleMaterialBatchByDepotItemId(Long diId) throws Exception {
+        DepotItem depotItem = depotItemService.getDepotItem(diId);
+        //根据单据商品id查询商品批次数据
+        List<MaterialBatch> list = materialBatchMapper.getMaterialBatchByMaterialId(depotItem.getMaterialId());
+        //根据单据子表基础单位数量减去批次库存
+        BigDecimal basicNumber = depotItem.getBasicNumber();
+        for (MaterialBatch materialBatch : list) {
+            if (materialBatch.getInventory().compareTo(basicNumber) >= 0){
+                //批次库存足够,扣除库存,结束循环
+                BigDecimal inventory = materialBatch.getInventory().subtract(basicNumber);
+                materialBatch.setInventory(inventory);
+                updateInventory("出库",diId,materialBatch);
+                break;
+            }else {
+                //库存不足,扣除当前批次库存,继续循环
+                basicNumber = basicNumber.subtract(materialBatch.getInventory());
+                materialBatch.setInventory(BigDecimal.ZERO);
+                updateInventory("出库",diId,materialBatch);
+            }
+        }
+
+    }
+
+    @Override
+    public synchronized void updateInventory(String type, Long id, MaterialBatch materialBatch) throws Exception {
+        if (materialBatch.getInventory() != null){
+            //获取修改前库存
+            int originalStock = materialBatchMapper.selectOne("id",materialBatch.getId()).getInventory().intValue();
+            if (originalStock != materialBatch.getInventory().intValue()){
+                //库存不相同,修改库存
+                User user = userService.getCurrentUser();
+                InventoryLog log = new InventoryLog();
+                log.setUpdateUser(user.getId());
+                log.setUpdateTime(new Date());
+                log.setMaterialId(materialBatch.getMaterialId());
+                log.setMaterialExtendId(materialBatch.getId());
+                log.setOriginalStock(originalStock);
+                log.setCurrentStock(materialBatch.getInventory().intValue());
+                log.setItemId(id);
+                log.setType(type);
+                inventoryLogService.save(log);
+                update(new UpdateWrapper<MaterialBatch>().set("inventory",materialBatch.getInventory()).eq("id",materialBatch.getId()));
+            }
+        }
+    }
+
+    /**
+     * 根据仓库id和商品id查询商品批次库存
+     * @param depotList 仓库id
+     * @param mid       商品id
+     */
+    @Override
+    public BigDecimal getInventorySumByDepotAndMid(List<Long> depotList, Long mid) {
+        return materialBatchMapper.getInventorySumByDepotAndMid(depotList,mid);
+    }
+
+}

+ 199 - 196
src/main/java/com/jsh/erp/service/impl/MaterialExtendServiceImpl.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jsh.erp.constants.BusinessConstants;
+import com.jsh.erp.datasource.dto.MaterialDto;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapper;
 import com.jsh.erp.datasource.mappers.MaterialExtendMapper;
@@ -93,174 +94,221 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
         return meList;
     }
 
-    /**
-     * 保存产品拓展记录
-     * @param obj
-     * @param sortList
-     * @param materialId
-     * @param type
-     * @return
-     * @throws Exception
-     */
+//    /**
+//     * 保存产品拓展记录
+//     * @param obj
+//     * @param sortList
+//     * @param materialId
+//     * @param type
+//     * @return
+//     * @throws Exception
+//     */
+//    @Override
+//    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+//    public String saveDetails(JSONObject obj, String sortList, Long materialId, String type) throws Exception {
+//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+//        //获取商品条码集合
+//        JSONArray meArr = obj.getJSONArray("meList");
+//        //添加商品拓展集合
+//        JSONArray insertedJson = new JSONArray();
+//        //修改商品拓展集合
+//        JSONArray updatedJson = new JSONArray();
+//        //移除商品集合
+//        JSONArray deletedJson = obj.getJSONArray("meDeleteIdList");
+//        JSONArray sortJson = JSONArray.parseArray(sortList);
+//        //添加/修改行数据处理
+//        if (null != meArr) {
+//            if("insert".equals(type)){
+//                for (int i = 0; i < meArr.size(); i++) {
+//                    JSONObject tempJson = meArr.getJSONObject(i);
+//                    insertedJson.add(tempJson);
+//                }
+//            } else if("update".equals(type)){
+//                for (int i = 0; i < meArr.size(); i++) {
+//                    JSONObject tempJson = meArr.getJSONObject(i);
+//                    String tempId = tempJson.getString("id");
+//                    if(tempId.length()>19){
+//                        //id长度大于19,属于新增数据
+//                        insertedJson.add(tempJson);
+//                    } else {
+//                        updatedJson.add(tempJson);
+//                    }
+//                }
+//            }
+//        }
+//        //删除行数据处理
+//        if (null != deletedJson && deletedJson.size()>0) {
+//            StringBuffer bf=new StringBuffer();
+//            for (int i = 0; i < deletedJson.size(); i++) {
+//                bf.append(deletedJson.getString(i));
+//                if(i<(deletedJson.size()-1)){
+//                    bf.append(",");
+//                }
+//            }
+//            //删除拓展行
+//            this.batchDeleteMaterialExtendByIds(bf.toString(), request);
+//        }
+//
+//        //添加产品拓展行
+//        if (null != insertedJson) {
+//            for (int i = 0; i < insertedJson.size(); i++) {
+//                //商品拓展
+//                MaterialExtend materialExtend = new MaterialExtend();
+//                JSONObject tempInsertedJson = JSONObject.parseObject(insertedJson.getString(i));
+//                //设置商品id
+//                materialExtend.setMaterialId(materialId);
+//                //设置商品单位
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityUnit"))) {
+//                    materialExtend.setCommodityUnit(tempInsertedJson.getString("commodityUnit"));
+//                }
+//                //设置商品属性
+//                if (tempInsertedJson.get("sku")!=null) {
+//                    materialExtend.setSku(tempInsertedJson.getString("sku"));
+//                }
+//                //设置采购价格
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("purchaseDecimal"))) {
+//                    materialExtend.setPurchaseDecimal(tempInsertedJson.getBigDecimal("purchaseDecimal"));
+//                }
+//                //设置零售价格
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityDecimal"))) {
+//                    materialExtend.setCommodityDecimal(tempInsertedJson.getBigDecimal("commodityDecimal"));
+//                }
+//                //设置销售价格
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("wholesaleDecimal"))) {
+//                    materialExtend.setWholesaleDecimal(tempInsertedJson.getBigDecimal("wholesaleDecimal"));
+//                }
+//                //设置最低售价
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("lowDecimal"))) {
+//                    materialExtend.setLowDecimal(tempInsertedJson.getBigDecimal("lowDecimal"));
+//                }
+//                //设置生产日期
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("productionDate"))) {
+//                    materialExtend.setProductionDate(tempInsertedJson.getDate("productionDate"));
+//                }
+//                //设置保质期天数
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("expiryNum"))) {
+//                    materialExtend.setExpiryNum(tempInsertedJson.getInteger("expiryNum"));
+//                }
+//                //设置供应商id
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("supplierId"))) {
+//                    materialExtend.setSupplierId(tempInsertedJson.getLong("supplierId"));
+//                }
+//                //设置商品条码
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("barCode"))) {
+//                    materialExtend.setBarCode(tempInsertedJson.getString("barCode"));
+//                }
+//                //设置批次号
+//                String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
+//                materialExtend.setBatchNumber(batchNumber);
+//                //设置库存
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("inventory"))) {
+//                    materialExtend.setInventory(tempInsertedJson.getBigDecimal("inventory"));
+//                }
+//                //设置仓库id
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("depotId"))) {
+//                    materialExtend.setDepotId(tempInsertedJson.getLong("depotId"));
+//                }
+//                //设置仓位货架
+//                if (StringUtils.isNotEmpty(tempInsertedJson.getString("position"))) {
+//                    materialExtend.setPosition(tempInsertedJson.getString("position"));
+//                }
+//                //添加数据
+//                this.insertMaterialExtend(materialExtend);
+//            }
+//        }
+//        //修改拓展行
+//        if (null != updatedJson) {
+//            for (int i = 0; i < updatedJson.size(); i++) {
+//                JSONObject tempUpdatedJson = JSONObject.parseObject(updatedJson.getString(i));
+//                MaterialExtend materialExtend = new MaterialExtend();
+//                //设置id
+//                materialExtend.setId(tempUpdatedJson.getLong("id"));
+//                materialExtend.setBarCode(tempUpdatedJson.getString("barCode"));
+//                //Json里的数据赋值到对象
+//                this.setMaterialExtend(tempUpdatedJson,materialExtend);
+//                //修改商品拓展
+//                this.updateMaterialExtend(materialExtend);
+//                //如果金额为空,此处单独置空
+//                materialExtendMapperEx.specialUpdatePrice(materialExtend);
+//            }
+//        }
+//        //处理条码的排序,基本单位排第一个
+//        if (null != sortJson && sortJson.size()>0) {
+//            //此处为更新的逻辑
+//            for (int i = 0; i < sortJson.size(); i++) {
+//                JSONObject tempSortJson = JSONObject.parseObject(sortJson.getString(i));
+//                MaterialExtend materialExtend = new MaterialExtend();
+//                if(StringUtil.isExist(tempSortJson.get("id"))) {
+//                    materialExtend.setId(tempSortJson.getLong("id"));
+//                }
+//                if(StringUtil.isExist(tempSortJson.get("defaultFlag"))) {
+//                    materialExtend.setDefaultFlag(tempSortJson.getString("defaultFlag"));
+//                }
+//                this.updateMaterialExtend(materialExtend);
+//            }
+//        } else {
+//            //新增的时候将第一条记录设置为默认基本单位
+//            MaterialExtendExample example = new MaterialExtendExample();
+//            example.createCriteria().andMaterialIdEqualTo(materialId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+//            List<MaterialExtend> meList = materialExtendMapper.selectByExample(example);
+//            if(meList!=null) {
+//                for(int i=0; i<meList.size(); i++) {
+//                    MaterialExtend materialExtend = new MaterialExtend();
+//                    materialExtend.setId(meList.get(i).getId());
+//                    if(i==0) {
+//                        materialExtend.setDefaultFlag("1"); //默认
+//                    } else {
+//                        materialExtend.setDefaultFlag("0"); //非默认
+//                    }
+//                    this.updateMaterialExtend(materialExtend);
+//                }
+//            }
+//        }
+//        return null;
+//    }
+
+
     @Override
-    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public String saveDetials(JSONObject obj, String sortList, Long materialId, String type) throws Exception {
-        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
-        //获取商品拓展行参数集合
-        JSONArray meArr = obj.getJSONArray("meList");
-        //添加商品拓展集合
-        JSONArray insertedJson = new JSONArray();
-        //修改商品拓展集合
-        JSONArray updatedJson = new JSONArray();
-        //移除商品集合
-        JSONArray deletedJson = obj.getJSONArray("meDeleteIdList");
-        JSONArray sortJson = JSONArray.parseArray(sortList);
+    public String saveDetails(List<MaterialExtend> materialExtends, String sortList, Long materialId, String type) throws Exception {
+        //添加商品条码集合
+        List<MaterialExtend> insertedList = new ArrayList<>();
+        //修改商品条码集合
+        List<MaterialExtend> updatedList = new ArrayList<>();
         //添加/修改行数据处理
-        if (null != meArr) {
+        if (null != materialExtends) {
             if("insert".equals(type)){
-                for (int i = 0; i < meArr.size(); i++) {
-                    JSONObject tempJson = meArr.getJSONObject(i);
-                    insertedJson.add(tempJson);
+                for (int i = 0; i < materialExtends.size(); i++) {
+                    MaterialExtend materialExtend = materialExtends.get(i);
+                    insertedList.add(materialExtend);
                 }
             } else if("update".equals(type)){
-                for (int i = 0; i < meArr.size(); i++) {
-                    JSONObject tempJson = meArr.getJSONObject(i);
-                    String tempId = tempJson.getString("id");
-                    if(tempId.length()>19){
-                        //id长度大于19,属于新增数据
-                        insertedJson.add(tempJson);
+                for (int i = 0; i < materialExtends.size(); i++) {
+                    MaterialExtend materialExtend = materialExtends.get(i);
+                    Long id = materialExtend.getId();
+                    if(id != null && id > 0){
+                        //id不等于空并且大于0,属于修改数据
+                        updatedList.add(materialExtend);
                     } else {
-                        updatedJson.add(tempJson);
+                        insertedList.add(materialExtend);
                     }
                 }
             }
         }
-        //删除行数据处理
-        if (null != deletedJson && deletedJson.size()>0) {
-            StringBuffer bf=new StringBuffer();
-            for (int i = 0; i < deletedJson.size(); i++) {
-                bf.append(deletedJson.getString(i));
-                if(i<(deletedJson.size()-1)){
-                    bf.append(",");
-                }
-            }
-            //删除拓展行
-            this.batchDeleteMaterialExtendByIds(bf.toString(), request);
-        }
-
-        //添加产品拓展行
-        if (null != insertedJson) {
-            for (int i = 0; i < insertedJson.size(); i++) {
-                //商品拓展
-                MaterialExtend materialExtend = new MaterialExtend();
-                JSONObject tempInsertedJson = JSONObject.parseObject(insertedJson.getString(i));
+        //添加条码
+        if (!insertedList.isEmpty()) {
+            for (MaterialExtend materialExtend : insertedList) {
                 //设置商品id
                 materialExtend.setMaterialId(materialId);
-                //设置商品单位
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityUnit"))) {
-                    materialExtend.setCommodityUnit(tempInsertedJson.getString("commodityUnit"));
-                }
-                //设置商品属性
-                if (tempInsertedJson.get("sku")!=null) {
-                    materialExtend.setSku(tempInsertedJson.getString("sku"));
-                }
-                //设置采购价格
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("purchaseDecimal"))) {
-                    materialExtend.setPurchaseDecimal(tempInsertedJson.getBigDecimal("purchaseDecimal"));
-                }
-                //设置零售价格
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityDecimal"))) {
-                    materialExtend.setCommodityDecimal(tempInsertedJson.getBigDecimal("commodityDecimal"));
-                }
-                //设置销售价格
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("wholesaleDecimal"))) {
-                    materialExtend.setWholesaleDecimal(tempInsertedJson.getBigDecimal("wholesaleDecimal"));
-                }
-                //设置最低售价
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("lowDecimal"))) {
-                    materialExtend.setLowDecimal(tempInsertedJson.getBigDecimal("lowDecimal"));
-                }
-                //设置生产日期
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("productionDate"))) {
-                    materialExtend.setProductionDate(tempInsertedJson.getDate("productionDate"));
-                }
-                //设置保质期天数
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("expiryNum"))) {
-                    materialExtend.setExpiryNum(tempInsertedJson.getInteger("expiryNum"));
-                }
-                //设置供应商id
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("supplierId"))) {
-                    materialExtend.setSupplierId(tempInsertedJson.getLong("supplierId"));
-                }
-                //设置商品条码
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("barCode"))) {
-                    materialExtend.setBarCode(tempInsertedJson.getString("barCode"));
-                }
-                //设置批次号
-                String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
-                materialExtend.setBatchNumber(batchNumber);
-                //设置库存
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("inventory"))) {
-                    materialExtend.setInventory(tempInsertedJson.getBigDecimal("inventory"));
-                }
-                //设置仓库id
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("depotId"))) {
-                    materialExtend.setDepotId(tempInsertedJson.getLong("depotId"));
-                }
-                //设置仓位货架
-                if (StringUtils.isNotEmpty(tempInsertedJson.getString("position"))) {
-                    materialExtend.setPosition(tempInsertedJson.getString("position"));
-                }
                 //添加数据
                 this.insertMaterialExtend(materialExtend);
             }
         }
+
         //修改拓展行
-        if (null != updatedJson) {
-            for (int i = 0; i < updatedJson.size(); i++) {
-                JSONObject tempUpdatedJson = JSONObject.parseObject(updatedJson.getString(i));
-                MaterialExtend materialExtend = new MaterialExtend();
-                //设置id
-                materialExtend.setId(tempUpdatedJson.getLong("id"));
-                materialExtend.setBarCode(tempUpdatedJson.getString("barCode"));
-                //Json里的数据赋值到对象
-                this.setMaterialExtend(tempUpdatedJson,materialExtend);
+        if (!updatedList.isEmpty()) {
+            for (MaterialExtend materialExtend : updatedList) {
                 //修改商品拓展
                 this.updateMaterialExtend(materialExtend);
-                //如果金额为空,此处单独置空
-                materialExtendMapperEx.specialUpdatePrice(materialExtend);
-            }
-        }
-        //处理条码的排序,基本单位排第一个
-        if (null != sortJson && sortJson.size()>0) {
-            //此处为更新的逻辑
-            for (int i = 0; i < sortJson.size(); i++) {
-                JSONObject tempSortJson = JSONObject.parseObject(sortJson.getString(i));
-                MaterialExtend materialExtend = new MaterialExtend();
-                if(StringUtil.isExist(tempSortJson.get("id"))) {
-                    materialExtend.setId(tempSortJson.getLong("id"));
-                }
-                if(StringUtil.isExist(tempSortJson.get("defaultFlag"))) {
-                    materialExtend.setDefaultFlag(tempSortJson.getString("defaultFlag"));
-                }
-                this.updateMaterialExtend(materialExtend);
-            }
-        } else {
-            //新增的时候将第一条记录设置为默认基本单位
-            MaterialExtendExample example = new MaterialExtendExample();
-            example.createCriteria().andMaterialIdEqualTo(materialId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            List<MaterialExtend> meList = materialExtendMapper.selectByExample(example);
-            if(meList!=null) {
-                for(int i=0; i<meList.size(); i++) {
-                    MaterialExtend materialExtend = new MaterialExtend();
-                    materialExtend.setId(meList.get(i).getId());
-                    if(i==0) {
-                        materialExtend.setDefaultFlag("1"); //默认
-                    } else {
-                        materialExtend.setDefaultFlag("0"); //非默认
-                    }
-                    this.updateMaterialExtend(materialExtend);
-                }
             }
         }
         return null;
@@ -278,25 +326,9 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
         materialExtend.setDeleteFlag(BusinessConstants.DELETE_FLAG_EXISTS);
         //创建时间
         materialExtend.setCreateTime(new Date());
-        //修改时间
-        materialExtend.setUpdateTime(new Date().getTime());
         //创建用户
         materialExtend.setCreateSerial(user.getLoginName());
-        //修改用户
-        materialExtend.setUpdateSerial(user.getLoginName());
-        int result = 0;
-        try{
-            result= materialExtendMapper.insertSelective(materialExtend);
-            //更新当前库存
-            depotItemService.updateCurrentStockFun(materialExtend.getMaterialId(), materialExtend.getDepotId());
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        //修改当前库存
-        if (materialExtend.getDepotId() != null && materialExtend.getInventory() != null){
-            insertCurrentStockByMaterialAndDepot(materialExtend.getDepotId(),materialExtend.getMaterialId(),materialExtend.getInventory(),"add");
-        }
-        return result;
+        return materialExtendMapper.insertSelective(materialExtend);
     }
 
     /**
@@ -309,15 +341,7 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
         User user = userService.getCurrentUser();
         materialExtend.setUpdateTime(System.currentTimeMillis());
         materialExtend.setUpdateSerial(user.getLoginName());
-        int res =0;
-        try{
-            //修改库存
-            updateInventory("商品修改",null,materialExtend);
-            res= materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return res;
+        return materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
     }
 
     @Override
@@ -498,27 +522,6 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
     }
 
     /**
-     * 修改子商品库存
-     */
-    @Override
-    public synchronized void updateInventory(String type, Long id, MaterialExtend materialExtend) throws Exception {
-        if (materialExtend.getInventory() != null){
-            User user = userService.getCurrentUser();
-            InventoryLog log = new InventoryLog();
-            log.setUpdateUser(user.getId());
-            log.setUpdateTime(new Date());
-            log.setMaterialId(materialExtend.getMaterialId());
-            log.setMaterialExtendId(materialExtend.getId());
-            log.setOriginalStock(materialExtendMapper.selectByPrimaryKey(materialExtend.getId()).getInventory().intValue());
-            Integer i = materialExtend.getInventory().intValue();
-            log.setCurrentStock(i);
-            log.setItemId(id);
-            log.setType(type);
-            inventoryLogService.save(log);
-            update(new UpdateWrapper<MaterialExtend>().set("inventory",materialExtend.getInventory()).set("position",materialExtend.getPosition()).eq("id",materialExtend.getId()));
-        }
-    }
-    /**
      * 设置当前库存
      * @param depotId 仓库id
      * @param mId 商品id

+ 106 - 128
src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java

@@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jsh.erp.constants.BusinessConstants;
 import com.jsh.erp.constants.ExceptionConstants;
+import com.jsh.erp.datasource.dto.MaterialDto;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.mappers.*;
 import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
@@ -15,7 +16,6 @@ import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
 import com.jsh.erp.datasource.pda.vo.PDATypeTree;
 import com.jsh.erp.datasource.vo.MaterialVoSearch;
 import com.jsh.erp.datasource.vo.MaterialWarnListVo;
-import com.jsh.erp.datasource.vo.TreeNode;
 import com.jsh.erp.exception.BusinessRunTimeException;
 import com.jsh.erp.exception.JshException;
 import com.jsh.erp.query.LambdaQueryWrapperX;
@@ -88,6 +88,9 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     @Resource
     private DepotMapperEx depotMapperEx;
 
+    @Resource
+    private MaterialBatchService materialBarCodeService;
+
     @Value(value="${file.uploadType}")
     private Long fileUploadType;
 
@@ -130,9 +133,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     }
 
 
-    /**
-     * 查询商品管理-商品信息列表查询
-     */
+
     @Override
     public List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
                                         String materialOther, String weight, String expiryNum, String enableSerialNumber,
@@ -178,51 +179,52 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
      */
     @Override
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int insertMaterial(JSONObject obj, HttpServletRequest request)throws Exception {
+    public int insertMaterial(MaterialDto obj, HttpServletRequest request)throws Exception {
         //商品主表信息
-        Material m = JSONObject.parseObject(obj.toJSONString(), Material.class);
+        Material m = obj;
+        //设置状态
         m.setEnabled(true);
         //获取类型编码
         Long serial_no = materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
-        String sku = serial_no + DateUtils.dateTimeNow();
+        String sku = serial_no + DateUtils.dateTimeNow()  + RandomHelper.getRandomStr(4);
         //设置系统sku
         m.setSystemSku(sku);
         User user = userService.getCurrentUser();
-        m.setTenantId(user.getId());
         try{
             //添加商品
             materialMapperEx.insertSelectiveEx(m);
             Long mId = m.getId();
-            //添加商品拓展记录
-            materialExtendService.saveDetials(obj, obj.getString("sortList"), mId, "insert");
+            //添加商品条码信息
+            materialExtendService.saveDetails(obj.getMbList(),obj.getSortList().toJSONString(),mId,"insert");
+            //materialExtendService.saveDetials(null, obj.getSortList(), mId, "insert");
             //设置初始库存
-            if(obj.get("stock")!=null) {
-                JSONArray stockArr = obj.getJSONArray("stock");
+            if(obj.getStock()!=null) {
+                List<MaterialInitialStock> stockArr = obj.getStock();
                 for (int i = 0; i < stockArr.size(); i++) {
-                    JSONObject jsonObj = stockArr.getJSONObject(i);
-                    if(jsonObj.get("id")!=null && jsonObj.get("initStock")!=null) {
-                        String number = jsonObj.getString("initStock");
-                        BigDecimal lowSafeStock = null;
+                    MaterialInitialStock jsonObj = stockArr.get(i);
+                    //此时id为仓库id,仓库di、最低安全库存数量不为空
+                    if(jsonObj.getId() != null && jsonObj.getLowSafeStock() != null || jsonObj.getPosition() != null) {
+                        BigDecimal lowSafeStock = jsonObj.getLowSafeStock();
                         BigDecimal highSafeStock = null;
-                        if(jsonObj.get("lowSafeStock")!=null) {
-                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
-                        }
-                        if(jsonObj.get("highSafeStock")!=null) {
-                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
+                        if(jsonObj.getHighSafeStock() != null) {
+                            highSafeStock = jsonObj.getHighSafeStock();
                         }
-                        Long depotId = jsonObj.getLong("id");
-                        if(StringUtil.isNotEmpty(number) && Double.parseDouble(number)>0 || lowSafeStock!=null || highSafeStock!=null) {
+                        Long depotId = jsonObj.getId();
+                        jsonObj.setDepotId(depotId);
+                        jsonObj.setMaterialId(mId);
+                        jsonObj.setId(null);
+                        if(lowSafeStock != null || highSafeStock != null || jsonObj.getPosition() != null) {
                             //设置初始库
-                            insertInitialStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number), lowSafeStock, highSafeStock);
+                            materialInitialStockMapper.insertSelective(jsonObj);
+                            //insertInitialStockByMaterialAndDepot(jsonObj);
                             //设置当前库
                             //insertCurrentStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number));
                             //更新当前库存
-                            depotItemService.updateCurrentStockFun(mId, depotId);
+                            //depotItemService.updateCurrentStockFun(mId, depotId);
                         }
                     }
                 }
             }
-
             logService.insertLog("商品",
                     new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(m.getName()).toString(), request);
             return 1;
@@ -243,43 +245,39 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
      */
     @Override
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int updateMaterial(JSONObject obj, HttpServletRequest request) throws Exception{
-        Material material = JSONObject.parseObject(obj.toJSONString(), Material.class);
+    public int updateMaterial(MaterialDto obj, HttpServletRequest request) throws Exception{
+        Material material = obj;
         try{
             //修改商品属性
             materialMapper.updateByPrimaryKeySelective(material);
-            //
             if(material.getUnitId() == null) {
                 materialMapperEx.setUnitIdToNull(material.getId());
             }
-//            if(material.getExpiryNum() == null) {
-//                materialMapperEx.setExpiryNumToNull(material.getId());
-//            }
-            materialExtendService.saveDetials(obj, obj.getString("sortList"),material.getId(), "update");
-            if(obj.get("stock")!=null) {
-                JSONArray stockArr = obj.getJSONArray("stock");
+            materialExtendService.saveDetails(obj.getMbList(), obj.getSortList().toJSONString(),material.getId(), "update");
+            if(obj.getStock()!=null) {
+                List<MaterialInitialStock> stockArr = obj.getStock();
                 for (int i = 0; i < stockArr.size(); i++) {
-                    JSONObject jsonObj = stockArr.getJSONObject(i);
-                    if (jsonObj.get("id") != null && jsonObj.get("initStock") != null) {
-                        String number = jsonObj.getString("initStock");
-                        BigDecimal lowSafeStock = null;
+                    MaterialInitialStock jsonObj = stockArr.get(i);
+                    if(jsonObj.getId() != null && jsonObj.getLowSafeStock() != null || jsonObj.getPosition() != null) {
+                        BigDecimal lowSafeStock = jsonObj.getLowSafeStock();
                         BigDecimal highSafeStock = null;
-                        if(jsonObj.get("lowSafeStock")!=null) {
-                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
-                        }
-                        if(jsonObj.get("highSafeStock")!=null) {
-                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
+                        if(jsonObj.getHighSafeStock() != null) {
+                            highSafeStock = jsonObj.getHighSafeStock();
                         }
-                        Long depotId = jsonObj.getLong("id");
+                        Long depotId = jsonObj.getId();
+                        jsonObj.setMaterialId(material.getId());
+                        jsonObj.setDepotId(depotId);
+                        jsonObj.setId(null);
                         //初始库存-先清除再插入
                         MaterialInitialStockExample example = new MaterialInitialStockExample();
                         example.createCriteria().andMaterialIdEqualTo(material.getId()).andDepotIdEqualTo(depotId);
                         materialInitialStockMapper.deleteByExample(example);
-                        if (StringUtil.isNotEmpty(number) || lowSafeStock!=null || highSafeStock!=null) {
-                            insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx(number), lowSafeStock, highSafeStock);
+                        if (lowSafeStock!=null || highSafeStock!=null || jsonObj.getPosition() != null) {
+                            //insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx("0"), lowSafeStock, highSafeStock);
+                            materialInitialStockMapper.insertSelective(jsonObj);
                         }
                         //更新当前库存
-                        depotItemService.updateCurrentStockFun(material.getId(), depotId);
+                        //depotItemService.updateCurrentStockFun(material.getId(), depotId);
                     }
                 }
             }
@@ -1198,29 +1196,6 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     }
 
     /**
-     * 写入初始库存
-     * @param depotId 仓库id
-     * @param mId   商品id
-     * @param stock 库存数量
-     */
-    @Override
-    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock){
-        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
-        materialInitialStock.setDepotId(depotId);
-        materialInitialStock.setMaterialId(mId);
-        stock = stock == null? BigDecimal.ZERO: stock;
-        materialInitialStock.setNumber(stock);
-        if(lowSafeStock!=null) {
-            materialInitialStock.setLowSafeStock(lowSafeStock);
-        }
-        if(highSafeStock!=null) {
-            materialInitialStock.setHighSafeStock(highSafeStock);
-        }
-        materialInitialStockMapper.insertSelective(materialInitialStock); //存入初始库存
-    }
-
-    /**
      * 写入当前库存
      * @param depotId 仓库id
      * @param mId   商品id
@@ -1465,7 +1440,12 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     @Override
     public List<MaterialVo4Unit> getMaterialByBarCode(String barCode) {
         String [] barCodeArray=barCode.split(",");
-        return materialMapperEx.getMaterialByBarCode(barCodeArray);
+        List<MaterialVo4Unit> list = materialMapperEx.getMaterialByBarCode(barCodeArray);
+        list.forEach(v -> {
+            v.setUnitList(v.getUnitId() == null ? null : unitService.getUnitListByID(v.getUnitId()));
+            v.setInventory(getMaterialStockByMid(v.getId()));
+        });
+        return list;
     }
 
     @Override
@@ -1761,6 +1741,25 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
             }
             for (int i = 2; i < rightRows; i++) {
                 String name = ExcelUtils.getContent(src, i, 0); //名称
+                String standard = ExcelUtils.getContent(src, i, 1); //规格
+                String model = ExcelUtils.getContent(src, i, 2); //型号
+                String color = ExcelUtils.getContent(src, i, 3); //颜色
+                String brand = ExcelUtils.getContent(src, i, 4); //品牌
+                String categoryName = ExcelUtils.getContent(src, i, 5); //类别
+                String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
+                String unit = ExcelUtils.getContent(src, i, 7); //基本单位
+                String manyUnit = ExcelUtils.getContent(src, i, 8); //副单位
+                String ratio = ExcelUtils.getContent(src, i, 9); //比例
+                String enabled = ExcelUtils.getContent(src, i, 10); //状态
+                String enableSerialNumber = ExcelUtils.getContent(src, i, 11); //序列号
+                String barCode = ExcelUtils.getContent(src, i, 12); //商品条码
+                String otherField1 = ExcelUtils.getContent(src, i, 13); //自定义1
+                String otherField2 = ExcelUtils.getContent(src, i, 14); //自定义2
+                String otherField3 = ExcelUtils.getContent(src, i, 15); //自定义3
+                String remark = ExcelUtils.getContent(src, i, 16); //备注
+                String depotName = ExcelUtils.getContent(src, i, 17); //仓库名称
+                String position = ExcelUtils.getContent(src, i, 18); //仓位货架
+                //校验字段
                 //名称为空
                 if(StringUtil.isEmpty(name)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
@@ -1771,21 +1770,16 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_OVER_CODE,
                             String.format(ExceptionConstants.MATERIAL_NAME_OVER_MSG, i+1));
                 }
-                String standard = ExcelUtils.getContent(src, i, 1); //规格
                 //规格长度超出
                 if(StringUtil.isNotEmpty(standard) && standard.length()>100) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STANDARD_OVER_CODE,
                             String.format(ExceptionConstants.MATERIAL_STANDARD_OVER_MSG, i+1));
                 }
-                String model = ExcelUtils.getContent(src, i, 2); //型号
                 //型号长度超出
                 if(StringUtil.isNotEmpty(model) && model.length()>100) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_MODEL_OVER_CODE,
                             String.format(ExceptionConstants.MATERIAL_MODEL_OVER_MSG, i+1));
                 }
-                String color = ExcelUtils.getContent(src, i, 3); //颜色
-                String brand = ExcelUtils.getContent(src, i, 4); //品牌
-                String categoryName = ExcelUtils.getContent(src, i, 5); //类别
                 //类别为空
                 if(StringUtil.isEmpty(categoryName)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_Category_Name_EMPTY_CODE,
@@ -1798,7 +1792,6 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TYPE_NOT_DECIMAL_CODE,
                             String.format(ExceptionConstants.MATERIAL_TYPE_NOT_DECIMAL_MSG, i+1));
                 }
-                String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
                 if(StringUtil.isNotEmpty(weight)) {
                     //校验基础重量是否是数字(含小数)
                     if(!StringUtil.isPositiveBigDecimal(weight)) {
@@ -1806,51 +1799,18 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                                 String.format(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_MSG, i+1));
                     }
                 }
-                String unit = ExcelUtils.getContent(src, i, 7); //基本单位
                 //基本单位为空
                 if(StringUtil.isEmpty(unit)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_EMPTY_CODE,
                             String.format(ExceptionConstants.MATERIAL_UNIT_EMPTY_MSG, i+1));
                 }
-                String manyUnit = ExcelUtils.getContent(src, i, 8); //副单位
-                String ratio = ExcelUtils.getContent(src, i, 9); //比例
-                String sku = ExcelUtils.getContent(src, i, 10); //多属性
-                String purchaseDecimal = ExcelUtils.getContent(src, i, 11); //采购价
-                String commodityDecimal = ExcelUtils.getContent(src, i, 12); //零售价
-                String wholesaleDecimal = ExcelUtils.getContent(src, i, 13); //销售价
-                String lowDecimal = ExcelUtils.getContent(src, i, 14); //最低售价
-                String enabled = ExcelUtils.getContent(src, i, 15); //状态
                 //状态格式错误
                 if(!"1".equals(enabled) && !"0".equals(enabled)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLED_ERROR_CODE,
                             String.format(ExceptionConstants.MATERIAL_ENABLED_ERROR_MSG, i+1));
                 }
-                String enableSerialNumber = ExcelUtils.getContent(src, i, 16); //序列号
-                String productionDate = ExcelUtils.getContent(src, i, 17); //生产日期
-                String expiryNum = ExcelUtils.getContent(src, i, 18); //保质期天数
-                if(StringUtil.isNotEmpty(expiryNum)) {
-                    //校验保质期是否是正整数
-                    if(!StringUtil.isPositiveLong(expiryNum)) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_CODE,
-                                String.format(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_MSG, i+1));
-                    }
-                }
-                String supplier = ExcelUtils.getContent(src, i, 19); //供应商
-                Long supplierId = null;
-                if(StringUtil.isNotEmpty(supplier)) {
-                    //根据供应商查询供应商id
-                    Supplier s  = supplierService.getOne(new LambdaQueryWrapperX<Supplier>().eq(Supplier::getSupplier,supplier));
-                    supplierId = s.getId();
-                    if (supplierId == null){
-                        //供应商不存在
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SUPPLIER_NOT_DECIMAL_CODE,
-                                String.format(ExceptionConstants.MATERIAL_SUPPLIER_NOT_DECIMAL_MSG, i+1));
-                    }
-                }
-                String barCode = ExcelUtils.getContent(src, i, 20); //商品条码
-                String depotName = ExcelUtils.getContent(src, i, 21); //仓库名称
                 Long depotId = null;
-                if(StringUtil.isNotEmpty(supplier)) {
+                if(StringUtil.isNotEmpty(depotName)) {
                     //根据仓库名查询仓库id
                     depotId = depotMapperEx.selectByConditionDepot(depotName,null,null).get(0).getId();
                     if (depotId == null){
@@ -1859,12 +1819,6 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                                 String.format(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_MSG, i+1));
                     }
                 }
-                String position = ExcelUtils.getContent(src, i, 22); //仓位货架
-                String inventory = ExcelUtils.getContent(src,i,23);//库存
-                String otherField1 = ExcelUtils.getContent(src, i, 24); //自定义1
-                String otherField2 = ExcelUtils.getContent(src, i, 25); //自定义2
-                String otherField3 = ExcelUtils.getContent(src, i, 26); //自定义3
-                String remark = ExcelUtils.getContent(src, i, 27); //备注
                 MaterialWithInitStock m = new MaterialWithInitStock();
                 //设置商品名字、规格、型号、颜色、品牌、类型id
                 m.setName(name);
@@ -1890,7 +1844,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                 //获取类型编码
                 Long serial_no = categoryId == null ? null : materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
                 //设置系统sku
-                m.setSystemSku(serial_no + DateUtils.dateTimeNow() + RandomHelper.getRandomStr(6));
+                m.setSystemSku(serial_no + DateUtils.dateTimeNow() + RandomHelper.getRandomStr(4));
                 m.setOtherField1(StringUtil.isNotEmpty(otherField1)?otherField1:null);
                 m.setOtherField2(StringUtil.isNotEmpty(otherField2)?otherField2:null);
                 m.setOtherField3(StringUtil.isNotEmpty(otherField3)?otherField3:null);
@@ -1899,16 +1853,16 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                 JSONObject materialExObj = new JSONObject();
                 JSONObject basicObj = new JSONObject();
                 basicObj.put("commodityUnit", unit);    //商品单位
-                basicObj.put("sku", sku);   //商品属性
-                basicObj.put("purchaseDecimal", purchaseDecimal);   //采购价格
-                basicObj.put("commodityDecimal", commodityDecimal); //零售价格
-                basicObj.put("wholesaleDecimal", wholesaleDecimal); //销售价格
-                basicObj.put("lowDecimal", lowDecimal); //最低售价
-                basicObj.put("productionDate",productionDate); //生产日期
-                basicObj.put("expiryNum",expiryNum);    //保质期天数
-                basicObj.put("supplierId",supplierId); //供应商id
+                //basicObj.put("sku", sku);   //商品属性
+//                basicObj.put("purchaseDecimal", purchaseDecimal);   //采购价格
+//                basicObj.put("commodityDecimal", commodityDecimal); //零售价格
+//                basicObj.put("wholesaleDecimal", wholesaleDecimal); //销售价格
+//                basicObj.put("lowDecimal", lowDecimal); //最低售价
+//                basicObj.put("productionDate",productionDate); //生产日期
+//                basicObj.put("expiryNum",expiryNum);    //保质期天数
+//                basicObj.put("supplierId",supplierId); //供应商id
                 basicObj.put("barCode", barCode); //商品条码
-                basicObj.put("inventory",inventory); //库存
+//                basicObj.put("inventory",inventory); //库存
                 basicObj.put("depotId",depotId);    //仓库id
                 basicObj.put("position",position);  //仓位货架
                 materialExObj.put("basic", basicObj);
@@ -2013,6 +1967,30 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     }
 
     /**
+     * 获取仓库id、商品id获取商品库位信息
+     * @param did 仓库id
+     * @param mid 商品id
+     * @return 库位
+     */
+    @Override
+    public String getPositionByDidAndMid(Long did, Long mid) {
+        MaterialInitialStock stock = materialInitialStockMapper.selectOne(new QueryWrapperX<MaterialInitialStock>().eq("depot_id",did).eq("material_id",mid));
+        return stock == null ? null : stock.getPosition();
+    }
+
+    /**
+     * 根据商品id查询商品库存
+     * @param mid 商品id
+     * @return 商品库存
+     */
+    @Override
+    public BigDecimal getMaterialStockByMid(Long mid){
+        List<Long> materialIdList = Arrays.asList(mid);
+        List<MaterialCurrentStock> mcsList = materialCurrentStockMapperEx.getCurrentStockMapByIdList(materialIdList);
+        return mcsList.size() == 0 ? BigDecimal.ZERO : mcsList.get(0).getCurrentNumber();
+    }
+
+    /**
      * 解析excel表格数据为商品对象
      */
     public List<Material> parseMapByExcelData(List<MaterialWithInitStock> mList){

+ 12 - 3
src/main/resources/application-dev.yml

@@ -7,7 +7,7 @@ server:
 #文件上传方式 1-本机 2-oss
 file:
   uploadType: 2
-  path: /pc/dev/upload #文件上传根目录
+  path: /root/erp/apk #文件上传根目录
 
 spring:
   #数据库连接
@@ -20,7 +20,7 @@ spring:
   redis:
     host: 127.0.0.1
     port: 6379
-    password:
+    password: foobared
 
 aliyun:
   accessKeyId: LTAI5tAWjmJQaDBF6u7JAgap
@@ -30,7 +30,16 @@ aliyun:
     bucketName: xiangli-erp
     miniProgramAppId: wxd716cb744e32271a
     linkUrl: https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com
+
 tesco:
   openSycn: false
   sycnErpMaterialStockUrl: http://localhost:8088/no-auth/erp/sync-stock
-  sycnErpMaterialPriceUrl: http://localhost:8088/no-auth/erp/sync-saleprice
+  sycnErpMaterialPriceUrl: http://localhost:8088/no-auth/erp/sync-saleprice
+mybatis-plus:
+  global-config:
+    db-config:
+      id-type: auto
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    #   log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+    default-executor-type: simple

+ 2 - 2
src/main/resources/application.yml

@@ -22,5 +22,5 @@ spring:
   servlet:
     #文件上传限制(byte)
     multipart:
-      max-file-size: 10485760
-      max-request-size: 10485760
+      max-file-size: 52428800
+      max-request-size: 52428800

+ 1 - 1
src/main/resources/mapper_xml/DepotHeadMapper.xml

@@ -769,7 +769,7 @@
       AND dh.delete_flag = '0'
       AND ifnull(dh.status,'0') != '0'
       <if test="number != null and number != ''">
-        AND dh.number = #{number}
+        AND dh.number like CONCAT('%',#{number},'%')
       </if>
       <if test="status != null and status != ''">
         AND dh.status = #{status}

+ 1 - 1
src/main/resources/mapper_xml/DepotHeadMapperEx.xml

@@ -184,7 +184,7 @@
     </select>
 
     <select id="getMaterialCountListByHeaderIdList" resultType="com.jsh.erp.datasource.vo.MaterialCountVo">
-        select header_id, sum(oper_number) materialCount from jsh_depot_item
+        select header_id, IF(ifnull(actual_quantity_in_storage,0) > 0,sum(actual_quantity_in_storage),sum(oper_number)) materialCount from jsh_depot_item
         where 1=1
         <if test="idList.size()>0">
             and header_id in

+ 24 - 0
src/main/resources/mapper_xml/DepotItemMapper.xml

@@ -246,6 +246,18 @@
       <if test="createTime != null">
         create_time,
       </if>
+      <if test="productionDate != null">
+        production_date,
+      </if>
+      <if test="expiryNum != null">
+        expiry_num,
+      </if>
+      <if test="position != null">
+        position,
+      </if>
+      <if test="wholesaleDecimal != null">
+        wholesale_decimal,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -341,6 +353,18 @@
       <if test="createTime != null">
         #{createTime,jdbcType=DATE},
       </if>
+      <if test="productionDate != null">
+        #{productionDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="expiryNum != null">
+        #{expiryNum,jdbcType=INTEGER},
+      </if>
+      <if test="position != null">
+        #{position,jdbcType=VARCHAR},
+      </if>
+      <if test="wholesaleDecimal != null">
+        #{wholesaleDecimal,jdbcType=DECIMAL},
+      </if>
     </trim>
   </insert>
     <select id="countByExample" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultType="java.lang.Long">

+ 6 - 5
src/main/resources/mapper_xml/DepotItemMapperEx.xml

@@ -286,7 +286,6 @@
         and di.material_id =#{mId}
         and ifnull(dh.delete_flag,'0') !='1'
         union all
-        --单独构造记录:调拨入库
         select dh.number from jsh_depot_head dh
         left join jsh_depot_item di on dh.id=di.header_id and ifnull(di.delete_flag,'0') !='1'
         where dh.type='出库' and dh.sub_type='调拨'
@@ -322,7 +321,8 @@
         select di.*,m.name MName,m.model MModel,m.color MColor,m.unit_id,m.standard MStandard,m.weight, m.img_name,
         m.other_field1 MOtherField1,m.other_field2 MOtherField2,m.other_field3 MOtherField3,m.enable_serial_number, m.enable_batch_number,
         m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.purchase_decimal,
-        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName,u.name unit_name
+        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName,u.name unit_name,me.inventory,
+        us.username warehousingUserName
         from jsh_depot_item di
         left join jsh_material m on di.material_id=m.id  and ifnull(m.delete_flag,'0') !='1'
         left join jsh_material_extend me on me.id=di.material_extend_id  and ifnull(me.delete_Flag,'0') !='1'
@@ -330,6 +330,7 @@
         left join jsh_depot dp2 on di.another_depot_id=dp2.id and ifnull(dp2.delete_Flag,'0') !='1'
         left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
         left join jsh_unit u on m.unit_id=u.id and ifnull(u.delete_Flag,'0') !='1'
+        left join jsh_user us on di.warehousing_user=us.id and ifnull(us.delete_Flag,'0') !='1'
         where di.header_id = #{headerId}
         and ifnull(di.delete_flag,'0') !='1'
         order by di.id asc
@@ -339,7 +340,7 @@
         select di.*,m.name MName,m.model MModel,m.color MColor,m.unit_id,m.standard MStandard,m.weight, m.img_name,
         m.other_field1 MOtherField1,m.other_field2 MOtherField2,m.other_field3 MOtherField3,m.enable_serial_number, m.enable_batch_number,
         m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.purchase_decimal,
-        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName
+        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName,me.inventory
         from jsh_depot_item di
         left join jsh_material m on di.material_id=m.id  and ifnull(m.delete_flag,'0') !='1'
         left join jsh_material_extend me on me.id=di.material_extend_id  and ifnull(me.delete_Flag,'0') !='1'
@@ -1112,8 +1113,8 @@
         left JOIN jsh_depot d on me.depot_id = d.id and ifnull(d.delete_Flag,'0') !='1'
         left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
         where 1=1
-        <if test="batchNumbers != null">
-            and me.batch_number in (${batchNumbers})
+        <if test="barCodes != null">
+            and me.bar_code in (${barCodes})
         </if>
         and ifnull(m.delete_flag,'0') !='1'
         order by m.id desc

+ 24 - 0
src/main/resources/mapper_xml/MaterialBatchMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jsh.erp.datasource.mappers.MaterialBatchMapper">
+
+    <select id="getMaterialBatchByMaterialId" resultType="com.jsh.erp.datasource.entities.MaterialBatch">
+        SELECT id,material_id,depot_id,inventory FROM material_batch
+        WHERE material_id = #{mid} AND inventory > 0
+        ORDER BY production_date ASC
+    </select>
+
+    <select id="getInventorySumByDepotAndMid"  resultType="java.math.BigDecimal">
+        select ifnull(sum(inventory),0) inventory from material_batch
+        where material_id = #{mid}
+        <if test="depotList.size()>0">
+            and depot_id in
+            <foreach collection="depotList" item="item" index="index" separator="," open="(" close=")">
+                #{item}
+            </foreach>
+        </if>
+        AND ifnull(delete_Flag,'0') !='1'
+    </select>
+
+
+</mapper>

+ 9 - 0
src/main/resources/mapper_xml/MaterialExtendMapper.xml

@@ -211,6 +211,9 @@
       <if test="position != null">
         position,
       </if>
+      <if test="ratio != null">
+        ratio,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -282,6 +285,9 @@
       <if test="position != null">
         #{position,jdbcType=VARCHAR},
       </if>
+      <if test="ratio != null">
+        #{ratio,jdbcType=INTEGER},
+      </if>
     </trim>
   </insert>
 
@@ -432,6 +438,9 @@
       <if test="position != null">
         position = #{position,jdbcType=VARCHAR},
       </if>
+      <if test="ratio != null">
+        position = #{ratio,jdbcType=INTEGER},
+      </if>
     </set>
     where id = #{id,jdbcType=BIGINT}
   </update>

+ 1 - 1
src/main/resources/mapper_xml/MaterialExtendMapperEx.xml

@@ -7,7 +7,7 @@
 
     <select id="getDetailList" parameterType="com.jsh.erp.datasource.entities.MaterialExtendExample" resultType="com.jsh.erp.datasource.vo.MaterialExtendVo4List">
         select distinct d.id,d.commodity_unit,d.sku,d.commodity_decimal,d.purchase_decimal,d.wholesale_decimal,
-                        d.low_decimal,d.default_flag,d.production_date,d.expiry_num,d.supplier_id,d.bar_code,d.batch_number,d.inventory,d.depot_id,d.position
+                        d.low_decimal,d.default_flag,d.production_date,d.expiry_num,d.supplier_id,d.bar_code,d.batch_number,d.inventory,d.depot_id,d.position,d.ratio
         from jsh_material_extend d
         where d.material_id = #{materialId}
         and ifnull(d.delete_flag,'0') !='1'

+ 10 - 2
src/main/resources/mapper_xml/MaterialInitialStockMapper.xml

@@ -70,9 +70,9 @@
     </where>
   </sql>
   <sql id="Base_Column_List">
-    id, material_id, depot_id, number, low_safe_stock, high_safe_stock, tenant_id, delete_flag
+    id, material_id, depot_id, number, low_safe_stock, high_safe_stock, tenant_id, delete_flag, position
   </sql>
-  <select id="selectByExample" parameterType="com.jsh.erp.datasource.entities.MaterialInitialStockExample" resultMap="BaseResultMap">
+  <select id="selectByExample" parameterType="com.jsh.erp.datasource.entities.MaterialInitialStockExample" resultType="com.jsh.erp.datasource.entities.MaterialInitialStock">
     select
     <if test="distinct">
       distinct
@@ -110,6 +110,7 @@
       #{number,jdbcType=DECIMAL}, #{lowSafeStock,jdbcType=DECIMAL}, #{highSafeStock,jdbcType=DECIMAL}, 
       #{tenantId,jdbcType=BIGINT}, #{deleteFlag,jdbcType=VARCHAR})
   </insert>
+
   <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.MaterialInitialStock">
     insert into jsh_material_initial_stock
     <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -137,6 +138,9 @@
       <if test="deleteFlag != null">
         delete_flag,
       </if>
+      <if test="position != null">
+        position,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -163,8 +167,12 @@
       <if test="deleteFlag != null">
         #{deleteFlag,jdbcType=VARCHAR},
       </if>
+      <if test="position != null">
+        #{position,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
+
   <select id="countByExample" parameterType="com.jsh.erp.datasource.entities.MaterialInitialStockExample" resultType="java.lang.Long">
     select count(*) from jsh_material_initial_stock
     <if test="_parameter != null">

+ 2 - 2
src/main/resources/mapper_xml/MaterialMapperEx.xml

@@ -614,7 +614,7 @@
     </select>
 
     <select id="getListWithStock" resultMap="ResultMapListWithStock">
-        select m.id, m.name, m.standard, m.model, m.color, m.brand, m.position,
+        select m.id, m.name, m.standard, m.model, m.color,
                me.commodity_unit unitName, mc.name categoryName, me.bar_code mBarCode,
         ifnull(me.purchase_decimal,0) purchaseDecimal,
         ifnull(mcs.current_unit_price,0) currentUnitPrice,
@@ -862,7 +862,7 @@
         and me.id is not null
         <if test="keyword != null and keyword !=''">
             <bind name="bindKey" value="'%'+keyword+'%'"/>
-            and (me.batch_number like #{bindKey} or m.name like #{bindKey})
+            and (me.batch_number like #{bindKey} or m.name like #{bindKey} or me.bar_code like #{bindKey})
         </if>
         <if test="position != null and position !=''">
             <bind name="bindPosition" value="'%'+position+'%'"/>

Some files were not shown because too many files changed in this diff