80 Commits 4561631adf ... 9d0db4f9a2

Auteur SHA1 Bericht Datum
  廖泽勇 9d0db4f9a2 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp 1 week geleden
  huang 8e2826d7b4 pda提交订单价格bug修改 1 week geleden
  huang e4931bee9b 盘点任务新增编辑-全盘增加仓库筛选,选择商品显示批次信息bug修改 1 week geleden
  huang d8b82d90a4 盘点-查询修改参数类型错误 1 week geleden
  maliang b79339ca75 fix:修改 1 week geleden
  maliang 5e839a7f55 fix:盘点 1 week geleden
  huang aff058f510 Merge branch 'dev_ml_423' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 1 week geleden
  huang 9b06d7a45e 盘点任务新增-查询批次接口新增仓库条件,盘点核对刷新库存 1 week geleden
  maliang f338eef51e fix:商品信息供应商回显 1 week geleden
  maliang 8b1d410b29 Merge branch 'master' into dev_ml_423 1 week geleden
  maliang 4ac0236606 fix:采购管理、销售管理 1 week geleden
  huang 3652023c1a apk上传地址修改,pda、pc端bug修改 1 week geleden
  huang 0abef30283 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 1 week geleden
  huang d588316f9c 商品编辑bug修改,出库去掉序列号校验 1 week geleden
  yz c73c7f5240 Merge remote-tracking branch 'origin/dev_huangjunjie' 1 week geleden
  huang b58f7b97aa pda出库配送地址,选择 1 week geleden
  yz 9d68df762c Merge remote-tracking branch 'origin/master' 1 week geleden
  maliang 5dc34ca9fe fix:bug 1 week geleden
  yz 9d0d9a9ccf Merge remote-tracking branch 'origin/dev_huangjunjie' 1 week geleden
  huang 168b70254a pda参数调整,中台bug修改 1 week geleden
  maliang d5e12ccb16 fix:修改 1 week geleden
  maliang ccfbfe6e03 fix:bug 1 week geleden
  maliang 434289c1f7 fix:盘点管理 1 week geleden
  maliang 35074df008 Merge branch 'master' into dev_ml_423 1 week geleden
  huang a857af5de7 中台、PDAbug修改 1 week geleden
  maliang 4f568f6188 fix:bug 1 week geleden
  maliang b92ce889a5 fix:二维码插件 2 weken geleden
  huang 1ec43e8f26 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 2 weken geleden
  huang 6b337f2925 修改商品提醒bug,处理商品库存单位换算 2 weken geleden
  yz df07e58cdf Merge remote-tracking branch 'origin/dev_ml_423' 2 weken geleden
  maliang 03ecf033a5 fix:bug 2 weken geleden
  huang 7435670004 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 2 weken geleden
  huang 6dd256174b 商品信息导入表格新增库位信息 2 weken geleden
  huang 3c8cae6327 订单保存并审核添加生成批次信息,修改商品信息导入条码判断问题,盘点是否存在差异条件查询不生效问题 3 weken geleden
  maliang 54bf2df97d fix:bug 3 weken geleden
  yz bcfdf368e1 Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  huang 50eca03c0d 商品导入增加xlsx格式 3 weken geleden
  huang 037ad6b163 Merge branch 'dev_ml_423' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 3 weken geleden
  13660505945 296744993f Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  13660505945 2d340838c8 Merge remote-tracking branch 'origin/dev_ml_423' 3 weken geleden
  maliang ec7c8d3766 fix: 盘点 3 weken geleden
  huang 41c43e6427 商品信息bug修改 3 weken geleden
  huang 7f83d3a39d 盘点问题修改 3 weken geleden
  13660505945 0846e8e16d Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  huang 5ab8c14493 pda出入库明细问题修改 3 weken geleden
  huang 7ea6107648 修改盘点,订单问题 3 weken geleden
  huang 9a291fd666 Merge branch 'dev_ml_423' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 3 weken geleden
  13660505945 0d82a42fca Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  maliang 2735c8b82e fix:盘点模块商品选择 3 weken geleden
  huang 7ec2459a33 盘点模块及pda接口调整 3 weken geleden
  13660505945 01dd5972f0 Merge remote-tracking branch 'origin/dev_ml_423' 3 weken geleden
  13660505945 8e4d10f663 Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  huang 32425ea6f3 盘点全盘批次号获取 3 weken geleden
  maliang dff1d99ce4 fix:商品编辑、新增 3 weken geleden
  maliang 8096b802c9 fix:盘点任务商品选择弹框调整 3 weken geleden
  maliang 7c11bc33ab Merge branch 'master' into dev_ml_423 3 weken geleden
  huang d4d90f79a7 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 3 weken geleden
  huang 69941d4e75 全盘获取批次号修改 3 weken geleden
  huang 5929696dbf 销售订单库存为空修改 3 weken geleden
  maliang 7b2c219008 fix:商品单位 3 weken geleden
  13660505945 e4dccfdbaf Merge remote-tracking branch 'origin/xq' 3 weken geleden
  13660505945 33c24accbf Merge remote-tracking branch 'origin/dev_huangjunjie' 3 weken geleden
  maliang 617f250e70 fix:商品信息 3 weken geleden
  huang c8c2fa7378 新增数据库表格sql语句 3 weken geleden
  huang 8ec2116df6 Merge branch 'master' of http://121.40.253.172:3000/pengyue/jsh_erp into dev_huangjunjie 3 weken geleden
  huang e79c10df96 商品批次号逻辑改为条码逻辑 3 weken geleden
  15102826049 8c9c84c6f0 盘点状态更新 3 weken geleden
  15102826049 f9800acf37 盘点核对编辑状态显示修改 3 weken geleden
  15102826049 a3143a0be9 Merge branch 'dev_ml_423' into xq 3 weken geleden
  maliang 9b584599de feat:4.23需求 3 weken geleden
  maliang ff03d39a36 fix:bug[937] 3 weken geleden
  maliang c1187dfb9f feat:app版本管理 3 weken geleden
  maliang 4594b14eda fix:bug[935] 3 weken geleden
  maliang 7b64139901 fix:bug[905] 4 weken geleden
  maliang 59d184ff11 fix:bug 4 weken geleden
  15102826049 82507ae171 Merge branch 'dev_xq' into xq 4 weken geleden
  15102826049 e0c98d3e81 bug修改提交 4 weken geleden
  15102826049 7ac807331c 供应商信息增加限制输入 4 weken geleden
  15102826049 12ad5140f1 bug修改提交 4 weken geleden
  15102826049 6211698478 bug修改提交 4 weken geleden
100 gewijzigde bestanden met toevoegingen van 3930 en 3687 verwijderingen
  1. 53 2
      docs/new_sql.sql
  2. 1 1
      jshERP-web/package.json
  3. BIN
      jshERP-web/public/doc/goods_template.xls
  4. 1 1
      jshERP-web/src/components/jeecg/JEditableTable.vue
  5. 42 0
      jshERP-web/src/components/jeecgbiz/JSelectList.vue
  6. 2 2
      jshERP-web/src/components/jeecgbiz/modal/JSelectMaterialModal.vue
  7. 524 0
      jshERP-web/src/components/jeecgbiz/modal/JSelectMaterialModal2.vue
  8. 20 6
      jshERP-web/src/mixins/JeecgListMixin.js
  9. 2 0
      jshERP-web/src/mixins/newTableMixin.js
  10. 1 0
      jshERP-web/src/utils/JEditableTableUtil.js
  11. 161 133
      jshERP-web/src/views/bill/dialog/BillDetail.vue
  12. 11 1
      jshERP-web/src/views/bill/dialog/ImportItemModal.vue
  13. 1 1
      jshERP-web/src/views/bill/dialog/WaitBillList.vue
  14. 180 100
      jshERP-web/src/views/bill/mixins/BillModalMixin.js
  15. 1 1
      jshERP-web/src/views/bill/modules/AllocationOutModal.vue
  16. 65 51
      jshERP-web/src/views/bill/modules/OtherInModal.vue
  17. 45 44
      jshERP-web/src/views/bill/modules/OtherOutModal.vue
  18. 1 1
      jshERP-web/src/views/bill/modules/PurchaseApplyModal.vue
  19. 69 56
      jshERP-web/src/views/bill/modules/PurchaseInModal.vue
  20. 59 47
      jshERP-web/src/views/bill/modules/PurchaseOrderModal.vue
  21. 40 40
      jshERP-web/src/views/bill/modules/SaleOrderModal.vue
  22. 54 54
      jshERP-web/src/views/bill/modules/SaleOutModal.vue
  23. 3 2
      jshERP-web/src/views/material/MaterialList.vue
  24. 1 1
      jshERP-web/src/views/material/modules/BatchSetStockModal.vue
  25. 213 594
      jshERP-web/src/views/material/modules/MaterialModal.vue
  26. 5 6
      jshERP-web/src/views/stock/CheckList.vue
  27. 3 3
      jshERP-web/src/views/stock/TaskList.vue
  28. 1 1
      jshERP-web/src/views/stock/components/FilterForm.vue
  29. 80 37
      jshERP-web/src/views/stock/components/checkModal.vue
  30. 19 24
      jshERP-web/src/views/stock/components/editForm.vue
  31. 72 27
      jshERP-web/src/views/stock/components/stockModal.vue
  32. 88 0
      jshERP-web/src/views/system/AppVersionList.vue
  33. 293 0
      jshERP-web/src/views/system/modules/AppVersionModal.vue
  34. 22 5
      jshERP-web/src/views/system/modules/VendorModal.vue
  35. 2 1
      jshERP-web/vue.config.js
  36. 9 1
      src/main/java/com/jsh/erp/constants/ExceptionConstants.java
  37. 2 1
      src/main/java/com/jsh/erp/controller/DepotController.java
  38. 19 14
      src/main/java/com/jsh/erp/controller/DepotItemController.java
  39. 28 100
      src/main/java/com/jsh/erp/controller/MaterialController.java
  40. 1 0
      src/main/java/com/jsh/erp/controller/MaterialExtendController.java
  41. 2 8
      src/main/java/com/jsh/erp/controller/apkVersion/apkVersionController.java
  42. 61 0
      src/main/java/com/jsh/erp/controller/materialBatch/MaterialBatchController.java
  43. 27 15
      src/main/java/com/jsh/erp/controller/pda/PdaController.java
  44. 8 13
      src/main/java/com/jsh/erp/controller/stocktaking/StocktakingController.java
  45. 26 0
      src/main/java/com/jsh/erp/datasource/dto/DepotHeadDto.java
  46. 29 0
      src/main/java/com/jsh/erp/datasource/dto/MaterialDto.java
  47. 1 1
      src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingItemQueryDTO.java
  48. 2 0
      src/main/java/com/jsh/erp/datasource/entities/ApkVersion.java
  49. 4 0
      src/main/java/com/jsh/erp/datasource/entities/DepotEx.java
  50. 21 0
      src/main/java/com/jsh/erp/datasource/entities/DepotItem.java
  51. 2 1
      src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4WithInfoEx.java
  52. 4 0
      src/main/java/com/jsh/erp/datasource/entities/Material.java
  53. 90 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialBatch.java
  54. 3 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialExtend.java
  55. 5 0
      src/main/java/com/jsh/erp/datasource/entities/MaterialInitialStock.java
  56. 8 0
      src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapper.java
  57. 1 1
      src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapperEx.java
  58. 47 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialBatchMapper.java
  59. 0 2
      src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapper.java
  60. 2 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapperEx.java
  61. 10 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialInitialStockMapper.java
  62. 6 1
      src/main/java/com/jsh/erp/datasource/mappers/MaterialMapper.java
  63. 8 3
      src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java
  64. 1 1
      src/main/java/com/jsh/erp/datasource/mappers/TaskStocktakingMapper.java
  65. 3 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDADepotHeadDTO.java
  66. 3 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDADepotMaterialDto.java
  67. 7 1
      src/main/java/com/jsh/erp/datasource/pda/dto/PDAInventoryDTO.java
  68. 3 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDATaskStocktakingDTO.java
  69. 3 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDADepotHeadVO.java
  70. 9 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDADepotItemVO.java
  71. 21 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDAPrintVo.java
  72. 3 0
      src/main/java/com/jsh/erp/datasource/vo/TaskStocktakingVO.java
  73. 8 0
      src/main/java/com/jsh/erp/service/ApkVersionService.java
  74. 12 4
      src/main/java/com/jsh/erp/service/DepotItemService.java
  75. 67 0
      src/main/java/com/jsh/erp/service/MaterialBatchService.java
  76. 6 3
      src/main/java/com/jsh/erp/service/MaterialExtendService.java
  77. 52 8
      src/main/java/com/jsh/erp/service/MaterialService.java
  78. 3 2
      src/main/java/com/jsh/erp/service/TaskStocktakingService.java
  79. 60 0
      src/main/java/com/jsh/erp/service/impl/ApkVersionServiceImpl.java
  80. 38 37
      src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java
  81. 112 75
      src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java
  82. 186 0
      src/main/java/com/jsh/erp/service/impl/MaterialBatchServiceImpl.java
  83. 219 197
      src/main/java/com/jsh/erp/service/impl/MaterialExtendServiceImpl.java
  84. 249 250
      src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java
  85. 39 36
      src/main/java/com/jsh/erp/service/impl/TaskStocktakingServiceImpl.java
  86. 0 1589
      src/main/java/com/jsh/erp/utils/StringHelper.java
  87. 11 3
      src/main/resources/application-dev.yml
  88. 1 0
      src/main/resources/application-pro.yml
  89. 1 0
      src/main/resources/application-test.yml
  90. 5 1
      src/main/resources/mapper_xml/DepotHeadMapper.xml
  91. 36 8
      src/main/resources/mapper_xml/DepotItemMapper.xml
  92. 2 3
      src/main/resources/mapper_xml/DepotItemMapperEx.xml
  93. 101 0
      src/main/resources/mapper_xml/MaterialBatchMapper.xml
  94. 9 4
      src/main/resources/mapper_xml/MaterialExtendMapper.xml
  95. 15 1
      src/main/resources/mapper_xml/MaterialExtendMapperEx.xml
  96. 19 2
      src/main/resources/mapper_xml/MaterialInitialStockMapper.xml
  97. 45 0
      src/main/resources/mapper_xml/MaterialMapper.xml
  98. 12 54
      src/main/resources/mapper_xml/MaterialMapperEx.xml
  99. 4 4
      src/main/resources/mapper_xml/TaskStocktakingItemMapper.xml
  100. 4 1
      src/main/resources/mapper_xml/TaskStocktakingMapper.xml

+ 53 - 2
docs/new_sql.sql

@@ -157,7 +157,7 @@ ALTER TABLE jsh_material_extend
   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';
+  MODIFY inventory DECIMAL(10,0) DEFAULT 0 COMMENT '库存';
 
 -- 初始库存表 修改库存类型
 ALTER TABLE jsh_material_initial_stock
@@ -172,5 +172,56 @@ ALTER TABLE jsh_material_current_stock
 
 -- 单据主表 新增提交时间
 ALTER TABLE jsh_depot_head
-  ADD COLUMN submit_time datetime DEFAULT NULL COMMENT '提交时间';
+  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 1 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/package.json

@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@antv/data-set": "^0.11.2",
+    "@chenfengyuan/vue-qrcode": "1.0.2",
     "@tinymce/tinymce-vue": "^2.0.0",
     "ant-design-vue": "1.5.2",
     "area-data": "^5.0.6",
@@ -36,7 +37,6 @@
     "vue-ls": "^3.2.0",
     "vue-photo-preview": "^1.1.3",
     "vue-print-nb-jeecg": "^1.0.9",
-    "vue-qr": "^4.0.9",
     "vue-router": "^3.0.1",
     "vue-splitpane": "^1.0.4",
     "vuedraggable": "^2.20.0",

BIN
jshERP-web/public/doc/goods_template.xls


+ 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,

+ 2 - 2
jshERP-web/src/components/jeecgbiz/modal/JSelectMaterialModal.vue

@@ -206,14 +206,14 @@ export default {
         { dataIndex: 'batchNumber', title: '批次号' },
         { dataIndex: 'name', title: '名称', scopedSlots: { customRender: 'customName' } },
         { dataIndex: 'categoryName', title: '类别' },
-        { dataIndex: 'standard', title: '规格' },
+        // { dataIndex: 'standard', title: '规格' },
         { dataIndex: 'model', title: '型号' },
         { dataIndex: 'color', title: '颜色' },
         { dataIndex: 'brand', title: '品牌' },
         { dataIndex: 'supplierName', title: '供应商' },
         { dataIndex: 'unit', title: '单位' },
         { dataIndex: 'sku', title: '多属性' },
-        { dataIndex: 'stock', title: '库存' },
+        { dataIndex: 'inventory', title: '库存' },
         { dataIndex: 'productionDate', title: '生产日期' },
         { dataIndex: 'expiryNum', title: '保质期' },
         { dataIndex: 'barCode', title: '商品条码' },

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

@@ -0,0 +1,524 @@
+<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 ? '100%' : '1550px'
+      let screenWidth = document.body.clientWidth
+      if (screenWidth < 500) {
+        this.scrollTrigger = { x: 800 }
+      } else {
+        this.scrollTrigger = {
+          x: 'max-content',
+        }
+      }
+    },
+    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>

+ 20 - 6
jshERP-web/src/mixins/JeecgListMixin.js

@@ -471,6 +471,8 @@ export const JeecgListMixin = {
     },
     //拖拽组件
     handleDrag(column) {
+      const draggingMap = {};
+      const draggingState = Vue.observable(draggingMap);
       return {
         header: {
           cell: (h, props, children) => {
@@ -483,26 +485,38 @@ export const JeecgListMixin = {
             if (!col || !col.width) {
               return h('th', { ...restProps }, [...children])
             }
-
+            let thDom = null;
+            const onDrag = x => {
+              draggingState[key] = 0;
+              col.width = Math.max(x, 1);
+            };
+            const onDragstop = () => {
+              draggingState[key] = thDom.getBoundingClientRect().width;
+              console.log('onDragstop', draggingState[key])
+            };
             const dragProps = {
               key: col.dataIndex || col.key,
               class: 'table-draggable-handle',
               attrs: {
                 w: 10,
-                x: col.width,
+                x: draggingState[key] || col.width,
                 z: 1,
                 axis: 'x',
                 draggable: true,
                 resizable: false,
               },
               on: {
-                dragging: (x, y) => {
-                  col.width = Math.max(x, 1)
-                },
+                dragging: onDrag,
+                dragstop: onDragstop
               },
             }
             const drag = h(VueDraggableResizable, { ...dragProps })
-            return h('th', { ...restProps, class: 'resize-table-th' }, [...children, drag])
+            return h('th', { ...restProps, class: 'resize-table-th',directives: [
+              {
+                name: 'ant-ref',
+                value: r => (thDom = r)
+              }
+            ], }, [...children, drag])
           },
         },
       }

+ 2 - 0
jshERP-web/src/mixins/newTableMixin.js

@@ -77,6 +77,8 @@ export const newTableMixin = {
           return '已完成'
         case 4:
           return '已取消'
+        case 5:
+          return '已更新'
         default:
           return ''
       }

+ 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)

File diff suppressed because it is too large
+ 161 - 133
jshERP-web/src/views/bill/dialog/BillDetail.vue


+ 11 - 1
jshERP-web/src/views/bill/dialog/ImportItemModal.vue

@@ -17,7 +17,7 @@
       <a-form :form="form">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="模板">
           <span
-            ><a :href="tmpUrl" target="_blank"><b>明细Excel模板[下载]</b></a></span
+            ><a :href="tmpUrl" ref="myLink" @click="importTemplate"><b>{{ exportTitle }}</b></a></span
           >
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="文件">
@@ -44,6 +44,12 @@ import Vue from 'vue'
 
 export default {
   name: 'ImportItemModal',
+  props:{
+    exportTitle:{
+      type: String,
+      default: '明细Excel模板[下载]',
+    }
+  },
   components: {},
   data() {
     return {
@@ -123,6 +129,10 @@ export default {
         prefixNo: this.prefixNo,
       }
     },
+    importTemplate() {
+      let link = this.$refs.myLink
+      link.setAttribute('download', this.exportTitle.replace('[下载]','') + '.xls')
+    },
   },
 }
 </script>

+ 1 - 1
jshERP-web/src/views/bill/dialog/WaitBillList.vue

@@ -239,7 +239,7 @@ export default {
       } else {
         if (this.selectedDetailRowKeys.length) {
           this.getSelectBillDetailRows()
-          this.$emit('ok', this.selectBillDetailRows, this.linkNumber, this.remark)
+          this.$emit('ok', this.selectBillDetailRows, this.linkNumber, this.remark, this.organId)
           this.close()
         } else {
           this.$message.warning('抱歉,请选择单据明细!')

+ 180 - 100
jshERP-web/src/views/bill/mixins/BillModalMixin.js

@@ -8,6 +8,8 @@ import {
   getBatchNumberList,
   getCurrentSystemConfig,
   getMaterialByBatchNumber,
+  getMaterialByBarCode,
+  getMaterialBySelect,
   getPersonByNumType,
   getPlatformConfigByKey,
   getUnitInfo,
@@ -80,6 +82,14 @@ export const BillModalMixin = {
     this.width = realScreenWidth < 1500 ? '1200px' : '1550px'
     this.minWidth = realScreenWidth < 1500 ? 1150 : 1500
   },
+  watch:{
+    $route(to, from) {
+      if(this.handleCancel){
+        this.handleCancel()
+      }
+      this.visible = false
+    }
+  },
   mounted() {
     document.getElementById(this.prefixNo).addEventListener('keydown', this.handleOkKey)
     this.getCreatorSpinnerList()
@@ -378,8 +388,6 @@ export const BillModalMixin = {
       this.initRetail(1)
     },
     batchSetDepotModalFormOk(depotId) {
-      console.log('22222222222222222211')
-
       this.getAllTable()
         .then((tables) => {
           return getListData(this.form, tables)
@@ -446,27 +454,40 @@ export const BillModalMixin = {
       setTimeout(function () {
         that.$refs.materialDataTable.resetScrollTop((target.rows.length + 1) * that.$refs.materialDataTable.rowHeight)
       }, 1000)
-      if (this.currentSelectDepotId) {
-        //如果单据选择过仓库,则直接从当前选择的仓库加载
-        target.setValues([{ rowKey: row.id, values: { depotId: this.currentSelectDepotId } }])
-      } else {
-        getAction('/depot/findDepotByCurrentUser').then((res) => {
-          if (res.code === 200) {
-            let arr = res.data
-            if (arr.length === 1) {
-              target.setValues([{ rowKey: row.id, values: { depotId: arr[0].id + '' } }])
-            } else {
-              for (let i = 0; i < arr.length; i++) {
-                if (arr[i].isDefault) {
-                  target.setValues([{ rowKey: row.id, values: { depotId: arr[i].id + '' } }])
-                }
-              }
-            }
-          }
-        })
-      }
+      // if (this.currentSelectDepotId) {
+      //   //如果单据选择过仓库,则直接从当前选择的仓库加载
+      //   target.setValues([{ rowKey: row.id, values: { depotId: this.currentSelectDepotId } }])
+      // } else {
+      //   getAction('/depot/findDepotByCurrentUser').then((res) => {
+      //     if (res.code === 200) {
+      //       let arr = res.data
+      //       if (arr.length === 1) {
+      //         target.setValues([{ rowKey: row.id, values: { depotId: arr[0].id + '' } }])
+      //       } else {
+      //         for (let i = 0; i < arr.length; i++) {
+      //           if (arr[i].isDefault) {
+      //             target.setValues([{ rowKey: row.id, values: { depotId: arr[i].id + '' } }])
+      //           }
+      //         }
+      //       }
+      //     }
+      //   })
+      // }
+    },
+    //根据仓库名、商品条码带出对应的仓位货架、库存数量
+    async setProPosition(barCode, depotId, event){
+      const { row, column, value, target } = event
+      findStockByDepotAndBarCode({ depotId: depotId, barCode: barCode }).then(res => {
+        const {position='',stock} = res.data
+        target.setValues([
+          {
+            rowKey: row.id,
+            values: { position:position,inventory: stock },
+          },
+        ])
+        target.$forceUpdate()
+      })
     },
-
     //单元值改变一个字符就触发一次
     onValueChange(event) {
       let that = this
@@ -475,87 +496,154 @@ export const BillModalMixin = {
       switch (column.key) {
         case 'depotId':
           that.currentSelectDepotId = row.depotId
-          if (row.barCode) {
-            that.getStockByDepotBarCode(row, target)
+          console.log('row========', row)
+          // // 选择商品自动带出barCode、商品ID
+          if(row.depotId&&row.barCode&&type=='select'){
+            // // 根据仓库id自动带出仓位货架(若有)参数:商品id、仓库id
+            this.setProPosition(row.barCode, row.depotId, event)
           }
           break
-        case 'batchNumber':
+        // case 'batchNumber':
+        //   param = {
+        //     batchNumber: value,
+        //     organId: this.form.getFieldValue('organId'),
+        //     mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
+        //     prefixNo: this.prefixNo,
+        //   }
+        //   getMaterialByBatchNumber(param).then((res) => {
+        //     if (res && res.code === 200) {
+        //       let mList = res.data
+
+        //       if (value.indexOf(',') > -1) {
+        //         //多个条码
+        //         this.$refs.materialDataTable.getValues((error, values) => {
+        //           values.pop() //移除最后一行数据
+        //           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()
+        //         })
+        //       } else {
+        //         //单个条码
+        //         let depotIdSelected = row.depotId || ''
+        //         // findStockByDepotAndBarCode({ depotId: depotIdSelected, barCode: row.batchNumber }).then((res) => {
+        //         //   if (res && res.code === 200) {
+        //         //     let mArr = []
+        //         //     let mInfo = mList[0]
+        //         //     if (mInfo.unitId) {
+        //         //       mInfo.unitList = JSON.stringify(mInfo.unitList)
+        //         //     }
+        //         //     this.changeColumnShow(mInfo)
+        //         //     let mInfoEx = this.parseInfoToObj(mInfo)
+        //         //     mInfoEx.stock = res.data.stock
+        //         //     mInfoEx.inventory = mInfo.inventory
+        //         //     let mObj = {
+        //         //       rowKey: row.id,
+        //         //       values: mInfoEx,
+        //         //     }
+        //         //     mArr.push(mObj)
+        //         //     target.setValues(mArr)
+        //         //     target.recalcAllStatisticsColumns()
+        //         //     that.autoChangePrice(target)
+        //         //     target.autoSelectBySpecialKey('operNumber', row.orderNum)
+        //         //     //强制渲染
+        //         //     target.$forceUpdate()
+        //         //   }
+        //         // })
+        //       }
+        //     }
+        //   })
+        //   break
+        case 'barCode':
           param = {
-            batchNumber: value,
+            barCode: value,
             organId: this.form.getFieldValue('organId'),
             mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
             prefixNo: this.prefixNo,
           }
-          getMaterialByBatchNumber(param).then((res) => {
+          getMaterialByBarCode(param).then((res) => {
             if (res && res.code === 200) {
               let mList = res.data
-
-              if (value.indexOf(',') > -1) {
-                //多个条码
-                this.$refs.materialDataTable.getValues((error, values) => {
-                  values.pop() //移除最后一行数据
-                  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
-                    mArr.push(mObj)
+              console.log('mList======',mList)
+              target.getValues(async (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)
                   }
-                  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
+                  this.changeColumnShow(mInfo)
+                  let mObj = this.parseInfoToObj(mInfo)
+                  mObj.depotId = mInfo.depotId
+                  const res = await findStockByDepotAndBarCode({ depotId: mInfo.depotId, barCode: mObj.barCode })
+                  const {position,stock} = res.data
+                  mObj.stock = stock
+                  console.log('stock===',stock)
+                  console.log('position===',position)
+                  mObj.position = position
+                  mObj.inventory = mInfo.inventory
+                  const unitPrice = (mObj.unitPrice||0)- 0
+                  mObj.allPrice = (unitPrice * mObj.operNumber).toFixed(2)
+                  // mObj.taxLastMoney = mInfo.taxLastMoney||0
+                  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 {
-                    target.statisticsColumns.taxLastMoney = taxLastMoneyTotal
-                  }
-                  that.autoChangePrice(target)
-                  //强制渲染
-                  target.$forceUpdate()
-                })
-              } else {
-                //单个条码
-                let depotIdSelected = row.depotId || ''
-                findStockByDepotAndBarCode({ depotId: depotIdSelected, barCode: row.batchNumber }).then((res) => {
-                  if (res && res.code === 200) {
-                    let mArr = []
-                    let mInfo = mList[0]
-                    if (mInfo.unitId) {
-                      mInfo.unitList = JSON.stringify(mInfo.unitList)
-                    }
-                    this.changeColumnShow(mInfo)
-                    let mInfoEx = this.parseInfoToObj(mInfo)
-                    mInfoEx.stock = res.data.stock
-                    let mObj = {
-                      rowKey: row.id,
-                      values: mInfoEx,
-                    }
-                    mArr.push(mObj)
-                    target.setValues(mArr)
-                    target.recalcAllStatisticsColumns()
-                    that.autoChangePrice(target)
-                    target.autoSelectBySpecialKey('operNumber', row.orderNum)
-                    //强制渲染
-                    target.$forceUpdate()
+                    mArr[j].mType = '普通子件'
                   }
-                })
-              }
+                }
+                console.log('mArr--------',mArr)
+                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
@@ -744,6 +832,7 @@ export const BillModalMixin = {
         unitId: mInfo.unitId,
         unitList: mInfo.unitList,
         depotId: mInfo.depotId,
+        inventory: mInfo.inventory,
       }
     },
     //使得型号、颜色、扩展信息、sku等为隐藏
@@ -807,15 +896,6 @@ export const BillModalMixin = {
       target.recalcAllStatisticsColumns()
       this.autoChangePrice(target)
     },
-    //根据仓库和条码查询库存
-    getStockByDepotBarCode(row, target) {
-      findStockByDepotAndBarCode({ depotId: row.depotId, barCode: row.batchNumber }).then((res) => {
-        if (res && res.code === 200) {
-          target.setValues([{ rowKey: row.id, values: { stock: res.data.stock } }])
-          target.recalcAllStatisticsColumns()
-        }
-      })
-    },
     //改变优惠、本次付款、欠款的值
     autoChangePrice(target) {
       let allTaxLastMoney = target.statisticsColumns.taxLastMoney - 0

+ 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',

+ 65 - 51
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: 'standard', 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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: '销售价',
+            key: 'wholesaleDecimal',
+            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: '5%', type: FormTypes.inputNumber },
-          { title: '金额', key: 'allPrice', width: '5%', 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: 'unitPrice', width: '120px', type: FormTypes.inputNumber,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { title: '金额', key: 'allPrice', width: '120px', type: FormTypes.inputNumber, statistics: true },
+          // {
+          //   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: '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
@@ -475,7 +488,7 @@ export default {
       this.$refs.waitBillList.show('入库', '采购,销售退货', '1,3')
       this.$refs.waitBillList.title = '请选择采购入库或销售退货'
     },
-    waitBillListOk(selectBillDetailRows, linkNumber, remark) {
+    waitBillListOk(selectBillDetailRows, linkNumber, remark, organId) {
       this.rowCanEdit = false
       this.materialTable.columns[1].type = FormTypes.normal
       this.changeFormTypes(this.materialTable.columns, 'preNumber', 1)
@@ -498,6 +511,7 @@ export default {
           this.form.setFieldsValue({
             linkNumber: linkNumber,
             remark: remark,
+            organId: organId?String(organId):'',
           })
         })
       }

+ 45 - 44
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: 'standard', 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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: '销售价', 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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.inputNumber },
+          { 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

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

@@ -120,7 +120,7 @@
         </a-row>
       </a-form>
     </a-spin>
-    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk"></import-item-modal>
+    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk" exportTitle="清购单导入模版[下载]"></import-item-modal>
     <history-bill-list ref="historyBillListModalForm"></history-bill-list>
     <workflow-iframe ref="modalWorkflow" @ok="workflowModalFormOk"></workflow-iframe>
     <bill-print-iframe ref="modalPrint"></bill-print-iframe>

+ 69 - 56
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"
@@ -365,7 +365,7 @@
       </a-form>
     </a-spin>
     <many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
-    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk"></import-item-modal>
+    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk" exportTitle="采购入库导入模版[下载]"></import-item-modal>
     <link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
     <vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
     <depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
@@ -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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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: '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: 'wholesaleDecimal',
+            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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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.inputNumber },
+          { 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
@@ -610,7 +623,7 @@ export default {
         }
         this.model.debt = (
           this.model.discountLastMoney +
-          this.model.otherMoney -
+          (this.model.otherMoney||0)-
           this.model.deposit -
           this.model.changeAmount
         ).toFixed(2)

+ 59 - 47
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">
@@ -336,7 +335,7 @@
       </a-form>
     </a-spin>
     <many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
-    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk"></import-item-modal>
+    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk" exportTitle="采购订单导入模版[下载]"></import-item-modal>
     <vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
     <account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
     <link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
@@ -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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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: '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: '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: '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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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

+ 40 - 40
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">
@@ -315,7 +315,7 @@
       </a-form>
     </a-spin>
     <many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
-    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk"></import-item-modal>
+    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk" exportTitle="销售订单导入模版[下载]"></import-item-modal>
     <customer-modal ref="customerModalForm" @ok="customerModalFormOk"></customer-modal>
     <account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
     <history-bill-list ref="historyBillListModalForm"></history-bill-list>
@@ -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: 'standard', 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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,

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

@@ -400,7 +400,7 @@
       </a-form>
     </a-spin>
     <many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
-    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk"></import-item-modal>
+    <import-item-modal ref="importItemModalForm" @ok="importItemModalFormOk" exportTitle="销售出库导入模版[下载]"></import-item-modal>
     <link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
     <customer-modal ref="customerModalForm" @ok="customerModalFormOk"></customer-modal>
     <depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
@@ -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: 'standard', 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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,validateRules: [{ required: true, message: '${title}不能为空' }], },
+          { 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.inputNumber },
+          { 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

+ 3 - 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">
@@ -343,6 +343,7 @@ export default {
         { title: '图片', dataIndex: 'pic', width: 60, scopedSlots: { customRender: 'customPic' } },
         { title: '条码', dataIndex: 'mBarCode', width: 120 },
         { title: '名称', dataIndex: 'name', width: 160, scopedSlots: { customRender: 'customName' } },
+        { title: '系统SKU', dataIndex: 'systemSku', width: 120 },
         { title: '规格', dataIndex: 'standard', width: 120 },
         { title: '型号', dataIndex: 'model', width: 120 },
         { title: '颜色', dataIndex: 'color', width: 70, ellipsis: true },

+ 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
+ 213 - 594
jshERP-web/src/views/material/modules/MaterialModal.vue


+ 5 - 6
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> -->
@@ -89,10 +88,10 @@ export default {
       // 权限按钮集合
       btnEnableList: [1, 1, 1],
       queryParam: {
-        taskStatus: '',
+        taskStatus: undefined,
         number: '',
-        depotId: '',
-        createBy: '',
+        depotId: undefined,
+        createBy: undefined,
       },
       // stockTable: {
       //   loading: false,
@@ -160,7 +159,7 @@ export default {
           this.$set(this.queryParam, i, null)
         }
       }
-      const url = this.url.list + '?pageNum=' + this.ipagination.current + '&pageSize=' + this.ipagination.pageSize
+      const url = this.url.list + '?currentPage=' + this.ipagination.current + '&pageSize=' + this.ipagination.pageSize
       this.loading = true
       const params = { ...this.queryParam }
       postAction(url, params).then((res) => {

+ 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>

+ 80 - 37
jshERP-web/src/views/stock/components/checkModal.vue

@@ -12,15 +12,14 @@
           :total="dataSource.length || 0"
           openType="detail"
           :stockType="stockType"
-          @getForm="getForm"
-          @clear="onClearList"
+          @changeForm="handleChangeForm"
         ></edit-form>
         <a-divider />
         <div>
           <div>
             <a-form :form="queryParam" ref="form">
               <a-row class="form-row" :gutter="24">
-                <a-col :lg="6" :md="12" :sm="24" class="form-col">
+                <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
                   <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="商品类别">
                     <!-- <a-input disabled placeholder="请输入" v-model="queryParam.categoryId" /> -->
                     <a-tree-select
@@ -34,24 +33,24 @@
                     </a-tree-select>
                   </a-form-item>
                 </a-col>
-                <a-col :lg="6" :md="12" :sm="24" class="form-col">
+                <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
                   <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="商品名称">
-                    <a-input placeholder="请输入" v-model="queryParam.name" />
+                    <a-input placeholder="请输入" v-model="queryParam.materialName" />
                   </a-form-item>
                 </a-col>
-                <a-col :lg="6" :md="12" :sm="24" class="form-col">
+                <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
                   <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="批次号">
                     <a-input placeholder="请输入" v-model="queryParam.batchNumber" />
                   </a-form-item>
                 </a-col>
-                <a-col :lg="6" :md="12" :sm="24" class="form-col">
+                <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
                   <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="仓位货架">
                     <a-input placeholder="请输入" v-model="queryParam.position" />
                   </a-form-item>
                 </a-col>
-                <a-col :lg="6" :md="12" :sm="24" class="form-col">
+                <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
                   <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="是否存在数量差异">
-                    <a-select placeholder="请选择" v-model="form.isDifference" :options="isDifferenceData"> </a-select>
+                    <a-select placeholder="请选择" v-model="queryParam.isDifference" :options="isDifferenceData"> </a-select>
                   </a-form-item>
                 </a-col>
                 <span>
@@ -68,6 +67,7 @@
             size="middle"
             bordered
             rowKey="id"
+            :scroll="{ x: 'max-content' }"
             :columns="columns"
             :dataSource="dataSource"
             :pagination="ipagination"
@@ -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>
@@ -202,12 +217,16 @@ export default {
       queryParam: { categoryId: '', materialName: '', batchNumber: '', position: '', isDifference: null },
       isDifferenceData: [
         {
+          label: '全部',
+          value: '',
+        },
+        {
           label: '是',
-          value: '1',
+          value: '2',
         },
         {
           label: '否',
-          value: '2',
+          value: '1',
         },
       ],
       categoryTree: [],
@@ -221,6 +240,12 @@ export default {
       },
       editForm: {},
       editVisible: false,
+      editFormRules: {
+        newInventory: [
+          { required: true, message: '请输入实际库存' },
+          { pattern: /^[0-9]*$/, message: '只能输入数字' },
+        ],
+      },
     }
   },
   watch: {
@@ -249,23 +274,29 @@ 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
     },
   },
   methods: {
     handleEdit(data) {
+      console.log('handleEdit=====',data)
       this.editForm = { ...data }
       this.editVisible = true
+      this.handleChangeNewInventory(data.inventory)
     },
     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() {
@@ -336,8 +367,9 @@ export default {
           positionRange,
           creator,
           id,
-          operBy,
+          operByName:operBy,
           operTime,
+          number
         } = res.data
         form.setFieldsValue({
           depotId,
@@ -352,6 +384,7 @@ export default {
           id,
           operBy,
           operTime,
+          number
         })
         this.getList(id)
       })
@@ -361,7 +394,7 @@ export default {
       const form = this.$refs['editForm'].form
 
       const params = { ...this.queryParam, taskStocktakingId: id || this.taskId }
-      const url = url2 + '?pageNum=' + this.ipagination.current + '&pageSize=' + this.ipagination.pageSize
+      const url = url2 + '?currentPage=' + this.ipagination.current + '&pageSize=' + this.ipagination.pageSize
       postAction(url, params).then((res) => {
         this.dataSource = res.data
         this.ipagination.total = this.dataSource.length
@@ -418,15 +451,25 @@ export default {
       this.dataSource = this.dataSource.filter((item) => item.batchNumber !== record.batchNumber)
     },
 
-    onClearList(val) {
+    handleChangeForm(val) {
       this.dataSource = []
       this.getForm(val)
       if (val.taskType === 1) {
         this.findAllSelect()
       }
     },
+
+    handleChangeNewInventory(val) {
+      console.log('1111111======',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>

+ 19 - 24
jshERP-web/src/views/stock/components/editForm.vue

@@ -1,16 +1,16 @@
 <template>
   <a-form :form="form" ref="form">
     <a-row class="form-row" :gutter="24">
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点单号">
           <a-input disabled placeholder="请输入" v-decorator="['number']" />
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点类型">
           <a-select
             placeholder="请选择"
-            @change="handleTaskType"
+            @change="emitForm"
             v-decorator="['taskType', rules.taskType]"
             :options="taskTypeList"
             :disabled="isDisabled"
@@ -18,66 +18,66 @@
           </a-select>
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" required prop="taskName" label="盘点任务名称">
           <a-input placeholder="请输入" :disabled="isDisabled" v-decorator="['taskName', rules.taskName]" />
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="depotId" label="盘点仓库">
           <a-select
             placeholder="请选择"
             v-decorator="['depotId', rules.depotId]"
             :options="depotList"
             :disabled="isDisabled"
-            @change="exportForm"
+            @change="emitForm"
           >
           </a-select>
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点负责人">
           <a-select placeholder="请选择" v-decorator="['creator']" :options="spinnerList" :disabled="isDisabled">
           </a-select>
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="创建人">
           <a-input placeholder="请输入" v-decorator="['createByName']" disabled />
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="创建时间">
           <a-input placeholder="请输入" disabled v-decorator="['createTime']" />
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点库位范围">
           <a-input placeholder="请输入" v-decorator="['positionRange']" disabled />
         </a-form-item>
       </a-col>
-      <a-col :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="商品数量">
           <a-input disabled placeholder="请输入" v-decorator="['materialCount']" />
         </a-form-item>
       </a-col>
-      <a-col v-if="stockType === 'check'" :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col v-if="stockType === 'check'" :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点人">
           <a-input placeholder="请输入" disabled v-decorator.trim="['operBy']" />
         </a-form-item>
       </a-col>
-      <a-col v-if="stockType === 'check'" :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col v-if="stockType === 'check'" :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="完成时间">
           <a-input placeholder="请输入" disabled v-decorator.trim="['operTime']" />
         </a-form-item>
       </a-col>
-      <a-col v-show="false" :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col v-show="true" :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点状态">
           <a-select placeholder="请选择" v-decorator="['taskStatus']" :options="taskStatusList" :disabled="isDisabled">
           </a-select>
         </a-form-item>
       </a-col>
-      <a-col v-show="false" :lg="6" :md="12" :sm="24" class="form-col">
+      <a-col v-show="false" :xl="6" :lg="8" :md="12" :sm="24" class="form-col">
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="盘点状态">
           <a-input v-decorator="['id']"></a-input>
         </a-form-item>
@@ -166,7 +166,7 @@ export default {
       handler(val) {
         if (!val) {
           this.form.resetFields()
-          this.exportForm()
+          this.emitForm()
         }
         if (this.openType === 'add') {
           this.model.taskStatus = 1
@@ -186,16 +186,11 @@ export default {
     },
   },
   methods: {
-    exportForm() {
+    emitForm(val){
       this.$nextTick(() => {
-        this.$emit('getForm', this.form.getFieldsValue())
+        this.$emit('changeForm', this.form.getFieldsValue())
       })
-    },
-    handleTaskType() {
-      this.$nextTick(() => {
-        this.$emit('clear', this.form.getFieldsValue())
-      })
-    },
+    }
   },
 }
 </script>

+ 72 - 27
jshERP-web/src/views/stock/components/stockModal.vue

@@ -9,11 +9,10 @@
           :rules="rules"
           :stockVisible="stockVisible"
           ref="editForm"
-          :total="dataSource.length || 0"
+          :total="ipagination.total"
           :openType="openType"
           :stockType="stockType"
-          @getForm="getForm"
-          @clear="onClearList"
+          @changeForm="handleChangeForm"
         ></edit-form>
         <div>
           <a-button v-if="form.taskType === 2" style="margin-bottom: 6px" type="primary" @click="onChangeGoods"
@@ -25,17 +24,17 @@
             size="middle"
             bordered
             rowKey="id"
+            :scroll="{ x: 'max-content'}"
             :columns="columns"
             :dataSource="dataSource"
             :loading="loading"
-            :scroll="{ y: 500 }"
-            :pagination="false"
+            :pagination="ipagination"
             @change="handleTableChange"
           >
             <span v-if="isShowBtn" slot="action" slot-scope="text, record">
               <!-- <a-divider type="vertical" /> -->
               <a-popconfirm @confirm="handleDelete(record)" title="确定删除吗?">
-                <a>删除</a>
+                <a v-if="form.taskType!=1">删除</a>
               </a-popconfirm>
             </span>
             <template slot="inventory" slot-scope="value, record">
@@ -67,7 +66,7 @@
 <script>
 import editForm from './editForm.vue'
 import table from '../utils/table'
-import JSelectMaterialModal from '../../../components/jeecgbiz/modal/JSelectMaterialModal.vue'
+import JSelectMaterialModal from '../../../components/jeecgbiz/modal/JSelectMaterialModal2.vue'
 import { getAction, postAction } from '@/api/manage'
 import { getMaterialByBatchNumber } from '@/api/api'
 import { newTableMixin } from '@/mixins/newTableMixin'
@@ -126,6 +125,7 @@ export default {
       form: {},
       isShow: false,
       stockType: 'task',
+      batchNumberStr: ''
     }
   },
   watch: {
@@ -167,14 +167,22 @@ 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)
+            }
           })
         }
       })
     },
     onChangeGoods() {
-      this.$refs.selectModal.queryParam.depotId = this.form.depotId
+      if(!this.form.depotId){
+        this.$message.warning('请选择仓库!')
+        return
+      }
+      // this.$refs.selectModal.queryParam.depotId = this.form.depotId
       this.$refs.selectModal.showModal()
     },
     getList(id) {
@@ -194,6 +202,7 @@ export default {
           positionRange,
           creator,
           id,
+          number
         } = res.data
         form.setFieldsValue({
           depotId,
@@ -206,6 +215,7 @@ export default {
           positionRange,
           creator,
           id,
+          number
         })
 
         postAction(url2, { taskStocktakingId: id }).then((res) => {
@@ -217,6 +227,8 @@ export default {
             materialExtendIdList,
           })
           this.getForm(form.getFieldsValue())
+          console.log('this.dataSource',this.dataSource)
+          console.log('this.columns',this.columns)
         })
       })
     },
@@ -225,28 +237,50 @@ export default {
         .split(',')
         .filter((item) => item)
         .join(',')
-      this.getBatchData(str)
+      if(!this.form.depotId){
+        this.$message.warning('请选择仓库!')
+        return
+      }
+      getAction('/materialBatch/findBatchNumbersByBarCode',{
+        barCodes: str,
+        depotId:this.form.depotId
+      }).then((res) => {
+        const batchStr = res.data.split(',')
+        .filter((item) => item)
+        .join(',')
+        this.batchNumberStr = batchStr
+        this.getBatchData()
+      })
     },
     findAllSelect() {
-      const params = { ...this.$refs.selectModal.queryParam }
-      getAction('/material/findBatchNumbersBySelect', params).then((res) => {
+      if(!this.form.depotId){
+        this.$message.warning('请选择仓库!')
+        return
+      }
+      getAction('/materialBatch/findBatchNumbersByBarCode',{
+        depotId:this.form.depotId
+      }).then((res) => {
         this.$refs.selectModal.close()
-        this.getBatchData(res.data)
-      })
-    },
-    getBatchData(val) {
-      const batchStr = val
-        .split(',')
+        const batchStr = res.data.split(',')
         .filter((item) => item)
         .join(',')
+        this.batchNumberStr = batchStr
+        this.getBatchData()
+      })
+    },
+    getBatchData() {
       const params = {
-        batchNumber: batchStr,
-        organId: '',
-        mpList: '',
-        prefixNo: '',
+        batchNumber: this.batchNumberStr,
+        // organId: '',
+        // mpList: '',
+        // prefixNo: '',
       }
-      getMaterialByBatchNumber(params).then((res) => {
-        this.dataSource.push(...res.data)
+      getAction(`/material/getMaterialByBatchNumber?currentPage=${this.ipagination.current}&pageSize=${this.ipagination.pageSize}`, params).then((res) => {
+        this.dataSource = res.data.rows
+        if(this.dataSource.length===0){
+          this.$message.warning('暂无数据!')
+        }
+        this.ipagination.total = Number(res.data.total)
         this.dataSource = this.dataSource.reduce((acc, cur) => {
           const hasDuplicate = acc.some((item) => item.batchNumber === cur.batchNumber)
           if (!hasDuplicate) {
@@ -265,8 +299,10 @@ export default {
       this.dataSource = this.dataSource.filter((item) => item.batchNumber !== record.batchNumber)
     },
 
-    onClearList(val) {
+    handleChangeForm(val) {
       this.dataSource = []
+      this.ipagination.current = 1
+      this.ipagination.total = 0
       this.getForm(val)
       if (val.taskType === 1) {
         this.findAllSelect()
@@ -276,7 +312,16 @@ export default {
     handleDrag() {},
     // ipagination() {},
 
-    handleTableChange() {},
+    handleTableChange(pagination) {
+      if (pagination && pagination.current) {
+        this.ipagination = pagination
+      }
+      if(this.openType=='add'){
+        this.getBatchData()
+      }else{
+        this.getList(this.taskId)
+      }
+    },
   },
 }
 </script>

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

@@ -0,0 +1,88 @@
+<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
+      const url = this.url.list + '?currentPage=' + this.ipagination.current + '&pageSize=' + this.ipagination.pageSize
+      postAction(url, {}).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]: '',

+ 9 - 1
src/main/java/com/jsh/erp/constants/ExceptionConstants.java

@@ -211,6 +211,9 @@ public class ExceptionConstants {
     //修改商品扩展信息失败
     public static final int MATERIAL_PROPERTY_EDIT_FAILED_CODE = 6000002;
     public static final String MATERIAL_PROPERTY_EDIT_FAILED_MSG = "修改商品扩展信息失败";
+    //修改商品扩展信息失败
+    public static final int MATERIAL_PROPERTY_BARCODE_EXIST_CODE = 6000003;
+    public static final String MATERIAL_PROPERTY_BARCODE_EXIST_MSG = "商品条码:%s 已存在";
     /**
      *  账户信息
      * type = 65
@@ -349,7 +352,7 @@ public class ExceptionConstants {
     public static final String MATERIAL_BARCODE_IS_NOT_EXIST_MSG = "商品条码%s不存在,请重新选择";
     //基本条码为空
     public static final int MATERIAL_BARCODE_EMPTY_CODE = 8000027;
-    public static final String MATERIAL_BARCODE_EMPTY_MSG = "第%s行基本条码为空";
+    public static final String MATERIAL_BARCODE_EMPTY_MSG = "第%s行商品条码为空";
     //EXCEL中有副条码在系统中已存在(除自身商品之外)
     public static final int MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_CODE = 80000028;
     public static final String MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_MSG = "抱歉,EXCEL中有副条码在系统中已存在,具体副条码为:%s";
@@ -373,6 +376,11 @@ public class ExceptionConstants {
     public static final int MATERIAL_ERP_SKU_NOT_DECIMAL_CODE = 8000032;
     public static final String MATERIAL_ERP_SKU_NOT_DECIMAL_MSG = "商品erp_sku[%s]不存在";
 
+    //EXCEL中有条码在系统中已存在(除自身商品之外)
+    public static final int MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_CODE = 80000033;
+    public static final String MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_MSG = "抱歉,EXCEL中有条码在系统中已存在,具体条码为:%s";
+    //基本单位为空
+
     /**
      *  单据信息
      * type = 85

+ 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);

+ 19 - 14
src/main/java/com/jsh/erp/controller/DepotItemController.java

@@ -149,7 +149,8 @@ public class DepotItemController {
         Map<String, Object> map = new HashMap<String, Object>();
         try {
             BigDecimal stock = BigDecimal.ZERO;
-            List<MaterialVo4Unit> list = materialService.getMaterialByBatchNumber(barCode);
+            String position = "";
+            List<MaterialVo4Unit> list = materialService.getMaterialByBarCode(barCode);
             if(list!=null && list.size()>0) {
                 MaterialVo4Unit materialVo4Unit = list.get(0);
                 if(StringUtil.isNotEmpty(materialVo4Unit.getSku())){
@@ -161,9 +162,11 @@ public class DepotItemController {
                         String commodityUnit = materialVo4Unit.getCommodityUnit();
                         stock = unitService.parseStockByUnit(stock, unit, commodityUnit);
                     }
+                    position = materialService.getPositionByDidAndMid(depotId,materialVo4Unit.getId());
                 }
             }
             map.put("stock", stock);
+            map.put("position", position);
             res.code = 200;
             res.data = map;
         } catch (Exception e) {
@@ -273,11 +276,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()));
@@ -288,6 +292,7 @@ public class DepotItemController {
                     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());
@@ -1001,7 +1006,7 @@ public class DepotItemController {
         Map<String, Object> data = new HashMap<>();
         String message = "";
         try {
-            String batchNumbers = "";
+            String barCodes = "";
             //文件合法性校验
             Sheet src = null;
             try {
@@ -1021,14 +1026,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);
@@ -1037,7 +1042,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);
@@ -1045,25 +1050,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 {

+ 28 - 100
src/main/java/com/jsh/erp/controller/MaterialController.java

@@ -2,12 +2,12 @@ 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.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import io.swagger.annotations.Api;
@@ -22,10 +22,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;
@@ -60,6 +57,9 @@ public class MaterialController extends BaseController {
     @Resource
     private UserService userService;
 
+    @Resource
+    private MaterialBatchService materialBatchService;
+
     @Value(value="${file.uploadType}")
     private Long fileUploadType;
 
@@ -104,7 +104,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 +112,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);
@@ -324,6 +324,7 @@ public class MaterialController extends BaseController {
                     item.put("mid", material.getId()); //商品扩展表的id
                     String ratioStr = ""; //比例
                     Unit unit = new Unit();
+                    BigDecimal ratio = new BigDecimal("1");
                     if (material.getUnitId() == null) {
                         ratioStr = "";
                     } else {
@@ -332,15 +333,19 @@ public class MaterialController extends BaseController {
                         String commodityUnit = material.getCommodityUnit();
                         if(commodityUnit.equals(unit.getBasicUnit())) {
                             ratioStr = "[基本]";
+                            ratio = new BigDecimal("1");
                         }
                         if(commodityUnit.equals(unit.getOtherUnit()) && unit.getRatio()!=null) {
                             ratioStr = "[" + unit.getRatio().stripTrailingZeros().toPlainString() + unit.getBasicUnit() + "]";
+                            ratio = unit.getRatio();
                         }
                         if(commodityUnit.equals(unit.getOtherUnitTwo()) && unit.getRatioTwo()!=null) {
                             ratioStr = "[" + unit.getRatioTwo().stripTrailingZeros().toPlainString() + unit.getBasicUnit() + "]";
+                            ratio = unit.getRatioTwo();
                         }
                         if(commodityUnit.equals(unit.getOtherUnitThree()) && unit.getRatioThree()!=null) {
                             ratioStr = "[" + unit.getRatioThree().stripTrailingZeros().toPlainString() + unit.getBasicUnit() + "]";
+                            ratio = unit.getRatioThree();
                         }
                     }
                     item.put("barCode", material.getBarCode());
@@ -365,7 +370,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()).divide(ratio,2,BigDecimal.ROUND_HALF_UP));
                     BigDecimal stock;
                     if(StringUtil.isNotEmpty(material.getSku())){
                         stock = depotItemService.getSkuStockByParam(depotId,material.getMeId(),null,null);
@@ -591,10 +596,10 @@ public class MaterialController extends BaseController {
             String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
             String[] mpArr = mpList.split(",");
             //支持序列号查询,先根据序列号查询条码,如果查不到就直接查条码
-            MaterialExtend materialExtend = materialService.getMaterialExtendBySerialNumber(barCode);
-            if(materialExtend!=null && StringUtil.isNotEmpty(materialExtend.getBarCode())) {
-                barCode = materialExtend.getBarCode();
-            }
+//            MaterialExtend materialExtend = materialService.getMaterialExtendBySerialNumber(barCode);
+//            if(materialExtend!=null && StringUtil.isNotEmpty(materialExtend.getBarCode())) {
+//                barCode = materialExtend.getBarCode();
+//            }
             List<MaterialVo4Unit> list = materialService.getMaterialByBarCode(barCode);
             if(list!=null && list.size()>0) {
                 for(MaterialVo4Unit mvo: list) {
@@ -644,6 +649,7 @@ public class MaterialController extends BaseController {
                         mvo.setDepotId(depotId);
                         getStockByMaterialInfo(mvo);
                     }
+                    mvo.setInventory(mvo.getStock());
                 }
             }
             res.code = 200;
@@ -826,88 +832,14 @@ public class MaterialController extends BaseController {
         return res;
     }
 
-    /**
-     * 根据批次号查询商品信息
-     * @return
-     * @throws Exception
-     */
+
     @GetMapping(value = "/getMaterialByBatchNumber")
     @ApiOperation(value = "根据批次号查询商品信息")
-    public BaseResponseInfo getMaterialByBatchNumber(@RequestParam("batchNumber") String batchNumber,
-                                                     @RequestParam(value = "organId", required = false) Long organId,
-                                                     @RequestParam(value = "depotId", required = false) Long depotId,
-                                                     @RequestParam("mpList") String mpList,
-                                                     @RequestParam(required = false, value = "prefixNo") String prefixNo,
-                                                     HttpServletRequest request) throws Exception {
-        BaseResponseInfo res = new BaseResponseInfo();
-        try {
-            Long userId = userService.getUserId(request);
-            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
-            String[] mpArr = mpList.split(",");
-            //支持序列号查询,先根据序列号查询条码,如果查不到就直接查条码
-//            MaterialExtend materialExtend = materialService.getMaterialExtendBySerialNumber(barCode);
-//            if(materialExtend!=null && StringUtil.isNotEmpty(materialExtend.getBarCode())) {
-//                barCode = materialExtend.getBarCode();
-//            }
-            List<MaterialVo4Unit> list = materialService.getMaterialByBatchNumber(batchNumber);
-            if(list!=null && list.size()>0) {
-                for(MaterialVo4Unit mvo: list) {
-                    mvo.setMaterialOther(materialService.getMaterialOtherByParam(mpArr, mvo));
-                    if ("LSCK".equals(prefixNo) || "LSTH".equals(prefixNo)) {
-                        //零售价
-                        mvo.setBillPrice(mvo.getCommodityDecimal());
-                    } else if ("CGDD".equals(prefixNo) || "CGRK".equals(prefixNo) || "CGTH".equals(prefixNo)) {
-                        //采购价
-                        mvo.setBillPrice(mvo.getPurchaseDecimal());
-                    } else if("QTRK".equals(prefixNo) || "DBCK".equals(prefixNo) || "ZZD".equals(prefixNo) || "CXD".equals(prefixNo)
-                            || "PDLR".equals(prefixNo) || "PDFP".equals(prefixNo)) {
-                        //采购价-给录入界面按权限屏蔽
-                        mvo.setBillPrice(roleService.parseBillPriceByLimit(mvo.getPurchaseDecimal(), "buy", priceLimit, request));
-                    } if ("XSDD".equals(prefixNo) || "XSCK".equals(prefixNo) || "XSTH".equals(prefixNo) || "QTCK".equals(prefixNo)) {
-                        //销售价
-                        if(organId == null) {
-                            mvo.setBillPrice(mvo.getWholesaleDecimal());
-                        } else {
-                            //查询最后一单的销售价,实现不同的客户不同的销售价
-                            BigDecimal lastUnitPrice = depotItemService.getLastUnitPriceByParam(organId, mvo.getMeId(), prefixNo);
-                            mvo.setBillPrice(lastUnitPrice!=null? lastUnitPrice : mvo.getWholesaleDecimal());
-                        }
-                        //销售价-给录入界面按权限屏蔽价格
-                        if("QTCK".equals(prefixNo)) {
-                            mvo.setBillPrice(roleService.parseBillPriceByLimit(mvo.getWholesaleDecimal(), "sale", priceLimit, request));
-                        }
-                    }
-                    //仓库id
-//                    if (depotId == null) {
-//                        JSONArray depotArr = depotService.findDepotByCurrentUser();
-//                        for (Object obj : depotArr) {
-//                            JSONObject depotObj = JSONObject.parseObject(obj.toString());
-//                            if (depotObj.get("isDefault") != null) {
-//                                Boolean isDefault = depotObj.getBoolean("isDefault");
-//                                if (isDefault) {
-//                                    Long id = depotObj.getLong("id");
-//                                    if (!"CGDD".equals(prefixNo) && !"XSDD".equals(prefixNo)) {
-//                                        //除订单之外的单据才有仓库
-//                                        mvo.setDepotId(id);
-//                                    }
-//                                    getStockByMaterialInfo(mvo);
-//                                }
-//                            }
-//                        }
-//                    } else {
-//                        mvo.setDepotId(depotId);
-//                        getStockByMaterialInfo(mvo);
-//                    }
-                }
-            }
-            res.code = 200;
-            res.data = list;
-        } catch(Exception e){
-            logger.error(e.getMessage(), e);
-            res.code = 500;
-            res.data = "获取数据失败";
-        }
-        return res;
+    public TableDataInfo getMaterialByBatchNumber(@RequestParam("batchNumber") String batchNumber){
+        String[] batchNumbers = batchNumber.split(",");
+        startPage();
+        List<TaskStocktakingItemVO> list = materialBatchService.getMaterialByBatchNumber(batchNumbers);
+        return getDataTable(list);
     }
 
     @GetMapping(value = "/getMaterialById")
@@ -929,15 +861,11 @@ public class MaterialController extends BaseController {
         return res;
     }
 
-    /**
-     * 商品信息全选获取批次号
-     */
     @GetMapping(value = "/findBatchNumbersBySelect")
     @ApiOperation(value = "商品选择全选获取商品批次号")
     public BaseResponseInfo findBatchNumberSBySelect(@RequestParam(value = "categoryId", required = false) Long categoryId,
                                            @RequestParam(value = "q", required = false) String q,
                                            @RequestParam(value = "standardOrModel", required = false) String standardOrModel,
-                                           @RequestParam(value = "mpList", required = false) String mpList,
                                            @RequestParam(value = "depotId", required = false) Long depotId,
                                            @RequestParam(value = "color", required = false) String color,
                                            @RequestParam(value = "brand", required = false) String brand,
@@ -947,7 +875,7 @@ public class MaterialController extends BaseController {
                                            HttpServletRequest request){
         BaseResponseInfo res = new BaseResponseInfo();
         try {
-            List<MaterialVo4Unit> dataList = materialService.findBySelectWithBarCode(categoryId, q, StringUtil.toNull(standardOrModel),
+            List<MaterialVo4Unit> dataList = materialBatchService.findBySelectWithBarCode(categoryId, q, StringUtil.toNull(standardOrModel),
                     StringUtil.toNull(color), StringUtil.toNull(brand), StringUtil.toNull(mfrs), enableSerialNumber, enableBatchNumber,
                     null, null,depotId);
             StringBuffer str = new StringBuffer();

+ 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);
                 }
             }

+ 2 - 8
src/main/java/com/jsh/erp/controller/apkVersion/apkVersionController.java

@@ -33,12 +33,6 @@ 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(){
@@ -74,10 +68,10 @@ public class apkVersionController extends BaseController {
             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);
+                savePath = apkVersionService.uploadLocal(file, request);
                 if(StringUtil.isNotEmpty(savePath)){
                     res.code = 200;
-                    res.data = filePath + "/" +savePath;
+                    res.data = savePath;
                 }else {
                     res.code = 500;
                     res.data = "上传失败!";

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

@@ -0,0 +1,61 @@
+package com.jsh.erp.controller.materialBatch;
+
+
+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.MaterialBatch;
+import com.jsh.erp.datasource.entities.MaterialVo4Unit;
+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 = "根据商品id获取批次信息")
+    public TableDataInfo getDetailList(@RequestParam("materialId") Long materialId){
+        startPage();
+        List<MaterialBatch> list = materialBatchService.list(new LambdaQueryWrapperX<MaterialBatch>().eq(MaterialBatch::getMaterialId,materialId));
+        return getDataTable(list);
+    }
+
+
+    @GetMapping(value = "/findBatchNumbersByBarCode")
+    @ApiOperation(value = "根据条码查询批次号")
+    public AjaxResult findBatchNumbersByBarCode(@RequestParam(value = "barCodes",required = false) String barCodes,
+                                                @RequestParam(value = "depotId") Long depotId){
+        List<MaterialBatch> dataList = materialBatchService.findBySelectWithBarCode(barCodes,depotId);
+        StringBuffer str = new StringBuffer();
+        if (null != dataList) {
+            for (MaterialBatch material : dataList) {
+                str.append("," + material.getBatchNumber());
+            }
+        }
+        return AjaxResult.success(str.length() > 1 ? str.deleteCharAt(0) : str);
+    }
+
+}

+ 27 - 15
src/main/java/com/jsh/erp/controller/pda/PdaController.java

@@ -15,15 +15,13 @@ import com.jsh.erp.datasource.pda.dto.PDADepotHeadDTO;
 import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
 import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingDTO;
 import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
-import com.jsh.erp.datasource.pda.vo.PDADepotHeadVO;
-import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
-import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
-import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
+import com.jsh.erp.datasource.pda.vo.*;
 import com.jsh.erp.datasource.vo.SpinnerVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.datasource.vo.TreeNode;
 import com.jsh.erp.query.LambdaQueryWrapperX;
 import com.jsh.erp.service.*;
+import com.jsh.erp.utils.StringUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
@@ -81,6 +79,9 @@ public class PdaController extends BaseController {
     @Resource
     private DepotService depotService;
 
+    @Resource
+    private MaterialBatchService materialBatchService;
+
     /**
      * 采购入库
      * @return
@@ -121,7 +122,7 @@ public class PdaController extends BaseController {
 
     @GetMapping("/orderDetail/{id}")
     @ApiOperation("订单明细")
-    public TableDataInfo orderDetail(@PathVariable("id") Long id) {
+    public TableDataInfo orderDetail(@PathVariable("id") Long id) throws Exception {
         startPage();
         List<PDADepotItemVO> list = depotItemService.pdaList(id);
         return getDataTable(list);
@@ -136,7 +137,7 @@ public class PdaController extends BaseController {
 
     @ApiOperation("商品详情")
     @GetMapping("/materialDetail/{id}")
-    public AjaxResult materialDetail(@PathVariable("id") Long id) {
+    public AjaxResult materialDetail(@PathVariable("id") Long id) throws Exception {
         return AjaxResult.success(depotItemService.pdaDetail(id));
     }
 
@@ -157,7 +158,7 @@ public class PdaController extends BaseController {
     @PostMapping("/taskStocktakingList")
     public TableDataInfo taskStocktakingList(@RequestBody PDATaskStocktakingDTO pdaTaskStocktakingDTO) {
         startPage();
-        List<PDATaskStocktakingVO> list = taskStocktakingService.pdaList(pdaTaskStocktakingDTO.getNumber(), pdaTaskStocktakingDTO.getStatus());
+        List<PDATaskStocktakingVO> list = taskStocktakingService.pdaList(pdaTaskStocktakingDTO.getNumber(), pdaTaskStocktakingDTO.getStatus(), pdaTaskStocktakingDTO.getDepotId());
         return getDataTable(list);
     }
 
@@ -179,7 +180,7 @@ public class PdaController extends BaseController {
     /**
      * 获取商品类别树数据
      * @Param:
-     * @return com.alibaba.fastjson.JSONArray
+     * @return
      */
     @ApiOperation(value = "获取商品类别树数据")
     @GetMapping(value = "/getMaterialCategoryTree")
@@ -220,8 +221,8 @@ public class PdaController extends BaseController {
     @PostMapping("/stocktaking")
     public AjaxResult stocktaking(@RequestBody TaskStocktakingItem taskStocktakingItem) throws Exception{
         User currentUser = userService.getCurrentUser();
-        MaterialExtend materialExtend = materialExtendService.getMaterialExtend(taskStocktakingItem.getMaterialItemId());
-        if (materialExtend == null) {
+        MaterialBatch materialBatch = materialBatchService.getById(taskStocktakingItem.getMaterialItemId());
+        if (materialBatch == null) {
             return AjaxResult.error("商品信息不存在");
         }
         UpdateWrapper<TaskStocktakingItem> updateWrapper = new UpdateWrapper<>();
@@ -230,7 +231,7 @@ public class PdaController extends BaseController {
                 .set("oper_time", new Date());
         if (ObjectUtil.isNotEmpty(taskStocktakingItem.getNewInventory())) {
             updateWrapper.set("new_inventory", taskStocktakingItem.getNewInventory());
-            BigDecimal subtract = taskStocktakingItem.getNewInventory().subtract(materialExtend.getInventory());
+            BigDecimal subtract = taskStocktakingItem.getNewInventory().subtract(materialBatch.getInventory());
             updateWrapper.set("difference_count", subtract);
             //差异数量,设置盘点状态为1.未盘,2.盘盈,3.盘亏 4.无差异
             if (subtract.compareTo(BigDecimal.ZERO) > 0) {
@@ -278,7 +279,12 @@ public class PdaController extends BaseController {
 
     @PostMapping("/inventoryInquiry")
     @ApiOperation("存货查询-商品存货查询")
-    public TableDataInfo inventoryInquiry(@RequestBody PDAInventoryDTO pdaInventoryDTO) throws Exception {
+    public TableDataInfo inventoryInquiry(@RequestBody PDAInventoryDTO pdaInventoryDTO){
+        if (StringUtil.isNotEmpty(pdaInventoryDTO.getPosition())){
+            pdaInventoryDTO.setMaterialIds(materialService.selectMaterialIdByPosition(pdaInventoryDTO.getPosition()));
+        }
+        //查询类型id的子类型
+        pdaInventoryDTO.setCategoryIds(materialService.selectCategoryIds(pdaInventoryDTO.getCategoryId()));
         startPage();
         List<PDADepotItemVO> list = materialService.inventoryInquiry(pdaInventoryDTO);
         return getDataTable(list);
@@ -286,8 +292,8 @@ public class PdaController extends BaseController {
 
     @ApiOperation("存货查询-库位树查询")
     @GetMapping("/inventoryPositionTree")
-    public AjaxResult inventoryPositionTree() throws Exception {
-        return AjaxResult.success(materialService.selectPosition());
+    public AjaxResult inventoryPositionTree(@RequestParam("depotId") Long depotId) throws Exception {
+        return AjaxResult.success(materialService.selectPosition(depotId));
     }
 
     @ApiOperation("存货查询-类型树查询")
@@ -340,7 +346,7 @@ public class PdaController extends BaseController {
             }
         }
         HttpHeaders headers = new HttpHeaders();
-        headers.setContentLength(size); // 手动设置Content-Length为13字节
+        headers.setContentLength(size);
         return new ResponseEntity<>(null, headers, HttpStatus.OK);
     }
 
@@ -352,5 +358,11 @@ public class PdaController extends BaseController {
     }
 
 
+    @ApiOperation("查询商品打印信息")
+    @GetMapping("/printMaterial")
+    public AjaxResult printMaterial(@RequestParam("id") Long id) {
+        PDAPrintVo pdaPrintVo = depotItemService.pdaPrintMaterial(id);
+        return AjaxResult.success(pdaPrintVo);
+    }
 
 }

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

@@ -9,17 +9,11 @@ import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
 import com.jsh.erp.datasource.dto.TaskStocktakingItemDTO;
 import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO;
 import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
-import com.jsh.erp.datasource.entities.MaterialExtend;
-import com.jsh.erp.datasource.entities.TaskStocktaking;
-import com.jsh.erp.datasource.entities.TaskStocktakingItem;
-import com.jsh.erp.datasource.entities.User;
+import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.vo.SpinnerVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.query.LambdaQueryWrapperX;
-import com.jsh.erp.service.MaterialExtendService;
-import com.jsh.erp.service.TaskStocktakingItemService;
-import com.jsh.erp.service.TaskStocktakingService;
-import com.jsh.erp.service.UserService;
+import com.jsh.erp.service.*;
 import com.jsh.erp.utils.DateUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -45,7 +39,8 @@ public class StocktakingController extends BaseController {
     private TaskStocktakingItemService taskStocktakingItemService;
 
     @Resource
-    private MaterialExtendService materialExtendService;
+    private MaterialBatchService materialBatchService;
+
 
     @ApiOperation("盘点任务列表")
     @PostMapping("/list")
@@ -181,10 +176,10 @@ public class StocktakingController extends BaseController {
             taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 5).eq("id", id));
             List<TaskStocktakingItem> list = taskStocktakingItemService.list(new LambdaQueryWrapperX<TaskStocktakingItem>().eq(TaskStocktakingItem::getTaskStocktakingId,id));
             for (TaskStocktakingItem taskStocktakingItem : list) {
-                MaterialExtend materialExtend = materialExtendService.getMaterialExtend(taskStocktakingItem.getMaterialItemId());
-                materialExtend.setInventory(taskStocktakingItem.getNewInventory());
-                materialExtend.setPosition(taskStocktakingItem.getNewPosition());
-                materialExtendService.updateInventory("盘点",taskStocktakingItem.getId(),materialExtend);
+                MaterialBatch materialBatch = materialBatchService.getById(taskStocktakingItem.getMaterialItemId());
+                materialBatch.setInventory(taskStocktakingItem.getNewInventory());
+                materialBatch.setPosition(taskStocktakingItem.getNewPosition());
+                materialBatchService.updateInventory("盘点",taskStocktakingItem.getId(),materialBatch);
             }
         }
         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;
+
+
+
+}

+ 1 - 1
src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingItemQueryDTO.java

@@ -15,7 +15,7 @@ public class TaskStocktakingItemQueryDTO {
     private Long categoryId;
 
     @ApiModelProperty("商品名称")
-    private Integer materialName;
+    private String materialName;
 
     @ApiModelProperty("批次号")
     private String batchNumber;

+ 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;
+
 }

+ 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;
+    }
 }

+ 2 - 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;

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

@@ -8,6 +8,7 @@ import lombok.experimental.Accessors;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 产品表实体类(商品信息)
@@ -89,6 +90,9 @@ public class Material {
     @TableField(exist = false)
     private List<MaterialExtend> list;
 
+    @TableField(exist = false)
+    private Map<Long,String> depotMap;
+
 
     public void setName(String name) {
         this.name = name == null ? null : name.trim();

+ 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;
+
+}

+ 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;
     }

+ 8 - 0
src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapper.java

@@ -6,6 +6,7 @@ import com.jsh.erp.datasource.entities.DepotItemExample;
 import java.util.List;
 
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
+import com.jsh.erp.datasource.pda.vo.PDAPrintVo;
 import org.apache.ibatis.annotations.Param;
 
 public interface DepotItemMapper  extends BaseMapperX<DepotItem>{
@@ -31,6 +32,13 @@ public interface DepotItemMapper  extends BaseMapperX<DepotItem>{
      */
     List<PDADepotItemVO> materialDepotDetail(@Param("type")String type, @Param("materialId") Long materialId);
 
+    /**
+     * 根据单据子表id查询商品打印信息
+     * @param id
+     * @return
+     */
+    PDAPrintVo pdaPrintMaterial(@Param("id")Long id) ;
+
     long countByExample(DepotItemExample example);
 
     int deleteByExample(DepotItemExample example);

+ 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,

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

@@ -0,0 +1,47 @@
+package com.jsh.erp.datasource.mappers;
+
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import com.jsh.erp.datasource.entities.MaterialVo4Unit;
+import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
+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(@Param("mid") Long mid,
+                                                     @Param("depotID") Long depotID);
+
+    /**
+     * 根据仓库id和商品id查询商品批次库存
+     * @param depotList 仓库id
+     * @param mid   商品id
+     */
+    BigDecimal getInventorySumByDepotAndMid(@Param("depotList") List<Long> depotList,
+                                            @Param("mid") Long mid);
+
+    List<MaterialVo4Unit> findBySelectWithBarCode(@Param("q") String q,
+                                                  @Param("standardOrModel") String standardOrModel,
+                                                  @Param("color") String color,
+                                                  @Param("brand") String brand,
+                                                  @Param("mfrs") String mfrs,
+                                                  @Param("enableSerialNumber") String enableSerialNumber,
+                                                  @Param("enableBatchNumber") String enableBatchNumber,
+                                                  @Param("offset") Integer offset,
+                                                  @Param("rows") Integer rows,
+                                                  @Param("depotId") Long depotId);
+
+    /**
+     * 根据批次号数据查询盘点商品批次信息
+     * @param batchNumberArray 批次号数组
+     */
+    List<TaskStocktakingItemVO> getMaterialByBatchNumber(@Param("batchNumberArray") String [] batchNumberArray);
+
+}

+ 0 - 2
src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapper.java

@@ -52,6 +52,4 @@ public interface MaterialExtendMapper extends BaseMapperX<MaterialExtend>{
     BigDecimal getInventorySumByDepotAndMid(@Param("depotList") List<Long> depotList,
                                             @Param("mid") long mid);
 
-    List<String> selectPosition();
-
 }

+ 2 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapperEx.java

@@ -41,4 +41,6 @@ public interface MaterialExtendMapperEx {
      * 仓库删除校验
      */
     int getMaterialExtendCountByDepotIds(@Param("depotIds") String[] depotIds);
+
+    List<Long> getIdsByBarcode(@Param("barCodeList") List<String> barCodeList);
 }

+ 10 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialInitialStockMapper.java

@@ -28,4 +28,14 @@ public interface MaterialInitialStockMapper extends BaseMapperX<MaterialInitialS
     int updateByPrimaryKeySelective(MaterialInitialStock record);
 
     int updateByPrimaryKey(MaterialInitialStock record);
+
+    /**
+     * 查询库位信息
+     */
+    List<String> selectPosition(@Param("depotId") Long depotId);
+
+    /**
+     * 根据库位获取商品id
+     */
+    List<Long> selectMaterialIdByPosition(@Param("position") String position);
 }

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

@@ -1,12 +1,15 @@
 package com.jsh.erp.datasource.mappers;
 
-import com.jsh.erp.datasource.entities.DepotItem;
 import com.jsh.erp.datasource.entities.Material;
 import com.jsh.erp.datasource.entities.MaterialExample;
 import java.util.List;
+
+import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
+import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
 import org.apache.ibatis.annotations.Param;
 
 public interface MaterialMapper extends BaseMapperX<Material>{
+
     long countByExample(MaterialExample example);
 
     int deleteByExample(MaterialExample example);
@@ -28,4 +31,6 @@ public interface MaterialMapper extends BaseMapperX<Material>{
     int updateByPrimaryKeySelective(Material record);
 
     int updateByPrimaryKey(Material record);
+
+    List<PDADepotItemVO> inventoryInquiryList(PDAInventoryDTO pdaInventoryDTO);
 }

+ 8 - 3
src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java

@@ -3,8 +3,10 @@ package com.jsh.erp.datasource.mappers;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
+import com.jsh.erp.datasource.pda.vo.PDAPrintVo;
 import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
 import com.jsh.erp.datasource.vo.MaterialVoSearch;
+import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
@@ -162,13 +164,16 @@ public interface MaterialMapperEx {
     MaterialExtend getMaterialExtendBySerialNumber(
             @Param("serialNumber") String serialNumber);
 
-    List<MaterialVo4Unit> getMaterialByBatchNumber(@Param("batchNumberArray") String [] batchNumberArray);
-
     List<MaterialVo4Unit> getMaterialBySystemSku(@Param("systemSkuArray") String [] systemSkuArray);
 
     List<MaterialCurrentStock4SystemSku> getMaterialCurrentPriceByIdList(@Param("idList") List<Long> idList);
 
-    List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO);
+    /**
+     * 根据单据子表id查询打印信息
+     * @param depotItemId 单据子表id
+     * @return
+     */
+    PDAPrintVo pdaPrintMaterial(@Param("depotItemId") Long depotItemId);
 
 
 }

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

@@ -12,5 +12,5 @@ public interface TaskStocktakingMapper extends BaseMapperX<TaskStocktaking> {
 
     List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO);
 
-    List<PDATaskStocktakingVO> pdaList(@Param("number") String number , @Param("taskStatus") Integer taskStatus);
+    List<PDATaskStocktakingVO> pdaList(@Param("number") String number , @Param("taskStatus") Integer taskStatus,@Param("depotId") Long depotId);
 }

+ 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/dto/PDADepotMaterialDto.java

@@ -10,6 +10,9 @@ import java.util.Date;
 @Data
 public class PDADepotMaterialDto {
 
+    @ApiModelProperty("条码")
+    private String barCode;
+
     @ApiModelProperty("批次号")
     private String batchNumber;
 

+ 7 - 1
src/main/java/com/jsh/erp/datasource/pda/dto/PDAInventoryDTO.java

@@ -24,7 +24,13 @@ public class PDAInventoryDTO {
     @ApiModelProperty("关键字")
     private String keyword;
 
-    @ApiModelProperty("商品种类ID数组")
+    @ApiModelProperty("商品种类ID集合")
     private List<Long> categoryIds;
 
+    @ApiModelProperty("商品ID集合")
+    private List<Long> materialIds;
+
+    @ApiModelProperty("仓库id")
+    private Long depotId;
+
 }

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

@@ -21,4 +21,7 @@ public class PDATaskStocktakingDTO {
     @ApiModelProperty("库位")
     private String position;
 
+    @ApiModelProperty("仓库id")
+    private Long depotId;
+
 }

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

@@ -39,4 +39,7 @@ public class PDADepotHeadVO {
     @ApiModelProperty("出入库时间")
     private Date warehousingTime;
 
+    @ApiModelProperty("配送地址")
+    private String receiverAddress;
+
 }

+ 9 - 0
src/main/java/com/jsh/erp/datasource/pda/vo/PDADepotItemVO.java

@@ -15,9 +15,15 @@ public class PDADepotItemVO{
     @ApiModelProperty("商品订单ID")
     private Long id;
 
+    @ApiModelProperty("订单主表ID")
+    private Long headerId;
+
     @ApiModelProperty("商品ID")
     private Long materialId;
 
+    @ApiModelProperty("商品条码ID")
+    private Long materialExtendId;
+
     @ApiModelProperty("商品名称")
     private String materialName;
 
@@ -69,5 +75,8 @@ public class PDADepotItemVO{
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date warehousingTime;
 
+    @ApiModelProperty("仓库id")
+    private Long depotId;
+
 
 }

+ 21 - 0
src/main/java/com/jsh/erp/datasource/pda/vo/PDAPrintVo.java

@@ -0,0 +1,21 @@
+package com.jsh.erp.datasource.pda.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class PDAPrintVo {
+
+    @ApiModelProperty("客户名")
+    private String customerName;
+
+    @ApiModelProperty("单据编号")
+    private String number;
+
+    @ApiModelProperty("商品条码")
+    private String barCode;
+
+    @ApiModelProperty("批次号")
+    private String batchNumber;
+
+}

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

@@ -18,6 +18,9 @@ public class TaskStocktakingVO extends TaskStocktaking {
     @ApiModelProperty("创建人名称")
     private String createByName;
 
+    @ApiModelProperty("盘点人名称")
+    private String operByName;
+
     @ApiModelProperty("仓库名称")
     private String depotName;
 

+ 8 - 0
src/main/java/com/jsh/erp/service/ApkVersionService.java

@@ -2,7 +2,15 @@ package com.jsh.erp.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jsh.erp.datasource.entities.ApkVersion;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
 
 public interface ApkVersionService extends IService<ApkVersion> {
 
+    /**
+     * apk文件上传
+     */
+    String uploadLocal(MultipartFile mf, HttpServletRequest request);
+
 }

+ 12 - 4
src/main/java/com/jsh/erp/service/DepotItemService.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
+import com.jsh.erp.datasource.pda.vo.PDAPrintVo;
 import com.jsh.erp.datasource.vo.DepotHeadXsddRequestVO;
 import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
 import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
@@ -23,14 +24,14 @@ public interface DepotItemService extends IService<DepotItem> {
      * pda根据订单信息查询商品列表
      * @return
      */
-    List<PDADepotItemVO> pdaList(Long id);
+    List<PDADepotItemVO> pdaList(Long id) throws Exception;
 
     /**
      * pda根据商品订单ID查询商品详情
      * @param id 商品订单ID
      * @return
      */
-    PDADepotItemVO pdaDetail(Long id);
+    PDADepotItemVO pdaDetail(Long id) throws Exception;
 
     /**
      * 商品库存详情列表
@@ -39,6 +40,13 @@ public interface DepotItemService extends IService<DepotItem> {
      */
     List<PDADepotItemVO> materialDepotDetail(String type, Long materialId);
 
+    /**
+     * pda 获取商品打印条码信息
+     * @param depotItemId 单据子表id
+     * @return
+     */
+    PDAPrintVo pdaPrintMaterial(Long depotItemId);
+
     DepotItem getDepotItem(long id)throws Exception;
 
     List<DepotItem> getDepotItem()throws Exception;
@@ -179,11 +187,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);
 

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

@@ -0,0 +1,67 @@
+package com.jsh.erp.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jsh.erp.datasource.entities.DepotItem;
+import com.jsh.erp.datasource.entities.MaterialBatch;
+import com.jsh.erp.datasource.entities.MaterialExtend;
+import com.jsh.erp.datasource.entities.MaterialVo4Unit;
+import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
+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 depotItem 单据子表id
+     */
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    void generateMaterialBatchByDepotItemId(DepotItem depotItem, Long supplierId) 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);
+
+    /**
+     * 获取批次号字符
+     */
+    List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color,
+                                                  String brand, String mfrs, String enableSerialNumber, String enableBatchNumber,
+                                                  Integer offset, Integer rows, Long depotId) throws Exception;
+
+    /**
+     * 根据商品条码获取商品批次信息
+     * @param barCodes 商品条码字符集合
+     */
+    List<MaterialBatch> findBySelectWithBarCode(String barCodes,Long depotId);
+
+    /**
+     * 根据批次号数组查询商品批次信息
+     * @param batchNumbers 批次号数组
+     */
+    List<TaskStocktakingItemVO> getMaterialByBatchNumber(String [] batchNumbers);
+
+}

+ 6 - 3
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;
 
     /**
      *  添加商品子信息
@@ -60,7 +62,8 @@ public interface MaterialExtendService extends IService<MaterialExtend> {
     MaterialExtend getInfoByBatchNumber(String batchNumber)throws Exception;
 
     /**
-     * 修改子商品库存
+     * 根据商品条码集合查询商品id
+     * @param barCodeList 商品条码
      */
-    void updateInventory(String type, Long id,MaterialExtend materialExtend) throws Exception;
+    List<Long> selectIdsByBarCode(List<String> barCodeList);
 }

+ 52 - 8
src/main/java/com/jsh/erp/service/MaterialService.java

@@ -4,12 +4,14 @@ 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;
 import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
 import com.jsh.erp.datasource.pda.vo.PDATypeTree;
 import com.jsh.erp.datasource.vo.MaterialWarnListVo;
+import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.utils.BaseResponseInfo;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -27,6 +29,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 +43,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 +108,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 +136,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);
@@ -171,8 +180,6 @@ public interface MaterialService extends IService<Material> {
 
     MaterialExtend getMaterialExtendBySerialNumber(String serialNumber);
 
-    List<MaterialVo4Unit> getMaterialByBatchNumber(String batchNumber);
-
     Material getMaterialById(Long id);
 
     List<MaterialVo4Unit> getMaterialBySystemSku(List<String> systemSkuList);
@@ -197,10 +204,47 @@ public interface MaterialService extends IService<Material> {
      * pdaInventoryDTO
      * @return
      */
-    List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO) throws Exception;
+    List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO);
+
+    /**
+     * 根据库位查询商品id集合
+     * @param position
+     * @return
+     */
+    List<Long> selectMaterialIdByPosition(String position);
+
+    /**
+     * 根据类型id查询子类型集合
+     * @param id 类型id
+     * @return
+     */
+    List<Long> selectCategoryIds(Long id);
 
     /**
      * 查询库位树
      */
-    List<PDATypeTree> selectPosition();
+    List<PDATypeTree> selectPosition(Long depotId);
+
+    /**
+     * 获取仓库id、商品id获取商品库位信息
+     * @param did 仓库id
+     * @param mid 商品id
+     * @return 库位
+     */
+    String getPositionByDidAndMid(Long did, Long mid);
+
+    /**
+     * 根据商品id查询商品库存
+     * @param mid 商品id
+     * @return 商品库存
+     */
+    BigDecimal getMaterialStockByMid(Long mid);
+
+    /**
+     * 根据商品id和仓库id查询商品当前库存
+     * @param mid 商品id
+     * @param did 仓库id
+     * @return 商品库存
+     */
+    BigDecimal getMaterialStockByMidAndDid(Long mid,Long did);
 }

+ 3 - 2
src/main/java/com/jsh/erp/service/TaskStocktakingService.java

@@ -16,7 +16,8 @@ import java.util.List;
 public interface TaskStocktakingService extends IService<TaskStocktaking> {
 
     /**
-     *
+     * PC-盘点任务列表
+     * @param taskStocktakingQueryDTO 筛选参数
      * @return
      */
     List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO);
@@ -54,7 +55,7 @@ public interface TaskStocktakingService extends IService<TaskStocktaking> {
      * @param taskStatus 盘点任务状态
      * @return
      */
-    List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus);
+    List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus, Long depotId);
 
     /**
      * PAD-盘点任务详情

+ 60 - 0
src/main/java/com/jsh/erp/service/impl/ApkVersionServiceImpl.java

@@ -4,9 +4,18 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jsh.erp.datasource.entities.ApkVersion;
 import com.jsh.erp.datasource.mappers.ApkVersionMapper;
 import com.jsh.erp.service.ApkVersionService;
+import com.jsh.erp.utils.FileUtils;
+import com.jsh.erp.utils.Tools;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
 
 
 @Service
@@ -14,4 +23,55 @@ import org.springframework.stereotype.Service;
 @Slf4j
 public class ApkVersionServiceImpl extends ServiceImpl<ApkVersionMapper, ApkVersion> implements ApkVersionService {
 
+    @Value(value="${file.apkPath}")
+    private String apkPath;
+
+    /**
+     * apk文件上传
+     */
+    @Override
+    public String uploadLocal(MultipartFile mf, HttpServletRequest request) {
+        try {
+            String token = request.getHeader("X-Access-Token");
+            Long tenantId = Tools.getTenantIdByToken(token);
+            String ctxPath = apkPath;
+            String fileName = null;
+            File file = new File(ctxPath + File.separator);
+            if (!file.exists()) {
+                file.mkdirs();// 创建文件根目录
+            }
+            String orgName = mf.getOriginalFilename();// 获取文件名
+            orgName = FileUtils.getFileName(orgName);
+            // 校验文件类型
+            String[] allowedExtensions = {".apk"};
+            boolean isValidExtension = false;
+            for (String ext : allowedExtensions) {
+                if (orgName.toLowerCase().endsWith(ext)) {
+                    isValidExtension = true;
+                    break;
+                }
+            }
+            if (!isValidExtension) {
+                throw new IllegalArgumentException("Invalid file type");
+            }
+            if(orgName.contains(".")){
+                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
+            }else{
+                fileName = orgName+ "_" + System.currentTimeMillis();
+            }
+            String savePath = file.getPath() + File.separator + fileName;
+            File savefile = new File(savePath);
+            FileCopyUtils.copy(mf.getBytes(), savefile);
+
+            // 返回路径
+            String dbpath = fileName;
+            if (dbpath.contains("\\")) {
+                dbpath = dbpath.replace("\\", "/");
+            }
+            return apkPath + "/" +dbpath;
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        }
+        return "";
+    }
 }

+ 38 - 37
src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java

@@ -2,19 +2,14 @@ package com.jsh.erp.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jsh.erp.constants.BusinessConstants;
 import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.mappers.DepotHeadMapper;
 import com.jsh.erp.datasource.mappers.DepotHeadMapperEx;
 import com.jsh.erp.datasource.mappers.DepotItemMapperEx;
-import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapper;
-import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapperEx;
 import com.jsh.erp.datasource.pda.dto.PDADepotHeadDTO;
 import com.jsh.erp.datasource.pda.dto.PDADepotMaterialDto;
 import com.jsh.erp.datasource.pda.vo.PDADepotHeadVO;
@@ -24,9 +19,7 @@ import com.jsh.erp.exception.JshException;
 import com.jsh.erp.query.LambdaQueryWrapperX;
 import com.jsh.erp.query.QueryWrapperX;
 import com.jsh.erp.service.*;
-import com.jsh.erp.util.QRCodeGenerator;
 import com.jsh.erp.utils.ExcelUtils;
-import com.jsh.erp.utils.HttpClient;
 import com.jsh.erp.utils.PageUtils;
 import com.jsh.erp.utils.StringUtil;
 import com.jsh.erp.utils.Tools;
@@ -92,13 +85,13 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
     @Resource
     private LogService logService;
     @Resource
-    private QRCodeGenerator qrCodeGenerator;
-    @Resource
     private MaterialService materialService;
     @Resource
     private MaterialExtendService materialExtendService;
     @Resource
     private SyncTescoSystemService syncTescoSystemService;
+    @Resource
+    private MaterialBatchService materialBatchService;
 
     /**
      * PDA查询订单
@@ -703,11 +696,23 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             DepotHeadExample example = new DepotHeadExample();
             example.createCriteria().andIdIn(dhIds);
             result = depotHeadMapper.updateByExampleSelective(depotHead, example);
-            //更新当前库存
             if(systemConfigService.getForceApprovalFlag()) {
                 for(Long dhId: dhIds) {
-                    List<DepotItem> list = depotItemService.getListByHeaderId(dhId);
+                    List<DepotItem> list = depotItemService.list(new LambdaQueryWrapperX<DepotItem>().eq(DepotItem::getHeaderId,dhId));
+                    DepotHead head = depotHeadMapper.selectById(dhId);
                     for (DepotItem depotItem : list) {
+                        if ("1".equals(status)){
+                            //单据审核,处理批次商品信息
+                            if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(head.getType())){
+                                //表单入库,新增批次商品信息
+                                materialBatchService.generateMaterialBatchByDepotItemId(depotItem,head.getOrganId());
+                            }else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(head.getType())){
+                                //表单出库,修改商品库存
+                                //materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
+                                materialBatchService.handleMaterialBatchByDepotItemId(depotItem.getId());
+                            }
+                        }
+                        //更新当前库存
                         depotItemService.updateCurrentStock(depotItem);
                     }
                 }
@@ -1207,10 +1212,6 @@ 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));
-            }
         }
         logService.insertLog("单据",
                 new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(depotHead.getNumber()).toString(),
@@ -1329,9 +1330,9 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         /**入库和出库处理单据子表信息*/
         depotItemService.saveDetials(rows,depotHead.getId(), "update",request);
         //处理实际入库数量价格总额
-        if (depotHead.getSubType().equals("采购") || depotHead.getSubType().equals("销售")){
-            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());
@@ -1988,7 +1989,7 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         Map<String,PDADepotMaterialDto> materialMap = new HashMap<>();
         for (int i = 0; i < list.size(); i++) {
             operNumber = operNumber + list.get(i).getMaterialNumber().intValue();
-            materialMap.put(list.get(i).getBatchNumber(),list.get(i));
+            materialMap.put(list.get(i).getBarCode(),list.get(i));
         }
         depotHead.setGoodsQuantity(operNumber);
         //商品总类
@@ -2006,21 +2007,23 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
         for (DepotItem depotItem : depotItems) {
             //获取子表单商品
             MaterialExtend materialExtend = materialExtendService.getMaterialExtend(depotItem.getMaterialExtendId());
-            //获取子表单批次号
-            String batchNumber = materialExtend.getBatchNumber();
+            //获取商品条码
+            String barCode = materialExtend.getBarCode();
             //修改原先采购订单实际入库数量
-            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);
+            //设置关联子表id
+            depotItem.setLinkId(depotItem.getId());
             depotItem.setId(null);
             //设置实际入库数量
-            depotItem.setActualQuantityInStorage(materialMap.get(batchNumber).getMaterialNumber());
+            depotItem.setOperNumber(materialMap.get(barCode).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();
+                BigDecimal oNumber = depotItem.getOperNumber();
                 //设置基础数量
                 if (StringUtil.isNotEmpty(unitInfo.getName())) {
                     String basicUnit = unitInfo.getBasicUnit(); //基本单位
@@ -2048,26 +2051,24 @@ 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,depotHead.getOrganId());
             }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);
             //更新当前成本价
             depotItemService.updateCurrentUnitPrice(depotItem);
             //修改商品生产日期
-            materialExtendService.update(new UpdateWrapper<MaterialExtend>().set("production_date",materialMap.get(batchNumber).getProductionDate()).eq("id", materialExtend.getId()));
-            //修改订单总额
-            updateTotalPriceById(depotHead);
+            //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").set("oper_id",userInfo.getId()).set("submit_time",new Date()).eq("id", pdaDepotHeadDTO.getId()));
-
         return true;
     }
 
@@ -2086,7 +2087,7 @@ public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead
             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()));
+            this.update(new UpdateWrapper<DepotHead>().set("total_price",totalPrice).set("change_amount",totalPrice).set("discount_last_money",sum).eq("id",depotHead.getId()));
         }
     }
 

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

@@ -10,6 +10,7 @@ import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.mappers.*;
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
+import com.jsh.erp.datasource.pda.vo.PDAPrintVo;
 import com.jsh.erp.datasource.vo.DepotHeadXsddRequestVO;
 import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
 import com.jsh.erp.datasource.vo.DepotItemVo4Stock;
@@ -75,18 +76,36 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
     @Resource
     private LogService logService;
     @Resource
-    private MaterialExtendMapper materialExtendMapper;
+    private MaterialMapperEx materialMapperEx;
 
     @Resource
     private SyncTescoSystemService syncTescoSystemService;
 
+    @Resource
+    private MaterialBatchService materialBatchService;
+
+    @Resource
+    private DepotItemService depotItemService;
+
     /**
      * pda根据订单信息查询商品列表
      * @return
      */
     @Override
-    public List<PDADepotItemVO> pdaList(Long id) {
-        return depotItemMapper.pdaList(id);
+    public List<PDADepotItemVO> pdaList(Long id) throws Exception {
+        List<PDADepotItemVO> list = depotItemMapper.pdaList(id);
+        for (PDADepotItemVO pdaDepotItemVO : list) {
+            Unit unitInfo = materialService.findUnit(pdaDepotItemVO.getMaterialId()); //查询多单位信息
+            pdaDepotItemVO.setActualQuantityInStorage(depotItemService.getFinishNumber(pdaDepotItemVO.getMaterialExtendId(), pdaDepotItemVO.getId(), pdaDepotItemVO.getHeaderId(), unitInfo, pdaDepotItemVO.getMaterialUnit(), "basic").toString());
+            BigDecimal stock;
+            if (unitInfo != null && unitInfo.getId() != null){
+                stock = unitService.parseStockByUnit(materialService.getCurrentStockByMaterialIdAndDepotId(pdaDepotItemVO.getMaterialId(),pdaDepotItemVO.getDepotId()),unitInfo,pdaDepotItemVO.getCommodityUnit());
+            }else {
+                stock = materialService.getCurrentStockByMaterialIdAndDepotId(pdaDepotItemVO.getMaterialId(),pdaDepotItemVO.getDepotId());
+            }
+            pdaDepotItemVO.setInventory(stock.toString());
+        }
+        return list;
     }
 
     /**
@@ -95,8 +114,17 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
      * @return
      */
     @Override
-    public PDADepotItemVO pdaDetail(Long id) {
-        return depotItemMapper.pdaDetail(id);
+    public PDADepotItemVO pdaDetail(Long id) throws Exception {
+        PDADepotItemVO itemVO = depotItemMapper.pdaDetail(id);
+        Unit unitInfo = materialService.findUnit(itemVO.getMaterialId()); //查询多单位信息
+        BigDecimal stock;
+        if (unitInfo != null && unitInfo.getId() != null){
+            stock = unitService.parseStockByUnit(materialService.getMaterialStockByMid(itemVO.getMaterialId()),unitInfo,itemVO.getCommodityUnit());
+        }else {
+            stock = materialService.getMaterialStockByMid(itemVO.getMaterialId());
+        }
+        itemVO.setInventory(stock.toString());
+        return itemVO;
     }
 
     /**
@@ -109,6 +137,16 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         return depotItemMapper.materialDepotDetail(type, materialId);
     }
 
+    /**
+     * pda 获取商品打印条码信息
+     * @param depotItemId 单据子表id
+     * @return
+     */
+    @Override
+    public PDAPrintVo pdaPrintMaterial(Long depotItemId) {
+        return materialMapperEx.pdaPrintMaterial(depotItemId);
+    }
+
     @Override
     public DepotItem getDepotItem(long id)throws Exception {
         DepotItem result=null;
@@ -485,26 +523,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");
-                if (batchNumber.isEmpty()){
-                    batchNumber = rowObj.getString("barCode");
-                }
-                MaterialExtend materialExtend = materialExtendService.getInfoByBatchNumber(batchNumber);
+                String barCode = rowObj.getString("barCode");
+                //根据条码获取商品信息
+                MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(barCode);
                 if(materialExtend == null) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
-                            String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, batchNumber));
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, barCode));
                 }
+                //设置单据子表属性
+                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())) {
@@ -512,18 +567,18 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                     if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(depotHead.getSubType()) ||
                             BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(depotHead.getSubType())) {
                         throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, batchNumber));
+                                String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, barCode));
                     }
                     //调拨单不能选择批号或序列号商品(该场景走出库和入库单)
                     if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
                         throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, batchNumber));
+                                String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, barCode));
                     }
                     //盘点业务不能选择批号或序列号商品(该场景走出库和入库单)
                     if(BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(depotHead.getSubType())
                        ||BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())) {
                         throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, batchNumber));
+                                String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, barCode));
                     }
                 }
                 if (StringUtil.isExist(rowObj.get("snList"))) {
@@ -541,14 +596,14 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                                     depotHead.getNumber(), materialExtend.getMaterialId(), depotId, inPrice, depotItem.getSnList());
                         } else {
                             throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_CODE,
-                                    String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, batchNumber));
+                                    String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, barCode));
                         }
                     }
                 } else {
                     //入库或出库
                     if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
                             BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
-                        //序列号不能为空
+                        //序列号不能为空  先去掉校验
                         if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
                             //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
                             if(systemConfigService.getInOutManageFlag() &&
@@ -557,14 +612,16 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                                             ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
                                             ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
                                 //跳过
-                            } else {
-                                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
-                                        String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, batchNumber));
                             }
+//                            else {
+//                                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
+//                                        String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, barCode));
+//                            }
                         }
                     }
                 }
                 if (StringUtil.isExist(rowObj.get("batchNumber"))) {
+                    //设置基础单位数量
                     depotItem.setBatchNumber(rowObj.getString("batchNumber"));
                 } else {
                     //入库或出库
@@ -581,29 +638,31 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                                 //跳过
                             } else {
                                 throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, batchNumber));
+                                        String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, barCode));
                             }
                         }
                     }
                 }
+                //设置有效期
                 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)) { //如果等于基本单位
@@ -631,7 +690,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         if(depotItem.getOperNumber().add(finishNumber).compareTo(preNumber)>0) {
                             if(!systemConfigService.getOverLinkBillFlag()) {
                                 throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
+                                        String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
                             }
                         }
                     } else if("update".equals(actionType)) {
@@ -649,7 +708,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                                 if (depotItem.getOperNumber().add(realFinishNumber).compareTo(preNumber) > 0) {
                                     if (!systemConfigService.getOverLinkBillFlag()) {
                                         throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
-                                                String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
+                                                String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
                                     }
                                 }
                             } else {
@@ -667,7 +726,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         if("零售".equals(depotHead.getSubType()) || "销售".equals(depotHead.getSubType())) {
                             if (unitPrice.compareTo(materialExtend.getLowDecimal()) < 0) {
                                 throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, batchNumber));
+                                        String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, barCode));
                             }
                         }
                     }
@@ -692,12 +751,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"));
@@ -728,18 +783,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"));
@@ -749,7 +798,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                 }
                 //出库时判断库存是否充足
                 if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                    String stockMsg = material.getName() + "-" + batchNumber;
+                    String stockMsg = material.getName() + "-" + barCode;
                     BigDecimal stock = getCurrentStockByParam(depotItem.getDepotId(),depotItem.getMaterialId());
                     if(StringUtil.isNotEmpty(depotItem.getSku())) {
                         //对于sku商品要换个方式计算库存
@@ -757,7 +806,7 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                     }
                     if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
                         //对于批次商品要换个方式计算库存
-                        stock = getOneBatchNumberStock(depotItem.getDepotId(), batchNumber, depotItem.getBatchNumber());
+                        stock = getOneBatchNumberStock(depotItem.getDepotId(), barCode, depotItem.getBatchNumber());
                         stockMsg += "-批号" + depotItem.getBatchNumber();
                     }
                     BigDecimal thisRealNumber = depotItem.getBasicNumber()==null?BigDecimal.ZERO:depotItem.getBasicNumber();
@@ -788,16 +837,18 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
                         }
                     }
                 }
-                if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
-                    //表单入库,修改商品库存
-                    materialExtend.setInventory(materialExtend.getInventory().add(depotItem.getBasicNumber()));
-                    materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
-                }else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                    //表单出库,修改商品库存
-                    materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
-                    materialExtendService.updateInventory("单据",depotItem.getId(),materialExtend);
-                }
                 this.insertDepotItemWithObj(depotItem);
+                if ("1".equals(depotHead.getStatus())){
+                    //单据审核,处理批次商品信息
+                    if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
+                        //表单入库,新增批次商品信息
+                        materialBatchService.generateMaterialBatchByDepotItemId(depotItem,depotHead.getOrganId());
+                    }else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
+                        //表单出库,修改商品库存
+                        //materialExtend.setInventory(materialExtend.getInventory().subtract(depotItem.getBasicNumber()));
+                        materialBatchService.handleMaterialBatchByDepotItemId(depotItem.getId());
+                    }
+                }
                 //更新当前库存
                 updateCurrentStock(depotItem);
                 //更新当前成本价
@@ -1176,14 +1227,15 @@ public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem
         Boolean forceFlag = systemConfigService.getForceApprovalFlag();
         Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
         //初始库存
-        BigDecimal initStock = materialService.getInitStockByMidAndDepotList(depotList, mId);
+        BigDecimal stock = materialService.getInitStockByMidAndDepotList(depotList, mId);
+        BigDecimal initStock = stock == null ? BigDecimal.ZERO : stock;
         //盘点复盘后数量的变动
         BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
         //表单的数量
         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();
@@ -1490,32 +1542,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();
@@ -1527,7 +1564,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) {
@@ -1542,7 +1579,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())) {

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

@@ -0,0 +1,186 @@
+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.datasource.mappers.MaterialCategoryMapperEx;
+import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
+import com.jsh.erp.exception.JshException;
+import com.jsh.erp.query.LambdaQueryWrapperX;
+import com.jsh.erp.service.*;
+import com.jsh.erp.utils.DateUtils;
+import com.jsh.erp.utils.RandomHelper;
+import com.jsh.erp.utils.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class MaterialBatchServiceImpl extends ServiceImpl<MaterialBatchMapper,MaterialBatch> implements MaterialBatchService {
+    private Logger logger = LoggerFactory.getLogger(MaterialBatchServiceImpl.class);
+
+    @Resource
+    private MaterialBatchMapper materialBatchMapper;
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private DepotItemService depotItemService;
+
+    @Resource
+    private MaterialExtendService materialExtendService;
+
+    @Resource
+    private InventoryLogService inventoryLogService;
+
+    @Resource
+    private MaterialService materialService;
+
+
+    @Override
+    public void generateMaterialBatchByDepotItemId(DepotItem depotItem, Long supplierId) throws Exception {
+        //获取单据子表信息
+        //获取条码信息
+        MaterialExtend materialExtend = materialExtendService.getMaterialExtend(depotItem.getMaterialExtendId());
+        //创建批次信息
+        MaterialBatch materialBatch = new MaterialBatch();
+        //设置单据id
+        materialBatch.setDepotItemId(depotItem.getId());
+        //设置商品id
+        materialBatch.setMaterialId(depotItem.getMaterialId());
+        //设置供应商id
+        materialBatch.setSupplierId(supplierId);
+        //设置商品单位
+        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());
+        //条码
+        materialBatch.setBarCode(materialExtend.getBarCode());
+        materialBatchMapper.insert(materialBatch);
+    }
+
+    @Override
+    public void handleMaterialBatchByDepotItemId(Long diId) throws Exception {
+        DepotItem depotItem = depotItemService.getDepotItem(diId);
+        //根据单据商品id查询商品批次数据
+        List<MaterialBatch> list = materialBatchMapper.getMaterialBatchByMaterialId(depotItem.getMaterialId(),depotItem.getDepotId());
+        //根据单据子表基础单位数量减去批次库存
+        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();
+                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()));
+                depotItemService.updateCurrentStockFun(materialBatch.getMaterialId(),materialBatch.getDepotId());
+        }
+    }
+
+    /**
+     * 根据仓库id和商品id查询商品批次库存
+     * @param depotList 仓库id
+     * @param mid       商品id
+     */
+    @Override
+    public BigDecimal getInventorySumByDepotAndMid(List<Long> depotList, Long mid) {
+        return materialBatchMapper.getInventorySumByDepotAndMid(depotList,mid);
+    }
+
+    /**
+     * 获取批次号字符
+     */
+    @Override
+    public List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color, String brand, String mfrs, String enableSerialNumber, String enableBatchNumber, Integer offset, Integer rows, Long depotId) throws Exception {
+        List<MaterialVo4Unit> list =null;
+        try{
+
+            if(StringUtil.isNotEmpty(q)) {
+                q = q.replace("'", "");
+                q = q.trim();
+            }
+            list=  materialBatchMapper.findBySelectWithBarCode(q, standardOrModel, color, brand, mfrs,
+                    enableSerialNumber, enableBatchNumber, offset, rows,depotId);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 根据商品条码和仓库id获取商品批次信息
+     * @param barCodes 商品条码字符集合
+     */
+    @Override
+    public List<MaterialBatch> findBySelectWithBarCode(String barCodes,Long depotId) {
+        List<String> barCodeList = null;
+        if (barCodes != null && !barCodes.isEmpty()){
+            barCodeList = Arrays.asList(barCodes.split(","));
+        }
+        List<Long> ids = materialExtendService.selectIdsByBarCode(barCodeList);
+        List<MaterialBatch> list = materialBatchMapper.selectList(new LambdaQueryWrapperX<MaterialBatch>().eq(MaterialBatch::getDepotId,depotId).inIfPresent(MaterialBatch::getMaterialId,ids).gt(MaterialBatch::getInventory,BigDecimal.ZERO));
+        return list;
+    }
+
+    /**
+     * 根据批次号数组查询商品批次信息
+     * @param batchNumbers 批次号数组
+     */
+    @Override
+    public List<TaskStocktakingItemVO> getMaterialByBatchNumber(String[] batchNumbers) {
+        List<TaskStocktakingItemVO> list =  materialBatchMapper.getMaterialByBatchNumber(batchNumbers);
+        return list;
+    }
+
+}

+ 219 - 197
src/main/java/com/jsh/erp/service/impl/MaterialExtendServiceImpl.java

@@ -5,11 +5,14 @@ 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.constants.ExceptionConstants;
+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;
 import com.jsh.erp.datasource.mappers.MaterialExtendMapperEx;
 import com.jsh.erp.datasource.vo.MaterialExtendVo4List;
+import com.jsh.erp.exception.BusinessRunTimeException;
 import com.jsh.erp.exception.JshException;
 import com.jsh.erp.service.*;
 import com.jsh.erp.utils.DateUtils;
@@ -93,175 +96,234 @@ 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(",");
+        //添加条码
+        if (!insertedList.isEmpty()) {
+            for (MaterialExtend materialExtend : insertedList) {
+                //EXCEL中有条码在系统中已存在
+                MaterialExtend me = getInfoByBarCode(materialExtend.getBarCode());
+                if (me != null && !me.getBarCode().isEmpty()) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_PROPERTY_BARCODE_EXIST_CODE,
+                            String.format(ExceptionConstants.MATERIAL_PROPERTY_BARCODE_EXIST_MSG, materialExtend.getBarCode()));
                 }
-            }
-            //删除拓展行
-            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"));
+        if (!updatedList.isEmpty()) {
+            for (MaterialExtend materialExtend : updatedList) {
+                //新条码和原来条码不一致,判断新条码是否已存在
+                MaterialExtend me = getInfoByBarCode(materialExtend.getBarCode());
+                if (me != null && !materialExtend.getId().equals(me.getId())) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_PROPERTY_BARCODE_EXIST_CODE,
+                            String.format(ExceptionConstants.MATERIAL_PROPERTY_BARCODE_EXIST_MSG, materialExtend.getBarCode()));
                 }
+                //修改商品拓展
                 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 +340,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 +355,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
@@ -458,7 +496,7 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
     @Override
     public MaterialExtend getInfoByBarCode(String barCode)throws Exception {
         MaterialExtendExample example = new MaterialExtendExample();
-        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        example.createCriteria().andBarCodeLike(barCode).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
         List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
         if(list!=null && list.size()>0) {
             return list.get(0);
@@ -498,31 +536,15 @@ public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper,
     }
 
     /**
-     * 修改子商品库存
+     * 根据商品条码集合查询商品id
+     *
+     * @param barCodeList 商品条码
      */
     @Override
-    public synchronized void updateInventory(String type, Long id, MaterialExtend materialExtend) throws Exception {
-        if (materialExtend.getInventory() != null){
-            //获取修改前库存
-            int originalStock = materialExtendMapper.selectByPrimaryKey(materialExtend.getId()).getInventory().intValue();
-            if (originalStock != materialExtend.getInventory().intValue()){
-                //库存不相同,修改库存
-                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(originalStock);
-                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()));
-            }
-        }
+    public List<Long> selectIdsByBarCode(List<String> barCodeList) {
+        return materialExtendMapperEx.getIdsByBarcode(barCodeList);
     }
+
     /**
      * 设置当前库存
      * @param depotId 仓库id

+ 249 - 250
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,7 @@ 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.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.exception.BusinessRunTimeException;
 import com.jsh.erp.exception.JshException;
 import com.jsh.erp.query.LambdaQueryWrapperX;
@@ -87,6 +88,8 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     private SupplierService supplierService;
     @Resource
     private DepotMapperEx depotMapperEx;
+    @Resource
+    private MaterialBatchService materialBatchService;
 
     @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,48 +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(6);
         //设置系统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("lowSafeStock")!=null) {
-                        BigDecimal lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
+                    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("highSafeStock")!=null) {
-                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
+                        if(jsonObj.getHighSafeStock() != null) {
+                            highSafeStock = jsonObj.getHighSafeStock();
                         }
-                        Long depotId = jsonObj.getLong("id");
-                        if(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("0"), 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;
@@ -240,50 +245,50 @@ 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);
                     }
                 }
             }
             logService.insertLog("商品",
                     new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(material.getName()).toString(), request);
             return 1;
-        }catch(Exception e){
+        }
+        catch (BusinessRunTimeException ex) {
+            throw new BusinessRunTimeException(ex.getCode(), ex.getMessage());
+        }
+        catch(Exception e){
             JshException.writeFail(logger, e);
             return 0;
         }
@@ -564,16 +569,16 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
             //遇到多个副条码的情况,只加第一个
             otherMaterialMap.putIfAbsent(me.getMaterialId(), me);
         }
-        String nameStr = "名称*,规格,型号,颜色,品牌,类别,基础重量(kg),基本单位*,副单位,基本条码*,副条码,比例,多属性," +
-                "采购价,零售价,销售价,最低售价,状态*,序列号,批号,自定义1,自定义2,自定义3,备注,系统sku,生产日期,保质期,供应商,商品条码,批次号,仓库名称,仓位货架";
+        String nameStr = "名称*,规格,型号,颜色,品牌,类别,基础重量(kg),基本单位*,副单位,比例,多属性," +
+                "状态*,序列号,系统sku,商品条码,自定义1,自定义2,自定义3,备注";
         List<String> nameList = StringUtil.strToStringList(nameStr);
         //仓库列表
         List<Depot> depotList = depotService.getAllList();
-        if (nameList != null) {
-            for(Depot depot: depotList) {
-                nameList.add(depot.getName());
-            }
-        }
+//        if (nameList != null) {
+//            for(Depot depot: depotList) {
+//                nameList.add(depot.getName());
+//            }
+//        }
         //期初库存缓存
         List<MaterialInitialStock> misList = materialInitialStockMapperEx.getListExceptZero();
         Map<String, BigDecimal> misMap = new HashMap<>();
@@ -597,36 +602,23 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                 objs[6] = m.getWeight() == null ? "" : m.getWeight().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
                 objs[7] = m.getCommodityUnit();
                 objs[8] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getCommodityUnit();
-                objs[9] = m.getmBarCode();
-                objs[10] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getBarCode();
-                objs[11] = m.getRatio() == null ? "" : m.getRatio().toString();
-                objs[12] = m.getSku();
-                objs[13] = m.getPurchaseDecimal() == null ? "" : m.getPurchaseDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[14] = m.getCommodityDecimal() == null ? "" : m.getCommodityDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[15] = m.getWholesaleDecimal() == null ? "" : m.getWholesaleDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[16] = m.getLowDecimal() == null ? "" : m.getLowDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[17] = m.getEnabled() ? "1" : "0";
-                objs[18] = m.getEnableSerialNumber();
-                objs[19] = m.getEnableBatchNumber();
-                objs[20] = m.getOtherField1();
-                objs[21] = m.getOtherField2();
-                objs[22] = m.getOtherField3();
-                objs[23] = m.getRemark();
-                objs[24] = m.getSystemSku();
-                objs[25] = m.getProductionDate() == null ? "" : m.getProductionDate().toString();
-                objs[26] = m.getExpiryNum() == null ? "" : m.getExpiryNum().toString();
-                objs[27] = m.getSupplierId() == null ? "" : m.getSupplierId().toString();
-                objs[28] = m.getBarCode();
-                objs[29] = m.getBatchNumber();
-                objs[30] = m.getDepotId() == null ? "" : m.getDepotId().toString();
-                objs[31] = m.getPosition();
+                objs[9] = m.getRatio() == null ? "" : m.getRatio().toString();
+                objs[10] = m.getSku();
+                objs[11] = m.getEnabled() ? "1" : "0";
+                objs[12] = m.getEnableSerialNumber();
+                objs[13] = m.getSystemSku();
+                objs[14] = m.getBarCode();
+                objs[15] = m.getOtherField1();
+                objs[16] = m.getOtherField2();
+                objs[17] = m.getOtherField3();
+                objs[18] = m.getRemark();
                 //仓库期初库存
-                int i = 32;
-                for(Depot depot: depotList) {
-                    BigDecimal number = misMap.get(m.getId() + "_" + depot.getId());
-                    objs[i] = number == null ? "0" : number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
-                    i++;
-                }
+                int i = 19;
+//                for(Depot depot: depotList) {
+//                    BigDecimal number = misMap.get(m.getId() + "_" + depot.getId());
+//                    objs[i] = number == null ? "0" : number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
+//                    i++;
+//                }
                 objects.add(objs);
             }
         }
@@ -992,10 +984,10 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
 
     /**
      * 缓存各个仓库的库存信息
-     * @param src
+     * @param src 行数据
      * @param depotCount
      * @param depotMap
-     * @param i
+     * @param i 行数
      * @return
      * @throws Exception
      */
@@ -1020,6 +1012,35 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     }
 
     /**
+     * 获取excel仓库库位信息
+     * @param src 行数据
+     * @param depotCount 仓库数量
+     * @param depotMap 仓库集合
+     * @param i
+     * @return
+     * @throws Exception
+     */
+    private Map<Long, String> getExcelDepot(Sheet src, int depotCount, Map<String, Long> depotMap, int i) throws Exception {
+        Map<Long, String> stockMap = new HashMap<>();
+        for(int j = 1; j<= depotCount; j++) {
+            int col = 16 + j;
+            if(col < src.getColumns()){
+                String depotName = ExcelUtils.getContent(src, 1, col); //获取仓库名称
+                if(StringUtil.isNotEmpty(depotName)) {
+                    Long depotId = depotMap.get(depotName);
+                    if(depotId!=null && depotId!=0L){
+                        String stockStr = ExcelUtils.getContent(src, i, col);
+                        if(StringUtil.isNotEmpty(stockStr)) {
+                            stockMap.put(depotId, stockStr);
+                        }
+                    }
+                }
+            }
+        }
+        return stockMap;
+    }
+
+    /**
      * 批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位
      * @param mList
      */
@@ -1068,6 +1089,12 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                         String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_MSG, manyBarCode));
             }
         }
+        //EXCEL中有条码在系统中已存在
+        MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(barCode);
+        if (materialExtend != null && !materialExtend.getBarCode().isEmpty()) {
+            throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_CODE,
+                    String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_MSG, barCode));
+        }
         for(MaterialWithInitStock material: mList){
             JSONObject materialExObj = material.getMaterialExObj();
             String basicBarCode = "";
@@ -1195,29 +1222,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
@@ -1319,9 +1323,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
         List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
         if(list!=null && list.size()>0) {
             for(MaterialInitialStock ms: list) {
-                if(ms!=null) {
-                    stock = stock.add(ms.getNumber());
-                }
+                    stock = stock.add(ms.getNumber() == null ? BigDecimal.ZERO : ms.getNumber());
             }
         }
         return stock;
@@ -1462,7 +1464,11 @@ 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()));
+        });
+        return list;
     }
 
     @Override
@@ -1607,20 +1613,6 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
     }
 
     /**
-     * 根据批次号查询商品信息
-     * @param batchNumber 批次号
-     */
-    @Override
-    public List<MaterialVo4Unit> getMaterialByBatchNumber(String batchNumber) {
-        String [] batchNumberArray=batchNumber.split(",");
-        List<MaterialVo4Unit> list =  materialMapperEx.getMaterialByBatchNumber(batchNumberArray);
-        list.forEach(v -> {
-            v.setUnitList(v.getUnitId() == null ? null : unitService.getUnitListByID(v.getUnitId()));
-        });
-        return list;
-    }
-
-    /**
      * 根据商品id查询主表及子表信息
      * @param id 商品id
      * @return
@@ -1664,10 +1656,8 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
         MaterialExample materialExample = new MaterialExample();
         materialExample.createCriteria().andDeleteFlagEqualTo("0");
         List<Material> materials = materialMapper.selectByExample(materialExample);
-        //获取商品子表信息
-        MaterialExtendExample materialExtendExample = new MaterialExtendExample();
-        materialExtendExample.createCriteria().andDeleteFlagEqualTo("0");
-        List<MaterialExtend> extendList = materialExtendMapper.selectByExample(materialExtendExample);
+        //获取商品批次信息
+        List<MaterialBatch> extendList = materialBatchService.list(new LambdaQueryWrapperX<MaterialBatch>().eq(MaterialBatch::getDeleteFlag,"0"));
         //无动销提醒
         materials.stream().filter( v -> v.getMovingPinReminderCycle() != null && !"".equals(v.getMovingPinReminderCycle()))
                         .forEach(v -> {
@@ -1736,7 +1726,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
             String fileName = file.getOriginalFilename();
             if(StringUtil.isNotEmpty(fileName)) {
                 String fileExt = fileName.substring(fileName.indexOf(".")+1);
-                if(!"xls".equals(fileExt)) {
+                if(!"xls".equals(fileExt) && !"xlsx".equals(fileExt)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
                             ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
                 }
@@ -1758,6 +1748,23 @@ 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); //备注
+                //校验字段
                 //名称为空
                 if(StringUtil.isEmpty(name)) {
                     throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
@@ -1768,21 +1775,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,
@@ -1795,7 +1797,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)) {
@@ -1803,65 +1804,38 @@ 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));
-                    }
+                //商品条码为空
+                if(StringUtil.isEmpty(barCode)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_EMPTY_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_EMPTY_MSG, i+1));
                 }
-                String barCode = ExcelUtils.getContent(src, i, 20); //商品条码
-                String depotName = ExcelUtils.getContent(src, i, 21); //仓库名称
-                Long depotId = null;
-                if(StringUtil.isNotEmpty(supplier)) {
-                    //根据仓库名查询仓库id
-                    depotId = depotMapperEx.selectByConditionDepot(depotName,null,null).get(0).getId();
-                    if (depotId == null){
-                        //仓库不存在
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_CODE,
-                                String.format(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_MSG, i+1));
-                    }
+                //校验基本条码长度为4到40位
+                if(!StringUtil.checkBarCodeLength(barCode)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, barCode));
                 }
-                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); //备注
+                //批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
+                batchCheckExistBarCodeByParam(mList, barCode, null);
+//                Long depotId = null;
+//                if(StringUtil.isNotEmpty(depotName)) {
+//                    //根据仓库名查询仓库id
+//                    depotId = depotMapperEx.selectByConditionDepot(depotName,null,null).get(0).getId();
+//                    if (depotId == null){
+//                        //仓库不存在
+//                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_CODE,
+//                                String.format(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_MSG, i+1));
+//                    }
+//                }
                 MaterialWithInitStock m = new MaterialWithInitStock();
                 //设置商品名字、规格、型号、颜色、品牌、类型id
                 m.setName(name);
@@ -1875,7 +1849,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                 //设置单位、备注、基础重量
                 m.setUnit(unit);
                 m.setRemark(remark);
-                m.setWeight(new BigDecimal(weight));
+                m.setWeight(weight.isEmpty()  ? null : new BigDecimal(weight));
                 //设置商品是否启用
                 m.setEnabled("1".equals(enabled));
                 //设置商品是否开启序列号
@@ -1895,19 +1869,8 @@ 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("commodityUnit", manyUnit.isEmpty() ? unit : manyUnit);    //商品单位
                 basicObj.put("barCode", barCode); //商品条码
-                basicObj.put("inventory",inventory); //库存
-                basicObj.put("depotId",depotId);    //仓库id
-                basicObj.put("position",position);  //仓位货架
                 materialExObj.put("basic", basicObj);
                 if(StringUtil.isNotEmpty(manyUnit) && StringUtil.isNotEmpty(ratio)){ //多单位
                     //校验比例是否是数字(含小数)
@@ -1920,20 +1883,13 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                         m.setUnitId(unitId);
                         m.setUnit("");
                     }
-//                    JSONObject otherObj = new JSONObject();
-//                    otherObj.put("commodityUnit", manyUnit);
-//                    otherObj.put("purchaseDecimal", parsePrice(purchaseDecimal,ratio));
-//                    otherObj.put("commodityDecimal", parsePrice(commodityDecimal,ratio));
-//                    otherObj.put("wholesaleDecimal", parsePrice(wholesaleDecimal,ratio));
-//                    otherObj.put("lowDecimal", parsePrice(lowDecimal,ratio));
-//                    materialExObj.put("other", otherObj);
                 } else {
                     m.setUnit(unit);
                     m.setUnitId(null);
                 }
                 m.setMaterialExObj(materialExObj);
-                //设置库存
-                m.setStockMap(getStockMapCache(src, depotCount, depotMap, i));
+                //设置仓库库位
+                m.setDepotMap(getExcelDepot(src, depotCount, depotMap, i));
                 mList.add(m);
             }
             //处理表单信息,转为对象集合
@@ -1941,6 +1897,21 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
             for (Material material : materialList) {
                 //添加商品信息
                 materialMapperEx.insertSelectiveEx(material);
+                //获取excel商品添加库存
+                Map<Long, String> stockMap = material.getDepotMap();
+                for(Depot depot: depotList){
+                    Long depotId = depot.getId();
+                    //excel里面的当前库位
+                    String position = stockMap.get(depot.getId());
+                    //新增或更新初始库存
+                    if(StringUtil.isNotEmpty(position)) {
+                        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
+                        materialInitialStock.setDepotId(depotId);
+                        materialInitialStock.setMaterialId(material.getId());
+                        materialInitialStock.setPosition(position);
+                        materialInitialStockMapper.insertSelective(materialInitialStock);
+                    }
+                }
                 //添加商品子信息
                 for (MaterialExtend materialExtend : material.getList()) {
                     //设置商品id
@@ -1967,27 +1938,50 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
         return info;
     }
 
+    /**
+     * PDA库存查询
+     */
+    @Override
+    public List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO){
+        return materialMapper.inventoryInquiryList(pdaInventoryDTO);
+    }
+
+    /**
+     * 根据库位查询商品id集合
+     */
+    @Override
+    public List<Long> selectMaterialIdByPosition(String position) {
+        return materialInitialStockMapper.selectMaterialIdByPosition(position);
+    }
+
+    /**
+     * 根据类型id查询子类型集合
+     */
     @Override
-    public List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO) throws Exception {
-        //查询类型id的子类型
-        pdaInventoryDTO.setCategoryIds(selectCategoryIds(pdaInventoryDTO.getCategoryId()));
-        return materialMapperEx.inventoryInquiry(pdaInventoryDTO);
+    public List<Long> selectCategoryIds(Long id) {
+        List<Long> longs = new ArrayList<>();
+        longs.add(id);
+        List<MaterialCategory> list = materialCategoryService.list(new LambdaQueryWrapperX<MaterialCategory>().eq(MaterialCategory::getParentId,id).eq(MaterialCategory::getDeleteFlag,"0"));
+        for (MaterialCategory materialCategory : list) {
+            longs.addAll(selectCategoryIds(materialCategory.getId()));
+        }
+        return longs;
     }
 
     /**
      * 查询库位树
      */
     @Override
-    public List<PDATypeTree> selectPosition() {
-        List<String> positions = materialExtendMapper.selectPosition();
+    public List<PDATypeTree> selectPosition(Long depotId) {
+        List<String> positions = materialInitialStockMapper.selectPosition(depotId);
         Map<String,List<String>> map = new HashMap<>();
         for (String s : positions) {
-            String [] str = s.split("-");
+            String [] str = s.split("-",2);
             if (map.get(str[0]) == null){
                 List<String> list = new ArrayList<>();
                 map.put(str[0],list);
             }
-            if (str.length > 2){
+            if (str.length > 1){
                 map.get(str[0]).add(str[1]);
             }
         }
@@ -2010,9 +2004,46 @@ 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();
+    }
+
+    /**
+     * 根据商品id和仓库id查询商品当前库存
+     *
+     * @param mid 商品id
+     * @param did 仓库id
+     * @return 商品库存
+     */
+    @Override
+    public BigDecimal getMaterialStockByMidAndDid(Long mid, Long did) {
+        MaterialCurrentStock materialCurrentStock = materialCurrentStockMapper.selectOne(new LambdaQueryWrapperX<MaterialCurrentStock>().eq(MaterialCurrentStock::getMaterialId,mid).eq(MaterialCurrentStock::getDepotId,did).eq(MaterialCurrentStock::getDeleteFlag,"0"));
+        return materialCurrentStock == null ? BigDecimal.ZERO : materialCurrentStock.getCurrentNumber();
+    }
+
+    /**
      * 解析excel表格数据为商品对象
      */
-    public List<Material> parseMapByExcelData(List<MaterialWithInitStock> mList){
+    private List<Material> parseMapByExcelData(List<MaterialWithInitStock> mList){
         List<Material> materials = new ArrayList<>();
         Map<String,Material> materialMap = new HashMap<>();
         for (MaterialWithInitStock m : mList) {
@@ -2030,8 +2061,7 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                     + "-" + m.getStandard()
                     + "-" + m.getBrand()
                     + "-" + m.getColor()
-                    + "-" + m.getUnit()
-                    + "-" + materialSku;
+                    + "-" + m.getUnit();
             if (materialMap.get(str) == null) {
                 //商品主表不存在,创建商品主表
                 Material material = new Material();
@@ -2071,52 +2101,21 @@ public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> i
                 material.setSystemSku(m.getSystemSku());
                 List<MaterialExtend> list = new ArrayList<>();
                 material.setList(list);
+                material.setDepotMap(m.getDepotMap());
                 materialMap.put(str,material);
             }
             //添加子表信息
             MaterialExtend materialExtend = new MaterialExtend();
             //商品单位
-            materialExtend.setCommodityUnit(m.getUnit());
+            materialExtend.setCommodityUnit(basicObj.getString("commodityUnit"));
             //商品属性
             materialExtend.setSku(materialSku);
-            //采购价格
-            materialExtend.setPurchaseDecimal(basicObj.getBigDecimal("purchaseDecimal"));
-            //零售价格
-            materialExtend.setCommodityDecimal(basicObj.getBigDecimal("commodityDecimal"));
-            //销售价格
-            materialExtend.setWholesaleDecimal(basicObj.getBigDecimal("wholesaleDecimal"));
-            //最低售价
-            materialExtend.setLowDecimal(basicObj.getBigDecimal("lowDecimal"));
-            //生产日期
-            materialExtend.setProductionDate(basicObj.getDate("productionDate"));
-            //保质期天数
-            materialExtend.setExpiryNum(basicObj.getInteger("expiryNum"));
-            //供应商id
-            materialExtend.setSupplierId(basicObj.getLong("supplierId"));
             //商品条码
             materialExtend.setBarCode(basicObj.getString("barCode"));
-            //设置批次号
-            String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
-            materialExtend.setBatchNumber(batchNumber);
-            //仓库id
-            materialExtend.setDepotId(basicObj.getLong("depotId"));
-            //仓位货架
-            materialExtend.setPosition(basicObj.getString("position"));
-            //库存
-            materialExtend.setInventory(basicObj.getBigDecimal("inventory"));
+
             materialMap.get(str).getList().add(materialExtend);
         }
         materialMap.values().forEach(v -> materials.add(v));
         return materials;
     }
-
-    public List<Long> selectCategoryIds(Long id) throws Exception {
-        List<Long> longs = new ArrayList<>();
-        longs.add(id);
-        List<MaterialCategory> list = materialCategoryService.list(new LambdaQueryWrapperX<MaterialCategory>().eq(MaterialCategory::getParentId,id).eq(MaterialCategory::getDeleteFlag,"0"));
-        for (MaterialCategory materialCategory : list) {
-            longs.addAll(selectCategoryIds(materialCategory.getId()));
-        }
-        return longs;
-    }
 }

+ 39 - 36
src/main/java/com/jsh/erp/service/impl/TaskStocktakingServiceImpl.java

@@ -13,10 +13,7 @@ import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.query.LambdaQueryWrapperX;
-import com.jsh.erp.service.DepotService;
-import com.jsh.erp.service.SequenceService;
-import com.jsh.erp.service.TaskStocktakingService;
-import com.jsh.erp.service.UserService;
+import com.jsh.erp.service.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
@@ -53,6 +50,8 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
 
     private final SequenceService sequenceService;
 
+    private final MaterialBatchMapper materialBatchMapper;
+
     @Override
     public List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO) {
         return taskStocktakingMapper.listBy(taskStocktakingQueryDTO);
@@ -68,27 +67,27 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
     public boolean add(TaskStocktakingDTO taskStocktakingDTO) {
         try {
             List<String> collect;
-            List<MaterialExtend> materialExtendList;
+            List<MaterialBatch> materialBatchList;
             //全盘,抽盘,处理任务明细
             if (taskStocktakingDTO.getTaskType() == 1) {
-                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
-                collect = materialExtendList
+                materialBatchList = materialBatchMapper.selectList(new LambdaQueryWrapper<MaterialBatch>().ne(MaterialBatch::getInventory, BigDecimal.ZERO).isNotNull(MaterialBatch::getInventory).eq(MaterialBatch::getDepotId,taskStocktakingDTO.getDepotId()));
+                collect = materialBatchList
                         .stream()
-                        .map(MaterialExtend::getPosition)
+                        .map(MaterialBatch::getPosition)
                         .collect(Collectors.toList());
-                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
-                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
+                List<Long> materialIdList = materialBatchList.stream().map(MaterialBatch::getMaterialId).distinct().collect(Collectors.toList());
+                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
                 List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
                 taskStocktakingDTO.setCategoryCount(categoryIdList.size());
-                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+                taskStocktakingDTO.setMaterialCount(materialBatchList.size());
             } else {
-                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
-                collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
-                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
+                materialBatchList = materialBatchMapper.selectList(new LambdaQueryWrapper<MaterialBatch>().in(MaterialBatch::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
+                collect = materialBatchList.stream().map(MaterialBatch::getPosition).collect(Collectors.toList());
+                List<Long> materialIdList = materialBatchList.stream().map(MaterialBatch::getMaterialId).collect(Collectors.toList());
                 List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
                 List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
                 taskStocktakingDTO.setCategoryCount(categoryIdList.size());
-                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+                taskStocktakingDTO.setMaterialCount(materialBatchList.size());
             }
             //处理商品库位范围处理
             String positionRange = extractRangePair(collect);
@@ -103,7 +102,7 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
             this.save(taskStocktakingDTO);
             //生成任务明细
             List<TaskStocktakingItem> taskStocktakingItemList = new ArrayList<>();
-            materialExtendList.forEach(item -> {
+            materialBatchList.forEach(item -> {
                 TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
                 taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId());
                 taskStocktakingItem.setMaterialItemId(item.getId());
@@ -131,12 +130,17 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
         //获取负责人名称
         User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreator()));
         if (user != null) {
-            taskStocktakingVO.setCreatorName(user.getLoginName());
+            taskStocktakingVO.setCreatorName(user.getUsername());
         }
         //获取创建人名称
         User user1 = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreateBy()));
         if (user1 != null) {
-            taskStocktakingVO.setCreateByName(user1.getLoginName());
+            taskStocktakingVO.setCreateByName(user1.getUsername());
+        }
+        //获取盘点人名称
+        User user2 = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getOperBy()));
+        if (user2 != null) {
+            taskStocktakingVO.setOperByName(user2.getUsername());
         }
         //获取仓库名称
         Depot depot = depotService.getDepot(one.getDepotId());
@@ -154,23 +158,23 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
     public boolean detailUpdate(TaskStocktakingDTO taskStocktakingDTO) {
         try {
             List<String> collect;
-            List<MaterialExtend> materialExtendList;
+            List<MaterialBatch> materialExtendList;
             //全盘,抽盘,处理任务明细
             if (taskStocktakingDTO.getTaskType() == 1) {
-                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
+                materialExtendList = materialBatchMapper.selectList(new LambdaQueryWrapper<MaterialBatch>().ne(MaterialBatch::getInventory, BigDecimal.ZERO).isNotNull(MaterialBatch::getInventory).eq(MaterialBatch::getDepotId,taskStocktakingDTO.getDepotId()));
                 collect = materialExtendList
                         .stream()
-                        .map(MaterialExtend::getPosition)
+                        .map(MaterialBatch::getPosition)
                         .collect(Collectors.toList());
-                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialBatch::getMaterialId).distinct().collect(Collectors.toList());
                 List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
                 List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
                 taskStocktakingDTO.setCategoryCount(categoryIdList.size());
                 taskStocktakingDTO.setMaterialCount(materialExtendList.size());
             } else {
-                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
-                collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
-                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
+                materialExtendList = materialBatchMapper.selectList(new LambdaQueryWrapper<MaterialBatch>().in(MaterialBatch::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
+                collect = materialExtendList.stream().map(MaterialBatch::getPosition).collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialBatch::getMaterialId).collect(Collectors.toList());
                 List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
                 List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
                 taskStocktakingDTO.setCategoryCount(categoryIdList.size());
@@ -196,7 +200,7 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
                     addTaskStocktakingItemList.add(taskStocktakingItem);
                 }
             });
-            List<Long> materialExtendIdList = materialExtendList.stream().map(MaterialExtend::getId).collect(Collectors.toList());
+            List<Long> materialExtendIdList = materialExtendList.stream().map(MaterialBatch::getId).collect(Collectors.toList());
             taskStocktakingItemIdList.forEach(item -> {
                 if (!materialExtendIdList.contains(item)) {
                     TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
@@ -232,8 +236,8 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
      * @return
      */
     @Override
-    public List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus) {
-        return taskStocktakingMapper.pdaList(number , taskStatus);
+    public List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus, Long depotId) {
+        return taskStocktakingMapper.pdaList(number , taskStatus, depotId);
     }
 
     /**
@@ -298,23 +302,22 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
         List<String> rangeParts = new ArrayList<>();
 
         for (String item : data) {
-            // 提取前两部分(假设格式固定,以 "-" 分割,取前两部分)
-            String[] parts = item.split("-");
-            if (parts.length >= 2) {
-                String rangePart = parts[0] + "-" + parts[1];
-                rangeParts.add(rangePart); // 添加到列表
+            if (item != null){
+                // 提取前两部分(假设格式固定,以 "-" 分割,取前两部分)
+                String[] parts = item.split("-");
+                if (parts.length >= 2) {
+                    String rangePart = parts[0] + "-" + parts[1];
+                    rangeParts.add(rangePart); // 添加到列表
+                }
             }
         }
-
         // 如果范围为空,直接返回空字符串
         if (rangeParts.isEmpty()) {
             return "";
         }
-
         // 找到最小和最大范围
         String minRange = Collections.min(rangeParts); // 字典序最小
         String maxRange = Collections.max(rangeParts); // 字典序最大
-
         // 返回范围对
         return minRange + "——" + maxRange;
     }

+ 0 - 1589
src/main/java/com/jsh/erp/utils/StringHelper.java

@@ -1,1589 +0,0 @@
-package com.jsh.erp.utils;
-
-import java.io.UnsupportedEncodingException;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- *   
- * 
- * @Title: StringHelper.java
- * @Description:
- * @author HJJ
- * @version V1.0   字符串处理工具类。
- */
-public final class StringHelper {
-
-	/**
-	 * 描述: 构造方法
-	 */
-	private StringHelper() {
-	}
-
-	/**
-	 * 空字符串
-	 */
-	public static final String EMPTY_STRING = "";
-
-	/**
-	 * 点
-	 */
-	public static final char DOT = '.';
-
-	/**
-	 * 下划线
-	 */
-	public static final char UNDERSCORE = '_';
-
-	/**
-	 * 逗点及空格
-	 */
-	public static final String COMMA_SPACE = ", ";
-
-	/**
-	 * 逗点
-	 */
-	public static final String COMMA = ",";
-
-	/**
-	 * 开始括号
-	 */
-	public static final String OPEN_PAREN = "(";
-
-	/**
-	 * 结束括号
-	 */
-	public static final String CLOSE_PAREN = ")";
-
-	/**
-	 * 单引号
-	 */
-	public static final char SINGLE_QUOTE = '\'';
-
-	/**
-	 * 回车
-	 */
-	public static final String CRLF = "\r\n";
-
-	/**
-	 * 常量 12
-	 */
-	public static final int FIANL_TWELVE = 12;
-
-	/**
-	 * 十六进制常量 0x80
-	 */
-	public static final int HEX_80 = 0x80;
-
-	/**
-	 * 十六进制常量 0xff
-	 */
-	public static final int HEX_FF = 0xff;
-
-	/**
-	 * 把字符数组,转化为一个字符
-	 *
-	 * @param seperator
-	 *            字符分隔符
-	 * @param strings
-	 *            数组对象
-	 * @return 字符串
-	 */
-	public static String join(String seperator, String[] strings) {
-		int length = strings.length;
-		if (length == 0) {
-			return EMPTY_STRING;
-		}
-		StringBuffer buf = new StringBuffer(length * strings[0].length()).append(strings[0]);
-		for (int i = 1; i < length; i++) {
-			buf.append(seperator).append(strings[i]);
-		}
-		return buf.toString();
-	}
-
-	/**
-	 * 把迭代对象转化为一个字符串
-	 *
-	 * @param seperator
-	 *            分隔符
-	 * @param objects
-	 *            迭代器对象
-	 * @return 字符串
-	 */
-	public static String join(String seperator, Iterator<?> objects) {
-		StringBuffer buf = new StringBuffer();
-		if (objects.hasNext()) {
-			buf.append(objects.next());
-		}
-		while (objects.hasNext()) {
-			buf.append(seperator).append(objects.next());
-		}
-		return buf.toString();
-	}
-
-	/**
-	 * 把两个字符串数组的元素用分隔符连接,生成新的数组,生成的数组以第一个字符串数组为参照,与其长度相同。
-	 *
-	 * @param x
-	 *            字符串数组
-	 * @param seperator
-	 *            分隔符
-	 * @param y
-	 *            字符串数组
-	 * @return 组合后的字符串数组
-	 */
-	public static String[] add(String[] x, String seperator, String[] y) {
-		String[] result = new String[x.length];
-		for (int i = 0; i < x.length; i++) {
-			result[i] = x[i] + seperator + y[i];
-		}
-		return result;
-	}
-
-	/**
-	 * 生成一个重复的字符串,如需要重复*10次,则生成:**********。
-	 *
-	 * @param string
-	 *            重复元素
-	 * @param times
-	 *            重复次数
-	 * @return 生成后的字符串
-	 */
-	public static String repeat(String string, int times) {
-		StringBuffer buf = new StringBuffer(string.length() * times);
-		for (int i = 0; i < times; i++) {
-			buf.append(string);
-		}
-		return buf.toString();
-	}
-
-	/**
-	 * 字符串替换处理,把旧的字符串替换为新的字符串,主要是通过字符串查找进行处理
-	 *
-	 * @param source
-	 *            需要进行替换的字符串
-	 * @param old
-	 *            需要进行替换的字符串
-	 * @param replace
-	 *            替换成的字符串
-	 * @return 替换处理后的字符串
-	 */
-	public static String replace(String source, String old, String replace) {
-		StringBuffer output = new StringBuffer();
-
-		int sourceLen = source.length();
-		int oldLen = old.length();
-
-		int posStart = 0;
-		int pos;
-
-		// 通过截取字符串的方式,替换字符串
-		while ((pos = source.indexOf(old, posStart)) >= 0) {
-			output.append(source.substring(posStart, pos));
-
-			output.append(replace);
-			posStart = pos + oldLen;
-		}
-
-		// 如果还有没有处理的字符串,则都添加到新字符串后面
-		if (posStart < sourceLen) {
-			output.append(source.substring(posStart));
-		}
-
-		return output.toString();
-	}
-
-	/**
-	 * 替换字符,如果指定进行全替换,必须设wholeWords=true,否则只替换最后出现的字符。
-	 *
-	 * @param template
-	 *            字符模板
-	 * @param placeholder
-	 *            需要替换的字符
-	 * @param replacement
-	 *            新的字符
-	 * @param wholeWords
-	 *            是否需要全替换,true为需要,false为不需要。如果不需要,则只替换最后出现的字符。
-	 * @return 替换后的新字符
-	 */
-	public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
-		int loc = template.indexOf(placeholder);
-		if (loc < 0) {
-			return template;
-		} else {
-			final boolean actuallyReplace = wholeWords || loc + placeholder.length() == template.length()
-					|| !Character.isJavaIdentifierPart(template.charAt(loc + placeholder.length()));
-			String actualReplacement = actuallyReplace ? replacement : placeholder;
-			return new StringBuffer(template.substring(0, loc)).append(actualReplacement).append(
-					replace(template.substring(loc + placeholder.length()), placeholder, replacement, wholeWords))
-					.toString();
-		}
-	}
-
-	/**
-	 * 替换字符,只替换第一次出现的字符串。
-	 *
-	 * @param template
-	 *            字符模板
-	 * @param placeholder
-	 *            需要替换的字符串
-	 * @param replacement
-	 *            新字符串
-	 * @return 替换后的字符串
-	 */
-	public static String replaceOnce(String template, String placeholder, String replacement) {
-		int loc = template.indexOf(placeholder);
-		if (loc < 0) {
-			return template;
-		} else {
-			return new StringBuffer(template.substring(0, loc)).append(replacement)
-					.append(template.substring(loc + placeholder.length())).toString();
-		}
-	}
-
-	/**
-	 * 把字符串,按指字的分隔符分隔为字符串数组
-	 *
-	 * @param seperators
-	 *            分隔符
-	 * @param list
-	 *            字符串
-	 * @return 字符串数组
-	 */
-	public static String[] split(String list, String seperators) {
-		return split(list, seperators, false);
-	}
-
-	/**
-	 * 把字符串,按指字的分隔符分隔为字符串数组
-	 *
-	 * @param seperators
-	 *            分隔符
-	 * @param list
-	 *            字符串
-	 * @param include
-	 *            是否需要把分隔符也返回
-	 * @return 字符串数组
-	 */
-	public static String[] split(String list, String seperators, boolean include) {
-		StringTokenizer tokens = new StringTokenizer(list, seperators, include);
-		String[] result = new String[tokens.countTokens()];
-		int i = 0;
-		while (tokens.hasMoreTokens()) {
-			result[i++] = tokens.nextToken();
-		}
-		return result;
-	}
-
-	/**
-	 * 提取字符串中,以.为分隔符后的所有字符,如string.exe,将返回exe。
-	 *
-	 * @param qualifiedName
-	 *            字符串
-	 * @return 提取后的字符串
-	 */
-	public static String unqualify(String qualifiedName) {
-		return unqualify(qualifiedName, ".");
-	}
-
-	/**
-	 * 提取字符串中,以指定分隔符后的所有字符,如string.exe,将返回exe。
-	 *
-	 * @param qualifiedName
-	 *            字符串
-	 * @param seperator
-	 *            分隔符
-	 * @return 提取后的字符串
-	 */
-	public static String unqualify(String qualifiedName, String seperator) {
-		return qualifiedName.substring(qualifiedName.lastIndexOf(seperator) + 1);
-	}
-
-	/**
-	 * 提取字符串中,以.为分隔符以前的字符,如string.exe,则返回string
-	 *
-	 * @param qualifiedName
-	 *            字符串
-	 * @return 提取后的字符串
-	 */
-	public static String qualifier(String qualifiedName) {
-		int loc = qualifiedName.lastIndexOf(".");
-		if (loc < 0) {
-			return EMPTY_STRING;
-		} else {
-			return qualifiedName.substring(0, loc);
-		}
-	}
-
-	/**
-	 * 向字符串数组中的所有元素添加上后缀
-	 *
-	 * @param columns
-	 *            字符串数组
-	 * @param suffix
-	 *            后缀
-	 * @return 添加后缀后的数组
-	 */
-	public static String[] suffix(String[] columns, String suffix) {
-		if (suffix == null) {
-			return columns;
-		}
-		String[] qualified = new String[columns.length];
-		for (int i = 0; i < columns.length; i++) {
-			qualified[i] = suffix(columns[i], suffix);
-		}
-		return qualified;
-	}
-
-	/**
-	 * 向字符串加上后缀
-	 *
-	 * @param name
-	 *            需要添加后缀的字符串
-	 * @param suffix
-	 *            后缀
-	 * @return 添加后缀的字符串
-	 */
-	public static String suffix(String name, String suffix) {
-		return (suffix == null) ? name : name + suffix;
-	}
-
-	/**
-	 * 向字符串数组中的所有元素,添加上前缀
-	 *
-	 * @param columns
-	 *            需要添加前缀的字符串数组
-	 * @param prefix
-	 *            prefix
-	 * @return
-	 */
-	public static String[] prefix(String[] columns, String prefix) {
-		if (prefix == null) {
-			return columns;
-		}
-		String[] qualified = new String[columns.length];
-		for (int i = 0; i < columns.length; i++) {
-			qualified[i] = prefix + columns[i];
-		}
-		return qualified;
-	}
-
-	/**
-	 * 向字符串添加上前缀
-	 *
-	 * @param name
-	 *            需要添加前缀的字符串
-	 * @param prefix
-	 *            前缀
-	 * @return 添加前缀后的字符串
-	 */
-	public static String prefix(String name, String prefix) {
-		return (prefix == null) ? name : prefix + name;
-	}
-
-	/**
-	 * 判断字符串是否为"true"、"t",如果是,返回true,否则返回false
-	 *
-	 * @param tfString
-	 *            需要进行判断真/假的字符串
-	 * @return true/false
-	 */
-	public static boolean booleanValue(String tfString) {
-		String trimmed = tfString.trim().toLowerCase();
-		return trimmed.equals("true") || trimmed.equals("t");
-	}
-
-	/**
-	 * 把对象数组转化为字符串
-	 *
-	 * @param array
-	 *            对象数组
-	 * @return 字符串
-	 */
-	public static String toString(Object[] array) {
-		int len = array.length;
-		if (len == 0) {
-			return StringHelper.EMPTY_STRING;
-		}
-		StringBuffer buf = new StringBuffer(len * FIANL_TWELVE);
-		for (int i = 0; i < len - 1; i++) {
-			buf.append(array[i]).append(StringHelper.COMMA_SPACE);
-		}
-		return buf.append(array[len - 1]).toString();
-	}
-
-	/**
-	 * 描述:把数组中的所有元素出现的字符串进行替换,把旧字符串替换为新字符数组的所有元素,只替换第一次出现的字符。
-	 * 
-	 * @param string
-	 *            需要替换的数组
-	 * @param placeholders
-	 *            需要替换的字符串
-	 * @param replacements
-	 *            新字符串数组
-	 * @return 替换后的字符串数组
-	 */
-	public static String[] multiply(String string, Iterator<?> placeholders, Iterator<?> replacements) {
-		String[] result = new String[] { string };
-		while (placeholders.hasNext()) {
-			result = multiply(result, (String) placeholders.next(), (String[]) replacements.next());
-		}
-		return result;
-	}
-
-	/**
-	 * 把数组中的所有元素出现的字符串进行替换,把旧字符串替换为新字符数组的所有元素,只替换第一次出现的字符。
-	 *
-	 * @param strings
-	 *            需要替换的数组
-	 * @param placeholder
-	 *            需要替换的字符串
-	 * @param replacements
-	 *            新字符串数组
-	 * @return 替换后的字符串数组
-	 */
-	private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
-		String[] results = new String[replacements.length * strings.length];
-		int n = 0;
-		for (int i = 0; i < replacements.length; i++) {
-			for (int j = 0; j < strings.length; j++) {
-				results[n++] = replaceOnce(strings[j], placeholder, replacements[i]);
-			}
-		}
-		return results;
-	}
-
-	/**
-	 * 统计Char在字符串中出现在次数,如"s"在字符串"string"中出现的次数
-	 *
-	 * @param string
-	 *            字符串
-	 * @param character
-	 *            需要进行统计的char
-	 * @return 数量
-	 */
-	public static int count(String string, char character) {
-		int n = 0;
-		for (int i = 0; i < string.length(); i++) {
-			if (string.charAt(i) == character) {
-				n++;
-			}
-		}
-		return n;
-	}
-
-	/**
-	 * 描述:计算字符串中未引用的字符
-	 * 
-	 * @param string
-	 *            字符串
-	 * @param character
-	 *            字符
-	 * @return 未引用的字符数
-	 */
-	public static int countUnquoted(String string, char character) {
-		if (SINGLE_QUOTE == character) {
-			throw new IllegalArgumentException("Unquoted count of quotes is invalid");
-		}
-
-		int count = 0;
-		int stringLength = string == null ? 0 : string.length();
-		boolean inQuote = false;
-		for (int indx = 0; indx < stringLength; indx++) {
-			if (inQuote) {
-				if (SINGLE_QUOTE == string.charAt(indx)) {
-					inQuote = false;
-				}
-			} else if (SINGLE_QUOTE == string.charAt(indx)) {
-				inQuote = true;
-			} else if (string.charAt(indx) == character) {
-				count++;
-			}
-		}
-		return count;
-	}
-
-	/**
-	 * 
-	 * 描述:描述:判断字符串是否为空,如果为true则为空。与isEmpty不同,如果字符为" "也视为空字符
-	 * 
-	 * @param str
-	 *            字符串
-	 * @return
-	 */
-	public static boolean isBlank(String str) {
-		boolean b = true;// 20140507 modify by liwei 修复对" "为false的bug
-		if (str == null) {
-			b = true;
-		} else {
-			int strLen = str.length();
-			if (strLen == 0) {
-				b = true;
-			}
-
-			for (int i = 0; i < strLen; i++) {
-				if (!Character.isWhitespace(str.charAt(i))) {
-					b = false;
-					break;
-				}
-			}
-		}
-
-		return b;
-	}
-
-	/**
-	 * 
-	 * 描述:描述:判断字符串是否为空,如果为true则不为空。与isNotEmpty不同,如果字符为" "也视为空字符
-	 * 
-	 * @param str
-	 *            字符串
-	 * @return
-	 */
-	public static boolean isNotBlank(String str) {
-		int strLen = 0;
-		if (str != null)
-			strLen = str.length();
-		if (str == null || strLen == 0) {
-			return false;
-		}
-		for (int i = 0; i < strLen; i++) {
-			if (!Character.isWhitespace(str.charAt(i))) {
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * 判断字符串是否非空,如果为true则不为空
-	 *
-	 * @param string
-	 *            字符串
-	 * @return true/false
-	 */
-	public static boolean isNotEmpty(String string) {
-		return string != null && string.length() > 0;
-	}
-
-	/**
-	 * 判断字符串是否空,如果为true则为空
-	 *
-	 * @param str
-	 *            字符串
-	 * @return true/false
-	 */
-
-	public static boolean isEmpty(String str) {
-		if (str == null || str.trim().length() == 0) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * 向字符串添加上前缀,并以.作为分隔符
-	 *
-	 * @param name
-	 *            需要添加前缀的字符串
-	 * @param prefix
-	 *            前缀
-	 * @return 添加前缀后的字符串
-	 */
-	public static String qualify(String name, String prefix) {
-		if (name.startsWith("'")) {
-			return name;
-		}
-
-		return new StringBuffer(prefix.length() + name.length() + 1).append(prefix).append(DOT).append(name).toString();
-	}
-
-	/**
-	 * 向字符串数组中的所有字符添加上前缀,前以点作为分隔符
-	 *
-	 * @param names
-	 *            字符串数组
-	 * @param prefix
-	 *            前缀
-	 * @return 添加前缀后的字符串数组
-	 */
-	public static String[] qualify(String[] names, String prefix) {
-		if (prefix == null) {
-			return names;
-		}
-		int len = names.length;
-		String[] qualified = new String[len];
-		for (int i = 0; i < len; i++) {
-			qualified[i] = qualify(prefix, names[i]);
-		}
-		return qualified;
-	}
-
-	/**
-	 * 在字符串中,查找字符第一次出现的位置
-	 *
-	 * @param sqlString
-	 *            原字符串
-	 * @param string
-	 *            需要查找到字符串
-	 * @param startindex
-	 *            开始位置
-	 * @return 第一个出现的位置
-	 */
-	public static int firstIndexOfChar(String sqlString, String string, int startindex) {
-		int matchAt = -1;
-		for (int i = 0; i < string.length(); i++) {
-			int curMatch = sqlString.indexOf(string.charAt(i), startindex);
-			if (curMatch >= 0) {
-				if (matchAt == -1) {
-					matchAt = curMatch;
-				} else {
-					matchAt = Math.min(matchAt, curMatch);
-				}
-			}
-		}
-		return matchAt;
-	}
-
-	/**
-	 * 从字符串中提取指字长度的字符。区分中英文。<br>
-	 * 如果需要加省略号,则将在指定长度上少取3个字符宽度,末尾加上"......"。
-	 *
-	 * @param string
-	 *            字符串
-	 * @param length
-	 *            要取的字符长度,此为中文长度,英文仅当作半个字符。
-	 * @param appendSuspensionPoints
-	 *            是否需要加省略号
-	 * @return 提取后的字符串
-	 */
-	public static String truncate(String string, int length, boolean appendSuspensionPoints) {
-		if (isEmpty(string) || length < 0) {
-			return string;
-		}
-
-		if (length == 0) {
-			return "";
-		}
-
-		int strLength = string.length(); // 字符串字符个数
-		int byteLength = byteLength(string); // 字符串字节长度
-		length *= 2; // 换成字节长度
-
-		// 判断是否需要加省略号
-		boolean needSus = false;
-		if (appendSuspensionPoints && byteLength >= length) {
-			needSus = true;
-
-			// 如果需要加省略号,则要少取2个字节用来加省略号
-			length -= 2;
-		}
-
-		StringBuffer result = new StringBuffer();
-		int count = 0;
-		for (int i = 0; i < strLength; i++) {
-			if (count >= length) { // 取完了
-				break;
-			}
-
-			char c = string.charAt(i);
-
-			if (isLetter(c)) { // Ascill字符
-				result.append(c);
-				count += 1;
-			} else { // 非Ascill字符
-				if (count == length - 1) { // 如果只要取1个字节了,而后面1个是汉字,就放空格
-					result.append(" ");
-					count += 1;
-				} else {
-					result.append(c);
-					count += 2;
-				}
-			}
-		}
-
-		if (needSus) {
-			result.append("...");
-		}
-
-		return result.toString();
-	}
-
-	/**
-	 * 描述:判断一个字符是Ascill字符还是其它字符(如汉,日,韩文字符)
-	 * 
-	 * @param c
-	 *            需要判断的字符
-	 * @return
-	 */
-	public static boolean isLetter(char c) {
-		int k = HEX_80;
-		return c / k == 0 ? true : false;
-	}
-
-	/**
-	 * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
-	 *
-	 * @param s
-	 *            ,需要得到长度的字符串
-	 * @return int, 得到的字符串长度
-	 */
-	public static int byteLength(String s) {
-		char[] c = s.toCharArray();
-		int len = 0;
-		for (int i = 0; i < c.length; i++) {
-			if (isLetter(c[i])) {
-				len++;
-			} else {
-				len += 2;
-			}
-		}
-		return len;
-	}
-
-	/**
-	 * 从字符串中提取指字长度的字符
-	 *
-	 * @param string
-	 *            字符串
-	 * @param length
-	 *            字符长度
-	 * @return 提取后的字符串
-	 */
-	public static String truncate(String string, int length) {
-		if (isEmpty(string)) {
-			return string;
-		}
-
-		if (string.length() <= length) {
-			return string;
-		} else {
-			return string.substring(0, length);
-		}
-	}
-
-	/**
-	 * 去丢字符的左侧空格
-	 *
-	 * @param value
-	 *            字符串
-	 * @return 去丢左侧空格后的字符串
-	 */
-	public static String leftTrim(String value) {
-		String result = value;
-		if (result == null) {
-			return result;
-		}
-		char ch[] = result.toCharArray();
-		int index = -1;
-		for (int i = 0; i < ch.length; i++) {
-			if (!Character.isWhitespace(ch[i])) {
-				break;
-			}
-			index = i;
-		}
-
-		if (index != -1) {
-			result = result.substring(index + 1);
-		}
-		return result;
-	}
-
-	/**
-	 * 去丢字符的右侧空格
-	 *
-	 * @param value
-	 *            字符串
-	 * @return 去右侧空格后的字符串
-	 */
-	public static String rightTrim(String value) {
-		String result = value;
-		if (result == null) {
-			return result;
-		}
-		char ch[] = result.toCharArray();
-		int endIndex = -1;
-		for (int i = ch.length - 1; i > -1; i--) {
-			if (!Character.isWhitespace(ch[i])) {
-				break;
-			}
-			endIndex = i;
-		}
-
-		if (endIndex != -1) {
-			result = result.substring(0, endIndex);
-		}
-		return result;
-	}
-
-	/**
-	 * 把null字符串转化为""
-	 *
-	 * @param source
-	 *            空字符串
-	 * @return 转化后的字符串
-	 */
-	public static String n2s(String source) {
-		return source != null ? source : "";
-	}
-
-	/**
-	 * 如果字符串为空,则返回默认字符串
-	 *
-	 * @param source
-	 *            源字符串
-	 * @param defaultStr
-	 *            默认字符串
-	 * @return 转换后的字符串
-	 */
-	public static String n2s(String source, String defaultStr) {
-		return source != null ? source : defaultStr;
-	}
-
-	/**
-	 * 将字符串格式化成 HTML 以SCRIPT变量 主要是替换单,双引号,以将内容格式化输出,适合于 HTML 中的显示输出
-	 *
-	 * @param str
-	 *            要格式化的字符串
-	 * @return 格式化后的字符串
-	 */
-	public static String toScript(String str) {
-		if (str == null) {
-			return null;
-		}
-
-		String html = new String(str);
-
-		html = replace(html, "\"", "\\\"");
-		html = replace(html, "\r\n", "\n");
-		html = replace(html, "\n", "\\n");
-		html = replace(html, "\t", "    ");
-		html = replace(html, "\'", "\\\'");
-
-		html = replace(html, "  ", " &nbsp;");
-
-		html = replace(html, "</script>", "<\\/script>");
-		html = replace(html, "</SCRIPT>", "<\\/SCRIPT>");
-
-		return html;
-	}
-
-	/**
-	 * 同于String#trim(),但是检测null,如果原字符串为null,则仍然返回null
-	 *
-	 * @param s
-	 *            s
-	 * @return
-	 */
-	public static String trim(String s) {
-		return s == null ? s : s.trim();
-	}
-
-	/**
-	 * 对字符串进行空格处理,如果字符串为null呀是空字符串, 则返回默认的数字。
-	 *
-	 * @param source
-	 *            需要进行处理的字符串
-	 * @param defaultValue
-	 *            缺省值
-	 * @return 字符串的数字值
-	 */
-	public static int strTrim(String source, int defaultValue) {
-		if (isEmpty(source)) {
-			return defaultValue;
-		}
-		try {
-			source = source.trim();
-			int value = (new Integer(source)).intValue();
-			return value;
-		} catch (Exception ex) {
-			ex.printStackTrace();
-			System.err.println("数字转换出错,请检查数据来源。返回默认值");
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * 对字符串进行过滤处理,如果字符串是null或为空字符串, 返回默认值。
-	 *
-	 * @param source
-	 *            需要进行处理的字符串
-	 * @param defaultValue
-	 *            缺省值
-	 * @return 过滤后的字符串
-	 */
-	public static String strTrim(String source, String defaultValue) {
-		if (StringHelper.isEmpty(source)) {
-			return defaultValue;
-		}
-		try {
-			source = source.trim();
-			return source;
-		} catch (Exception ex) {
-			ex.printStackTrace();
-			System.err.println("字符串去空格失败,返回默认值");
-			return defaultValue;
-		}
-	}
-
-	/**
-	 * 描述:为了防止跨站脚本攻击,转换<>这种尖括号。
-	 * 
-	 * @param source
-	 * @return
-	 */
-	public static String encodeURL(String source) {
-		if (source == null) {
-			return null;
-		}
-		String html = new String(source);
-		html = replace(html, "<", "&lt;");
-		html = replace(html, ">", "&gt;");
-		html = replace(html, "\"", "&quot;");
-		html = replace(html, " ", "&nbsp;");
-		html = replace(html, "\'", "&acute;");
-		html = replace(html, "\\", "&#092;");
-		html = replace(html, "&", "&amp;");
-		html = replace(html, "\r", "");
-		html = replace(html, "\n", "");
-		html = replace(html, "(", "&#40;");
-		html = replace(html, ")", "&#41;");
-		html = replace(html, "[", "&#91;");
-		html = replace(html, "]", "&#93;");
-		html = replace(html, ";", "&#59;");
-		html = replace(html, "/", "&#47;");
-
-		return html;
-	}
-
-	/**
-	 * 把字符串中一些特定的字符转换成html字符,如&、<、>、"号等
-	 *
-	 * @param source
-	 *            需要进行处理的字符串
-	 * @return 处理后的字符串
-	 */
-	public static String encodeHtml(String source) {
-		if (source == null) {
-			return null;
-		}
-
-		String html = new String(source);
-
-		html = replace(html, "&", "&amp;");
-		html = replace(html, "<", "&lt;");
-		html = replace(html, ">", "&gt;");
-		html = replace(html, "\"", "&quot;");
-		html = replace(html, " ", "&nbsp;");
-		html = replace(html, "\'", "&acute;");
-		return html;
-	}
-
-	/**
-	 * 把一些html的字符串还原
-	 *
-	 * @param source
-	 *            需要进行处理的字符串
-	 * @return 处理后的字符串
-	 */
-	public static String decodeHtml(String source) {
-		if (source == null) {
-			return null;
-		}
-
-		String html = new String(source);
-
-		html = replace(html, "&amp;", "&");
-		html = replace(html, "&lt;", "<");
-		html = replace(html, "&gt;", ">");
-		html = replace(html, "&quot;", "\"");
-		html = replace(html, " ", "&nbsp;");
-
-		html = replace(html, "\r\n", "\n");
-		html = replace(html, "\n", "<br>\n");
-		html = replace(html, "\t", "    ");
-		html = replace(html, "  ", " &nbsp;");
-
-		return html;
-	}
-
-	/**
-	 * 判断字符串是否为布尔值,如true/false等
-	 *
-	 * @param source
-	 *            需要进行判断的字符串
-	 * @return 返回字符串的布尔值
-	 */
-	public static boolean isBoolean(String source) {
-		if (source.equalsIgnoreCase("true") || source.equalsIgnoreCase("false")) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * 去除字符串中的最后字符
-	 *
-	 * @param str
-	 *            原字符串
-	 * @param strMove
-	 *            要去除字符 比如","
-	 * @return 去除后的字符串
-	 */
-	public static String lastCharTrim(String str, String strMove) {
-		if (isEmpty(str)) {
-			return "";
-		}
-
-		String newStr = "";
-		if (str.lastIndexOf(strMove) != -1 && str.lastIndexOf(strMove) == str.length() - 1) {
-			newStr = str.substring(0, str.lastIndexOf(strMove));
-		}
-		return newStr;
-	}
-
-	/**
-	 * 清除字符串里的html代码
-	 *
-	 * @param html
-	 *            需要进行处理的字符串
-	 * @return 清除html后的代码
-	 */
-	public static String clearHtml(String html) {
-		if (isEmpty(html)) {
-			return "";
-		}
-
-		String patternStr = "(<[^>]*>)";
-		Pattern pattern = Pattern.compile(patternStr, Pattern.CASE_INSENSITIVE);
-		Matcher matcher = null;
-		StringBuffer bf = new StringBuffer();
-		try {
-			matcher = pattern.matcher(html);
-			boolean first = true;
-			int start = 0;
-			int end = 0;
-			while (matcher.find()) {
-				start = matcher.start(1);
-				if (first) {
-					bf.append(html.substring(0, start));
-					first = false;
-				} else {
-					bf.append(html.substring(end, start));
-				}
-
-				end = matcher.end(1);
-			}
-			if (end < html.length()) {
-				bf.append(html.substring(end));
-			}
-			html = bf.toString();
-			return html;
-		} catch (Exception ex) {
-			ex.printStackTrace();
-			System.err.println("清除html标签失败");
-		} finally {
-			pattern = null;
-			matcher = null;
-		}
-		return html;
-	}
-
-	/**
-	 * 把文件格式转换为html格式
-	 *
-	 * @param content
-	 *            转换的内容
-	 * @return
-	 */
-	public static String textFmtToHtmlFmt(String content) {
-		content = StringHelper.replace(content, " ", "&nbsp;");
-		content = StringHelper.replace(content, "\r\n", "<br>");
-		content = StringHelper.replace(content, "\n", "<br>");
-
-		return content;
-	}
-
-	/**
-	 * 
-	 * 描述:大写英文字母转换成小写
-	 * 
-	 * @param strIn
-	 *            字符串参数
-	 * @return
-	 */
-	public static String toLowerStr(String strIn) {
-		String strOut = new String(); // 输出的字串
-		int len = strIn.length(); // 参数的长度
-		int i = 0; // 计数器
-		char ch; // 存放参数的字符
-
-		while (i < len) {
-			ch = strIn.charAt(i);
-
-			if (ch >= 'A' && ch <= 'Z') {
-				ch = (char) (ch - 'A' + 'a');
-			}
-
-			strOut += ch;
-			i++;
-		}
-		return strOut;
-	}
-
-	/**
-	 * 
-	 * 描述:小写英文字母转换成大写
-	 * 
-	 * @param strIn
-	 *            字符串参数
-	 * @return
-	 */
-	public static String toUpperStr(String strIn) {
-		String strOut = new String(); // 输出的字串
-		int len = strIn.length(); // 参数的长度
-		int i = 0; // 计数器
-		char ch; // 存放参数的字符
-
-		while (i < len) {
-			ch = strIn.charAt(i);
-
-			if (ch >= 'a' && ch <= 'z') {
-				ch = (char) (ch - 'a' + 'A');
-			}
-
-			strOut += ch;
-			i++;
-		}
-		return strOut;
-	}
-
-	/**
-	 * 货币缩写,提供亿和万两个单位,并精确到小数点2位 切换到新的算法:对数算法
-	 * 
-	 * @param original
-	 * @return
-	 */
-	public static String currencyShortFor(String original) {
-		if (StringHelper.isBlank(original)) {
-			return "";
-		} else {
-			String shortFor = "";
-			double shortForValue = 0;
-			DecimalFormat df = new DecimalFormat("#.00");
-
-			try {
-				double account = Double.parseDouble(original);
-				if (account / 100000000 > 1) {
-					shortForValue = account / 100000000;
-					shortFor = df.format(shortForValue) + "亿";
-				} else if (account / 10000 > 1) {
-					shortForValue = account / 10000;
-					shortFor = df.format(shortForValue) + "万";
-				} else {
-					shortFor = original;
-				}
-			} catch (NumberFormatException e) {
-				e.printStackTrace();
-				System.err.println("字符串[" + original + "]转换成数字出错");
-			}
-
-			return shortFor;
-		}
-	}
-
-	/**
-	 * 将日期格式由yyyyMMdd装换为yyyy-MM-dd
-	 * 
-	 * @param date
-	 *            Date string whose format is yyyyMMdd.
-	 * @return
-	 */
-	public static String formatDate(String date) {
-		if (isBlank(date) || date.length() < 8) {
-			return "";
-		}
-		StringBuffer dateBuf = new StringBuffer();
-		dateBuf.append(date.substring(0, 4));
-		dateBuf.append("-");
-		dateBuf.append(date.substring(4, 6));
-		dateBuf.append("-");
-		dateBuf.append(date.substring(6, 8));
-		return dateBuf.toString();
-	}
-
-	/**
-	 * 判断是否为整数
-	 * 
-	 * @param str
-	 *            传入的字符串
-	 * @return 是整数返回true,否则返回false
-	 */
-	public static boolean isInteger(String str) {
-		Pattern pattern = Pattern.compile("^\\d+(\\.0)?$", Pattern.CASE_INSENSITIVE);
-		return pattern.matcher(str).matches();
-
-	}
-
-	/**
-	 * 用于=中英文混排标题中限定字符串长度。保证显示长度最多只相差一个全角字符。
-	 * 
-	 * @param string
-	 *            需要截取的字符串
-	 * @param byteCount
-	 *            字节数(度量标准为中文为两个字节,ASCII字符为一个字节,这样子,刚好匹配ASCII为半角字符,而中文为全角字符,
-	 *            保证在网页上中英文混合的句子长度一致)
-	 * @return
-	 * @throws UnsupportedEncodingException
-	 */
-	public static String substring(String string, int byteCount) throws UnsupportedEncodingException {
-		if (isBlank(string)) {
-			return string;
-		}
-		byte[] bytes = string.getBytes("Unicode");// 使用UCS-2编码.
-		int viewBytes = 0; // 表示当前的字节数(英文为单字节,中文为双字节的表示方法)
-		int ucs2Bytes = 2; // 要截取的字节数,从第3个字节开始,前两位为位序。(UCS-2的表示方法)
-		// UCS-2每个字符使用两个字节来编码。
-		// ASCII n+=1,i+=2
-		// 中文 n+=2,i+=2
-		for (; ucs2Bytes < bytes.length && viewBytes < byteCount; ucs2Bytes++) {
-			// 奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节
-			if (ucs2Bytes % 2 == 1) {
-				viewBytes++; // 低字节,无论中英文,都算一个字节。
-			} else {
-				// 当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节
-				// 高位时,仅中文的高位算一字节。
-				if (bytes[ucs2Bytes] != 0) {
-					viewBytes++;
-				}
-			}
-		}
-		// 截一半的汉字要保留
-		if (ucs2Bytes % 2 == 1) {
-			ucs2Bytes = ucs2Bytes + 1;
-		}
-		String result = new String(bytes, 0, ucs2Bytes, "Unicode");// 将字节流转换为java默认编码UTF-8的字符串
-		if (bytes.length > ucs2Bytes) {
-			result += "...";
-		}
-		return result;
-	}
-
-	/**
-	 * 描述:根据长度截断字串
-	 * 
-	 * @param str
-	 *            字串
-	 * @param length
-	 *            截取长度
-	 * @return
-	 */
-	public static String[] splite(String str, int length) {
-		if (StringHelper.isEmpty(str)) {
-			return null;
-		}
-		String[] strArr = new String[(str.length() + length - 1) / length];
-		for (int i = 0; i < strArr.length; i++) {
-			if (str.length() > i * length + length - 1) {
-				strArr[i] = str.substring(i * length, i * length + length - 1);
-			} else {
-				strArr[i] = str.substring(i * length);
-			}
-		}
-		return strArr;
-	}
-
-	/**
-	 * 描述:把某一个字符变成大写
-	 * 
-	 * @param str
-	 *            str 字串
-	 * @param index
-	 *            第几个字符
-	 * @return
-	 */
-	public static String toUpOneChar(String str, int index) {
-		return toUpOrLowOneChar(str, index, 1);
-	}
-
-	/**
-	 * 描述:把某一个字符变成小写 作者:李建 时间:Dec 17, 2010 9:42:32 PM
-	 * 
-	 * @param str
-	 *            str 字串
-	 * @param index
-	 *            第几个字符
-	 * @return
-	 */
-	public static String toLowOneChar(String str, int index) {
-		return toUpOrLowOneChar(str, index, 0);
-	}
-
-	/**
-	 * 描述:把某一个字符变成大写或小写 作者:李建 时间:Dec 17, 2010 9:39:32 PM
-	 * 
-	 * @param str
-	 *            字串
-	 * @param index
-	 *            第几个字符
-	 * @param upOrLow
-	 *            大小写 1:大写;0小写
-	 * @return
-	 */
-	public static String toUpOrLowOneChar(String str, int index, int upOrLow) {
-		if (StringHelper.isNotEmpty(str) && index > -1 && index < str.length()) {
-			char[] chars = str.toCharArray();
-			if (upOrLow == 1) {
-				chars[index] = Character.toUpperCase(chars[index]);
-			} else {
-				chars[index] = Character.toLowerCase(chars[index]);
-			}
-			return new String(chars);
-		}
-		return str;
-	}
-
-	/**
-	 * 将字符串用分隔符断裂成字符串列表
-	 * 
-	 * @param value
-	 *            原字符串
-	 * @param separator
-	 *            分隔字符
-	 * @return 结果列表
-	 */
-	public static List<String> split2List(String value, String separator) {
-		List<String> ls = new ArrayList<String>();
-		int i = 0, j = 0;
-		while ((i = value.indexOf(separator, i)) != -1) {
-			ls.add(value.substring(j, i));
-			++i;
-			j = i;
-		}
-		ls.add(value.substring(j));
-		return ls;
-	}
-
-	/**
-	 * 将数组用分隔符连接成新字符串(split的逆方法)
-	 * 
-	 * @param strs
-	 *            字符串数组
-	 * @param sep
-	 *            分隔符
-	 * @return 结果字符串
-	 */
-	public static String join(String[] strs, String sep) {
-		StringBuilder res = new StringBuilder();
-		for (int i = 0; i < strs.length; i++) {
-			res.append(strs[i] + sep);
-		}
-		return res.substring(0, res.length() - sep.length());
-	}
-
-	/**
-	 * 获得一个UUID
-	 * 
-	 * @return String UUID
-	 */
-	public static String getUUID() {
-		String str = UUID.randomUUID().toString();// 标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx(8-4-4-4-12)
-		// 去掉"-"符号,不用replaceAll的原因与split一样,replaceAll支持正则表达式,频繁使用时效率不够高(当然偶尔用一下影响也不会特别严重)
-		return join(split(str, "-"), "");
-	}
-
-	/**
-	 * <pre>
-	 * 例: String strVal="This is a dog"; String
-	 * strResult=CTools.replace(strVal,"dog","cat"); 结果: strResult equals
-	 * "This is cat"
-	 *
-	 * @param strSrc
-	 *            要进行替换操作的字符串
-	 * @param strOld
-	 *            要查找的字符串
-	 * @param strNew
-	 *            要替换的字符串
-	 * @return 替换后的字符串
-	 * 
-	 *         <pre>
-	 */
-	public static final String replaceAllStr(String strSrc, String strOld, String strNew) {
-		if (strSrc == null || strOld == null || strNew == null)
-			return "";
-
-		int i = 0;
-
-		if (strOld.equals(strNew)) // 避免新旧字符一样产生死循环
-			return strSrc;
-
-		if ((i = strSrc.indexOf(strOld, i)) >= 0) {
-			char[] arr_cSrc = strSrc.toCharArray();
-			char[] arr_cNew = strNew.toCharArray();
-
-			int intOldLen = strOld.length();
-			StringBuffer buf = new StringBuffer(arr_cSrc.length);
-			buf.append(arr_cSrc, 0, i).append(arr_cNew);
-
-			i += intOldLen;
-			int j = i;
-
-			while ((i = strSrc.indexOf(strOld, i)) > 0) {
-				buf.append(arr_cSrc, j, i - j).append(arr_cNew);
-				i += intOldLen;
-				j = i;
-			}
-
-			buf.append(arr_cSrc, j, arr_cSrc.length - j);
-
-			return buf.toString();
-		}
-
-		return strSrc;
-	}
-
-	/**
-	 * 用于将字符串中的特殊字符转换成Web页中可以安全显示的字符串 可对表单数据据进行处理对一些页面特殊字符进行处理如'
-	 * <','>','"',''','&'
-	 * 
-	 * @param strSrc
-	 *            要进行替换操作的字符串
-	 * @return 替换特殊字符后的字符串
-	 * @since 1.0
-	 */
-
-	public static String htmlEncode(String strSrc) {
-		if (strSrc == null)
-			return "";
-
-		char[] arr_cSrc = strSrc.toCharArray();
-		StringBuffer buf = new StringBuffer(arr_cSrc.length);
-		char ch;
-
-		for (int i = 0; i < arr_cSrc.length; i++) {
-			ch = arr_cSrc[i];
-
-			if (ch == '<')
-				buf.append("&lt;");
-			else if (ch == '>')
-				buf.append("&gt;");
-			else if (ch == '"')
-				buf.append("&quot;");
-			else if (ch == '\'')
-				buf.append("&#039;");
-			else if (ch == '&')
-				buf.append("&amp;");
-			else
-				buf.append(ch);
-		}
-
-		return buf.toString();
-	}
-
-	/**
-	 * 用于将字符串中的特殊字符转换成Web页中可以安全显示的字符串 可对表单数据据进行处理对一些页面特殊字符进行处理如'
-	 * <','>','"',''','&'
-	 * 
-	 * @param strSrc
-	 *            要进行替换操作的字符串
-	 * @param quotes
-	 *            为0时单引号和双引号都替换,为1时不替换单引号,为2时不替换双引号,为3时单引号和双引号都不替换
-	 * @return 替换特殊字符后的字符串
-	 * @since 1.0
-	 */
-	public static String htmlEncode(String strSrc, int quotes) {
-
-		if (strSrc == null)
-			return "";
-		if (quotes == 0) {
-			return htmlEncode(strSrc);
-		}
-
-		char[] arr_cSrc = strSrc.toCharArray();
-		StringBuffer buf = new StringBuffer(arr_cSrc.length);
-		char ch;
-
-		for (int i = 0; i < arr_cSrc.length; i++) {
-			ch = arr_cSrc[i];
-			if (ch == '<')
-				buf.append("&lt;");
-			else if (ch == '>')
-				buf.append("&gt;");
-			else if (ch == '"' && quotes == 1)
-				buf.append("&quot;");
-			else if (ch == '\'' && quotes == 2)
-				buf.append("&#039;");
-			else if (ch == '&')
-				buf.append("&amp;");
-			else
-				buf.append(ch);
-		}
-
-		return buf.toString();
-	}
-
-	/**
-	 * 和htmlEncode正好相反
-	 * 
-	 * @param strSrc
-	 *            要进行转换的字符串
-	 * @return 转换后的字符串
-	 * @since 1.0
-	 */
-	public static String htmlDecode(String strSrc) {
-		if (strSrc == null)
-			return "";
-		strSrc = strSrc.replaceAll("&lt;", "<");
-		strSrc = strSrc.replaceAll("&gt;", ">");
-		strSrc = strSrc.replaceAll("&quot;", "\"");
-		strSrc = strSrc.replaceAll("&#039;", "'");
-		strSrc = strSrc.replaceAll("&amp;", "&");
-		return strSrc;
-	}
-
-	/**
-	 * 实际处理 return toChineseNoReplace(null2Blank(str));
-	 * 
-	 * @param str
-	 *            要进行处理的字符串
-	 * @return 转换后的字符串
-	 */
-	public static String toChineseAndHtmlEncode(String str, int quotes) {
-		try {
-			if (str == null) {
-				return "";
-			} else {
-				str = str.trim();
-				str = new String(str.getBytes("ISO8859_1"), "GBK");
-				String htmlEncode = htmlEncode(str, quotes);
-				return htmlEncode;
-			}
-		} catch (Exception exp) {
-			return "";
-		}
-	}
-
-	/**
-	 * 把null值和""值转换成&nbsp; 主要应用于页面表格格的显示
-	 * 
-	 * @param str
-	 *            要进行处理的字符串
-	 * @return 转换后的字符串
-	 */
-	public static String str4Table(String str) {
-		if (str == null)
-			return "&nbsp;";
-		else if (str.equals(""))
-			return "&nbsp;";
-		else
-			return str;
-	}
-
-}

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

@@ -7,7 +7,8 @@ server:
 #文件上传方式 1-本机 2-oss
 file:
   uploadType: 2
-  path: /pc/dev/upload #文件上传根目录
+  path: /pc/pro/upload #文件上传根目录
+  apkPath: /root/saas/apk #apk文件上传目录
 
 spring:
   #数据库连接
@@ -20,7 +21,7 @@ spring:
   redis:
     host: 127.0.0.1
     port: 6379
-    password:
+    password: 
 
 aliyun:
   accessKeyId: LTAI5tAWjmJQaDBF6u7JAgap
@@ -30,7 +31,14 @@ 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:
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    #   log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+    default-executor-type: simple

+ 1 - 0
src/main/resources/application-pro.yml

@@ -8,6 +8,7 @@ server:
 file:
   uploadType: 2
   path: /pc/pro/upload #文件上传根目录
+  apkPath: /root/saas/apk #apk文件上传目录
 
 spring:
   #数据库连接

+ 1 - 0
src/main/resources/application-test.yml

@@ -8,6 +8,7 @@ server:
 file:
   uploadType: 2
   path: /pc/test/upload #文件上传根目录
+  apkPath: /root/saas/apk #apk文件上传目录
 
 spring:
   #数据库连接

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

@@ -760,7 +760,8 @@
       dh.goods_type_count,
       dh.oper_time,
       s.supplier AS supplier_name,
-      dh.status
+      dh.status,
+      dh.receiver_address
     FROM
       jsh_depot_head dh
       LEFT JOIN jsh_supplier s ON dh.organ_id = s.id
@@ -777,6 +778,9 @@
       <if test="beginTime != null and beginTime != ''">
         AND dh.create_time between #{beginTime} and #{endTime}
       </if>
+      <if test="depotId != null and depotId !=0">
+        AND dh.depot_id = #{depotId}
+      </if>
     </where>
       GROUP BY dh.id
       ORDER BY dh.create_time DESC

+ 36 - 8
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">
@@ -576,8 +600,8 @@
       m.`name` AS material_name,
       m.standard AS material_standard,
       me.batch_number AS batch_number,
-      me.production_date AS production_date,
-      me.position AS position,
+      di.production_date AS production_date,
+      di.position AS position,
 	  me.inventory AS inventory,
 	  me.bar_code AS bar_code,
 	  di.oper_number AS oper_number,
@@ -585,7 +609,10 @@
       di.material_unit AS material_unit,
       di.actual_quantity_in_storage AS actual_quantity_in_storage,
       di.material_id AS material_id,
-      m.img_name AS img_name
+      m.img_name AS img_name,
+      di.header_id,
+      di.material_extend_id,
+      di.depot_id
     FROM
       jsh_depot_item di
     LEFT JOIN jsh_material m ON di.material_id = m.id
@@ -600,9 +627,9 @@
       di.id AS id,
       m.`name` AS material_name,
       m.standard AS material_standard,
-      me.batch_number AS batch_number,
-      me.production_date AS production_date,
-      me.position AS position,
+      mb.batch_number AS batch_number,
+      di.production_date AS production_date,
+      di.position AS position,
 	  me.inventory AS inventory,
 	  me.bar_code AS bar_code,
 	  di.oper_number AS oper_number,
@@ -614,6 +641,7 @@
       jsh_depot_item di
       LEFT JOIN jsh_material m ON di.material_id = m.id
       LEFT JOIN jsh_material_extend me ON di.material_extend_id = me.id
+      LEFT JOIN material_batch mb ON (SELECT id FROM jsh_depot_item WHERE link_id = di.id LIMIT 1) = mb.depot_item_id
     WHERE
       di.delete_flag = '0'
       AND di.id = #{id}
@@ -626,7 +654,7 @@
       m.`name` AS material_name,
       d.name AS depot_name,
       m.standard AS material_standard,
-      di.actual_quantity_in_storage AS actual_quantity_in_storage,
+      di.oper_number AS actual_quantity_in_storage,
       dh.create_time AS warehousing_time,
       me.commodity_unit AS commodity_unit,
       m.img_name AS img_name
@@ -639,7 +667,7 @@
     WHERE
       di.delete_flag = '0'
       AND dh.delete_flag = '0'
-      AND dh.status in ('2','3')
+      AND dh.status in ('1','2','3')
       AND dh.type = #{type}
       AND di.material_id = #{materialId}
   </select>

+ 2 - 3
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='调拨'
@@ -1114,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

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

@@ -0,0 +1,101 @@
+<?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 depot_id = #{depotID} 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>
+
+    <select id="findBySelectWithBarCode" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
+        select m.*,u.name unit_name,mc.name categoryName,me.bar_code,me.id meId,me.commodity_unit,me.sku,
+        me.production_date,me.expiry_num,me.supplier_id,me.batch_number,me.depot_id,me.position,d.`name` depotName,s.supplier supplierName,me.inventory
+        from jsh_material m
+        left join material_batch me on m.id=me.material_id and ifnull(me.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_material_category mc on m.category_id = mc.id and ifnull(mc.delete_Flag,'0') !='1'
+        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 m.enabled=1 and me.id is not null
+        <if test="q != null and q !=''">
+            <bind name="bindKey" value="'%'+q+'%'"/>
+            and (me.bar_code like #{bindKey} or me.batch_number like #{bindKey} or m.name like #{bindKey} or m.mnemonic like #{bindKey} or m.standard like #{bindKey}
+            or m.model like #{bindKey} or m.color like #{bindKey} or m.brand like #{bindKey} )
+        </if>
+        <if test="standardOrModel != null and standardOrModel !=''">
+            <bind name="bindStandardOrModel" value="'%'+standardOrModel+'%'"/>
+            and (m.standard like #{bindStandardOrModel} or m.model like #{bindStandardOrModel})
+        </if>
+        <if test="color != null and color !=''">
+            <bind name="bindColor" value="'%'+color+'%'"/>
+            and m.color like #{bindColor}
+        </if>
+        <if test="brand != null and brand !=''">
+            <bind name="bindBrand" value="'%'+brand+'%'"/>
+            and m.brand like #{bindBrand}
+        </if>
+        <if test="enableSerialNumber != null and enableSerialNumber !=''">
+            and m.enable_serial_number = #{enableSerialNumber}
+        </if>
+        <if test="enableBatchNumber != null and enableBatchNumber !=''">
+            and m.enable_batch_number = #{enableBatchNumber}
+        </if>
+        <if test="depotId != null and depotId !=''">
+            and me.depot_id = #{depotId}
+        </if>
+        and ifnull(m.delete_flag,'0') !='1'
+        ORDER BY m.id desc, me.default_flag desc, me.id asc
+        <if test="offset != null and rows != null">
+            limit #{offset},#{rows}
+        </if>
+    </select>
+
+    <select id="getMaterialByBatchNumber" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.vo.TaskStocktakingItemVO">
+        select
+        mc.`name` AS category_name,
+        m.`name` AS material_name,
+        m.standard AS standard,
+        m.model AS model,
+        m.color AS color,
+        m.brand AS brand,
+        me.position AS position,
+        me.batch_number AS batch_number,
+        m.system_sku AS system_sku,
+        me.sku AS sku,
+        me.commodity_unit AS commodity_unit,
+        me.production_date AS production_date,
+        s.supplier AS supplier_name,
+        me.bar_code AS bar_code,
+        me.inventory AS inventory,
+        me.expiry_num AS expiry_num,
+        d.`name` AS depot_name
+        from jsh_material m
+        left join material_batch me on m.id=me.material_id and ifnull(me.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_material_category mc ON mc.id = m.category_id
+        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
+        me.batch_number in (
+        <foreach collection="batchNumberArray" item="batchNumber" separator=",">
+            #{batchNumber}
+        </foreach>
+        )
+        and ifnull(m.delete_flag,'0') !='1'
+        order by m.id desc, me.default_flag desc, me.id asc
+    </select>
+
+</mapper>

+ 9 - 4
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>
@@ -481,8 +490,4 @@
     AND ifnull(me.delete_Flag,'0') !='1'
   </select>
 
-  <select id="selectPosition"  resultType="String">
-    SELECT DISTINCT position FROM jsh_material_extend WHERE position IS NOT NULL AND position != "" AND ifnull(delete_Flag,'0') !='1'
-  </select>
-
 </mapper>

+ 15 - 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'
@@ -92,4 +92,18 @@
         )
         AND IFNULL(delete_Flag,'0') != '1'
     </select>
+
+    <select id="getIdsByBarcode" resultType="java.lang.Long">
+        SELECT DISTINCT material_id FROM jsh_material_extend
+        <where>
+            <if test="barCodeList != null and barCodeList.size()>0">
+                and bar_code in
+                <foreach collection="barCodeList" item="item" index="index" separator="," open="(" close=")">
+                    #{item}
+                </foreach>
+            </if>
+            AND IFNULL(delete_Flag,'0') != '1'
+        </where>
+    </select>
+
 </mapper>

+ 19 - 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">
@@ -255,4 +263,13 @@
       delete_flag = #{deleteFlag,jdbcType=VARCHAR}
     where id = #{id,jdbcType=BIGINT}
   </update>
+
+  <select id="selectPosition" resultType="String" parameterType="java.lang.Long">
+    SELECT DISTINCT position FROM jsh_material_initial_stock WHERE depot_id = #{depotId} AND position IS NOT NULL AND position != "" AND ifnull(delete_Flag,'0') !='1'
+  </select>
+
+  <select id="selectMaterialIdByPosition" resultType="String">
+    SELECT DISTINCT material_id FROM jsh_material_initial_stock WHERE position LIKE CONCAT('%',#{position},'%') AND ifnull(delete_Flag,'0') !='1'
+  </select>
+
 </mapper>

+ 45 - 0
src/main/resources/mapper_xml/MaterialMapper.xml

@@ -488,4 +488,49 @@
     where id = #{id,jdbcType=BIGINT}
   </update>
 
+  <select id="inventoryInquiryList" parameterType="com.jsh.erp.datasource.pda.dto.PDAInventoryDTO" resultType="com.jsh.erp.datasource.pda.vo.PDADepotItemVO">
+    SELECT
+    m.id materialId,
+    me.id materialExtendId,
+    m.name materialName,
+    m.standard materialStandard,
+    mis.position,
+    me.bar_code,
+    me.commodity_unit,
+    m.img_name,
+    CAST(IFNULL(mi.inventory,0) / me.ratio AS DECIMAL(10,0)) inventory
+    FROM jsh_material m
+    left join jsh_material_extend me on m.id=me.material_id and ifnull(me.delete_Flag,'0') !='1'
+    left join jsh_material_initial_stock mis ON m.id= mis.material_id AND mis.depot_id = #{depotId}
+    left JOIN (SELECT material_id,SUM(current_number) AS 'inventory' FROM jsh_material_current_stock GROUP BY material_id) mi ON m.id = mi.material_id
+    <where>
+      m.enabled = 1 and me.id is not null
+      <if test="keyword != null and keyword !=''">
+        <bind name="bindKey" value="'%'+keyword+'%'"/>
+        and (m.name like #{bindKey} or me.bar_code like #{bindKey})
+      </if>
+      <if test="categoryId != null">
+        and m.category_id IN (
+        <foreach collection="categoryIds" item="item" separator=",">
+          #{item}
+        </foreach>
+        )
+      </if>
+      <if test="materialIds != null">
+        and m.id IN (
+        <foreach collection="materialIds" item="item" separator=",">
+          #{item}
+        </foreach>
+        )
+      </if>
+      <if test="type == 'have'">
+        and mi.inventory > 0
+      </if>
+      <if test="type == 'none'">
+        and ifnull(mi.inventory,0) &lt;= 0
+      </if>
+      and ifnull(me.delete_flag,'0') !='1'
+    </where>
+  </select>
+
 </mapper>

+ 12 - 54
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,
@@ -791,24 +791,6 @@
         limit 0,1
     </select>
 
-    <select id="getMaterialByBatchNumber" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
-        select m.*,u.name unit_name, me.id meId, me.commodity_unit, me.purchase_decimal, me.commodity_decimal,me.inventory,
-        me.wholesale_decimal, me.low_decimal, me.sku,me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.depot_id, me.position,d.`name` depotName,s.supplier supplierName
-        from jsh_material m
-        left join jsh_material_extend me on m.id=me.material_id and ifnull(me.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_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
-        me.batch_number in (
-        <foreach collection="batchNumberArray" item="batchNumber" separator=",">
-            #{batchNumber}
-        </foreach>
-        )
-        and ifnull(m.delete_flag,'0') !='1'
-        order by m.id desc, me.default_flag desc, me.id asc
-    </select>
-
 
     <select id="getMaterialBySystemSku" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
         WITH RankedExtend AS (
@@ -849,41 +831,6 @@
         ORDER BY m.id DESC, me.default_flag DESC, me.production_date,me.batch_number ASC
     </select>
 
-    <select id="inventoryInquiry" parameterType="com.jsh.erp.datasource.pda.dto.PDAInventoryDTO" resultType="com.jsh.erp.datasource.pda.vo.PDADepotItemVO">
-        select m.id materialId,m.name materialName,m.standard materialStandard,u.name unit_name,mc.name categoryName,me.bar_code,me.id meId,me.commodity_unit,me.sku,
-        me.production_date,me.expiry_num,me.supplier_id,me.batch_number,me.depot_id,me.position,d.`name` depotName,s.supplier supplierName,m.img_name,me.inventory
-        from jsh_material m
-        left join jsh_material_extend me on m.id=me.material_id and ifnull(me.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_material_category mc on m.category_id = mc.id and ifnull(mc.delete_Flag,'0') !='1'
-        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 m.enabled = 1
-        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} or me.bar_code like #{bindKey})
-        </if>
-        <if test="position != null and position !=''">
-            <bind name="bindPosition" value="'%'+position+'%'"/>
-            and me.position like #{bindPosition}
-        </if>
-        <if test="categoryId != null">
-            and m.category_id IN (
-            <foreach collection="categoryIds" item="item" separator=",">
-                #{item}
-            </foreach>
-            )
-        </if>
-        <if test="type == 'have'">
-            and me.inventory > 0
-        </if>
-        <if test="type == 'none'">
-            and me.inventory &lt;= 0
-        </if>
-        and ifnull(me.delete_flag,'0') !='1'
-    </select>
-
     <select id="getMaterialCurrentPriceByIdList" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku">
         WITH RankedExtend AS (
             SELECT
@@ -911,4 +858,15 @@
         ORDER BY m.id DESC
     </select>
 
+    <select id="pdaPrintMaterial" parameterType="java.lang.Long" resultType="com.jsh.erp.datasource.pda.vo.PDAPrintVo">
+        SELECT s.supplier customerName,dh.number,m.system_sku barCode,mb.batch_number
+        FROM
+        jsh_depot_item di
+        LEFT JOIN jsh_depot_head dh ON di.header_id = dh.id
+        LEFT JOIN jsh_material m ON di.material_id = m.id
+        LEFT JOIN jsh_supplier s ON dh.organ_id = s.id
+        LEFT JOIN material_batch mb ON (SELECT id FROM jsh_depot_item WHERE link_id = di.id LIMIT 1) = mb.depot_item_id
+        WHERE di.id = #{depotItemId}
+    </select>
+
 </mapper>

+ 4 - 4
src/main/resources/mapper_xml/TaskStocktakingItemMapper.xml

@@ -20,7 +20,7 @@
         tsi.status AS status
         FROM
         task_stocktaking_item tsi
-        LEFT JOIN jsh_material_extend me ON tsi.material_item_id = me.id
+        LEFT JOIN material_batch me ON tsi.material_item_id = me.id
         LEFT JOIN jsh_material m ON me.material_id = m.id
         LEFT JOIN jsh_material_category mc ON m.category_id = mc.id
         LEFT JOIN jsh_user u ON u.id = tsi.creator
@@ -92,7 +92,7 @@
             tsi.difference_reason AS difference_reason
         FROM
             task_stocktaking_item tsi
-                LEFT JOIN jsh_material_extend me ON tsi.material_item_id = me.id
+                LEFT JOIN material_batch me ON tsi.material_item_id = me.id
                 LEFT JOIN jsh_material m ON me.material_id = m.id
                 LEFT JOIN jsh_material_category mc ON mc.id = m.category_id
                 LEFT JOIN jsh_supplier s ON me.supplier_id = s.id
@@ -112,10 +112,10 @@
             <if test="position != null and position != ''">
                 AND me.position LIKE  CONCAT('%',#{position},'%')
             </if>
-            <if test="isDifference != null and isDifference == '1'">
+            <if test="isDifference != null and isDifference == '1'.toString()">
                 AND tsi.new_inventory = me.inventory
             </if>
-            <if test="isDifference != null and isDifference == '2'">
+            <if test="isDifference != null and isDifference == '2'.toString()">
                 AND tsi.new_inventory != 0
                 AND tsi.new_inventory != me.inventory
             </if>

+ 4 - 1
src/main/resources/mapper_xml/TaskStocktakingMapper.xml

@@ -31,6 +31,9 @@
             <if test="taskStatus != null and taskStatus != 0">
                 AND ts.task_status = #{taskStatus}
             </if>
+            <if test="depotId != null and depotId != 0">
+                AND ts.depot_id = #{depotId}
+            </if>
             ORDER BY
                 ts.create_time DESC,
                 ts.id DESC
@@ -60,7 +63,7 @@
                 LEFT JOIN jsh_user u ON ts.creator = u.id
                 LEFT JOIN task_stocktaking_item tsi ON ts.id = tsi.task_stocktaking_id
         <where>
-            ts.delete_flag = 0
+            ts.delete_flag = 0 AND tsi.delete_flag = 0
             <if test="number != null and number != ''">
                 AND (ts.number LIKE CONCAT('%',#{number},'%') OR ts.task_name LIKE CONCAT('%',#{number},'%'))
             </if>

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