Browse Source

[feat]采购管理

修复添加采购入库单前端页面,物料类型不显示值的问题
新增采购入库单详情页面,新增详情按钮和方法
采购入库单子表新增 通过采购入库单号查询采购入库单子表方法
采购入库单新增 保存采购入库单详情方法
采购入库单子表新增 根据采购入库单号查询采购入库单子表方法
采购入库单Controller1新增 采购入库单详情接口。新增修改保存采购入库单详情接口,新增查询采购入库单详情物料信息接口
dev
liuxiaoxu 5 days ago
parent
commit
6a18a33ee7
  1. 47
      ruoyi-admin/src/main/java/com/ruoyi/purchase/controller/PurchaseStorageController.java
  2. 5
      ruoyi-admin/src/main/java/com/ruoyi/purchase/mapper/PurchaseStorageChildMapper.java
  3. 5
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseStorageChildService.java
  4. 6
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseStorageService.java
  5. 11
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseStorageChildServiceImpl.java
  6. 12
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseStorageServiceImpl.java
  7. 5
      ruoyi-admin/src/main/resources/mapper/purchase/PurchaseStorageChildMapper.xml
  8. 2
      ruoyi-admin/src/main/resources/templates/purchase/purchaseOrder/addPurchaseStorage.html
  9. 302
      ruoyi-admin/src/main/resources/templates/purchase/purchaseStorage/detail.html
  10. 8
      ruoyi-admin/src/main/resources/templates/purchase/purchaseStorage/purchaseStorage.html

47
ruoyi-admin/src/main/java/com/ruoyi/purchase/controller/PurchaseStorageController.java

@ -1,6 +1,9 @@
package com.ruoyi.purchase.controller;
import java.util.List;
import com.ruoyi.purchase.domain.PurchaseStorageChild;
import com.ruoyi.purchase.service.IPurchaseStorageChildService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -34,6 +37,10 @@ public class PurchaseStorageController extends BaseController
@Autowired
private IPurchaseStorageService purchaseStorageService;
@Autowired
private IPurchaseStorageChildService purchaseStorageChildService;
@RequiresPermissions("purchase:purchaseStorage:view")
@GetMapping()
public String purchaseStorage()
@ -112,6 +119,46 @@ public class PurchaseStorageController extends BaseController
return toAjax(purchaseStorageService.updatePurchaseStorage(purchaseStorage));
}
/**
* 采购入库单详情
*
* */
@GetMapping("/detail/{purchaseStorageId}")
public String detail(@PathVariable("purchaseStorageId") Long purchaseStorageId, ModelMap mmap)
{
PurchaseStorage purchaseStorage = purchaseStorageService.selectPurchaseStorageById(purchaseStorageId);
mmap.put("purchaseStorage", purchaseStorage);
return prefix + "/detail";
}
/**
* 修改保存采购入库单详情
*/
@Log(title = "采购入库单", businessType = BusinessType.UPDATE)
@PostMapping("/detail")
@ResponseBody
public AjaxResult detailSave(PurchaseStorage purchaseStorage)
{
return toAjax(purchaseStorageService.detailPurchaseStorage(purchaseStorage));
}
/**
* 查询采购入库单详情物料信息
*/
@PostMapping("/selectStorageChildMaterialList")
@ResponseBody
public TableDataInfo selectStorageChildMaterialList(PurchaseStorage purchaseStorage)
{
startPage();
String warehouseStorageCode = purchaseStorage.getWarehouseStorageCode();
List<PurchaseStorageChild> list = purchaseStorageChildService.selectPurchaseStorageChildListByCode(warehouseStorageCode);
return getDataTable(list);
}
/**
* 删除采购入库单
*/

5
ruoyi-admin/src/main/java/com/ruoyi/purchase/mapper/PurchaseStorageChildMapper.java

@ -79,4 +79,9 @@ public interface PurchaseStorageChildMapper
* 批量新增采购入库单子表
* */
int insertBatchPurchaseStorageChild(List<PurchaseStorageChild> purchaseStorageChildren);
/**
* 根据采购入库单号查询采购入库单子表
* */
List<PurchaseStorageChild> selectPurchaseStorageChildListByCode(String warehouseStorageCode);
}

5
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseStorageChildService.java

@ -72,4 +72,9 @@ public interface IPurchaseStorageChildService
* @return
*/
int restorePurchaseStorageChildById(Long purchaseStorageChildId);
/**
* 通过采购入库单号查询采购入库单子表
* */
List<PurchaseStorageChild> selectPurchaseStorageChildListByCode(String warehouseStorageCode);
}

6
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseStorageService.java

@ -72,4 +72,10 @@ public interface IPurchaseStorageService
* @return
*/
int restorePurchaseStorageById(Long purchaseStorageId);
/**
* 保存采购入库单详情
*
* */
int detailPurchaseStorage(PurchaseStorage purchaseStorage);
}

11
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseStorageChildServiceImpl.java

@ -46,6 +46,17 @@ public class PurchaseStorageChildServiceImpl implements IPurchaseStorageChildSer
return purchaseStorageChildMapper.selectPurchaseStorageChildList(purchaseStorageChild);
}
/**
* 根据采购入库单号查询采购入库单子表列表
*
* @param warehouseStorageCode 采购入库单号
* @return 采购入库单子表
*/
@Override
public List<PurchaseStorageChild> selectPurchaseStorageChildListByCode(String warehouseStorageCode) {
return purchaseStorageChildMapper.selectPurchaseStorageChildListByCode(warehouseStorageCode);
}
/**
* 新增采购入库单子表
*

12
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseStorageServiceImpl.java

@ -76,6 +76,18 @@ public class PurchaseStorageServiceImpl implements IPurchaseStorageService
return purchaseStorageMapper.updatePurchaseStorage(purchaseStorage);
}
/**
* 详情采购入库单
*
* @param purchaseStorage 采购入库单
* @return 结果
*/
@Override
public int detailPurchaseStorage(PurchaseStorage purchaseStorage) {
return 1;
}
/**
* 删除采购入库单对象
*

5
ruoyi-admin/src/main/resources/mapper/purchase/PurchaseStorageChildMapper.xml

@ -60,6 +60,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where purchase_storage_child_id = #{purchaseStorageChildId}
</select>
<select id="selectPurchaseStorageChildListByCode" parameterType="String" resultMap="PurchaseStorageChildResult">
<include refid="selectPurchaseStorageChildVo"/>
where warehouse_storage_code = #{warehouseStorageCode}
</select>
<insert id="insertPurchaseStorageChild" parameterType="PurchaseStorageChild" useGeneratedKeys="true" keyProperty="purchaseStorageChildId">
insert into purchase_storage_child
<trim prefix="(" suffix=")" suffixOverrides=",">

2
ruoyi-admin/src/main/resources/templates/purchase/purchaseOrder/addPurchaseStorage.html

@ -176,7 +176,7 @@
title: '物料类型',
field: 'materialType',
formatter: function (value,row, index) {
$.table.selectCategoryLabel(materialTypeDatas, value)
return $.table.selectCategoryLabel(materialTypeDatas, value)
}
},
{

302
ruoyi-admin/src/main/resources/templates/purchase/purchaseStorage/detail.html

@ -3,194 +3,115 @@
<head>
<th:block th:include="include :: header('采购入库单详情')" />
<th:block th:include="include :: datetimepicker-css" />
<style>
.supplier-value span {
margin-right: 10px;
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-purchaseStorage-detail" th:object="${warehouseStorageOrder}">
<input name="warehouseStorageId" th:field="*{warehouseStorageId}" type="hidden">
<form class="form-horizontal m" id="form-purchaseStorage-detail" th:object="${purchaseStorage}">
<input type="hidden" name="purchaseStorageId" th:field="*{purchaseStorageId}"/>
<div class="form-group">
<label class="col-sm-3 control-label">入库单号:</label>
<div class="col-sm-8">
<input name="warehouseStorageCode" th:field="*{warehouseStorageCode}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">采购单号:</label>
<label class="col-sm-3 control-label ">供应商ID</label>
<div class="col-sm-8">
<input name="relatedOrderCode" th:field="*{relatedOrderCode}" class="form-control" type="text" readonly>
<input name="supplierCode" th:field="*{supplierCode}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">入库类型</label>
<label class="col-sm-3 control-label is-required">供应商名称</label>
<div class="col-sm-8">
<select name="warehouseStorageType" class="form-control m-b" th:with="type=${@dict.getType('warehouse_storage_type')}" disabled>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{warehouseStorageType}"></option>
</select>
<input name="supplierName" th:field="*{supplierName}" class="form-control" type="text" required readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">到货时间:</label>
<label class="col-sm-3 control-label">到货时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="arrivedTime" th:value="${#dates.format(warehouseStorageOrder.arrivedTime, 'yyyy-MM-dd')}" class="form-control" placeholder="yyyy-MM-dd" type="text" readonly disabled>
<input name="arrivedTime" class="form-control" placeholder="yyyy-MM-dd" type="text" readonly>
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="container">
<!--供应商物料相关-->
<div class="row">
<div class="col-sm-12" id="tablesContainer">
<!-- 表格将在这里动态生成 -->
</div>
</form>
<!--物料信息-->
<div class="container">
<div class="row">
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</form>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: bootstrap-table-editable-js" />
<script th:inline="javascript">
var prefix = ctx + "purchase/purchaseStorage";
var warehouseStorageCode = [[${warehouseStorageOrder.warehouseStorageCode}]];
var warehouseCode = [[${warehouseStorageOrder.warehouseCode}]];
var processMethodDatas = [[${@dict.getType('processMethod')}]];
var materialUnitDatas = [[${@dict.getType('sys_unit_class')}]];
var materialTypeDatas = [[${@category.getChildByCode('materialType')}]];
var warehouseDeptDatas = [[${@dict.getType('warehouseDept')}]];
var prefix = ctx + "purchase/purchaseStorage";
$("#form-purchaseStorage-detail").validate({
focusCleanup: true
});
var purchaseStorage = [[${purchaseStorage}]];
$("#form-purchaseStorage-detail").validate({ focusCleanup: true});
//生成的不同table的id集合
var tableDatas = [];
function submitHandler() {
const storageOrderData = $("#form-purchaseStorage-detail").serializeArray().reduce((obj, item) => {
obj[item.name] = item.value;
return obj;
}, {});
// 初始化一个数组用于存放所有表格的数据
let allMaterialDataList = [];
for(let i in tableDatas){
$('#' + tableDatas[i]).each(function() {
const tableData = $(this).bootstrapTable('getData');
console.log(JSON.stringify(tableData));
// 将表数据转换成与qualityReportData格式一致的数组
var materialDataList = tableData.map(function (item) {
// 根据实际字段名调整
return {
"supplierCode": item.supplierCode,
"materialNo": item.materialNo,
"materialName": item.materialName,
"materialType": item.materialType,
"materialPhotourl": item.materialPhotourl,
"materialDescribe": item.materialDescribe,
"materialBrand": item.materialBrand,
"materialUnit": item.materialUnit,
"materialProcessMethod": item.materialProcessMethod,
"notifyHasArrivedNum": item.notifyHasArrivedNum,
"actualHasArrivedNum": item.actualHasArrivedNum,
"temporaryHasQualifiedNum": item.temporaryHasQualifiedNum,
"hasStorageNum": item.hasStorageNum,
"notifyArriveNum": item.notifyArriveNum,
"actualArriveNum": item.actualArriveNum,
"temporaryQualifiedNum": item.temporaryQualifiedNum,
"temporaryRemark": item.temporaryRemark,
"temporaryReportUrl": item.temporaryReportUrl,
"storageNum": item.storageNum,
"storageLocation": item.storageLocation,
// ...其他字段
};
});
allMaterialDataList = allMaterialDataList.concat(materialDataList);
});
if ($.validate.form()) {
$.operate.save(prefix + "/detail", $('#form-purchaseStorage-detail').serialize());
}
const combinedData = Object.assign({}, storageOrderData, {
warehouseStorageOrderDetailList: allMaterialDataList
});
// 合并表单数据和表格数据
// const combinedData = Object.assign({}, ...complaintNoticeData.array(item => ({ [item.name]: item.value })), ...materialData);
console.log(combinedData)
// 使用 JSON.stringify() 序列化数据
const jsonData = JSON.stringify(combinedData);
// 发送 AJAX 请求到后端接口
$.operate.saveJson(prefix + "/detail", jsonData);
}
$("input[name='arrivedTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
$("input[name='deliveryInspectionTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
//物料信息展示列表
$(function() {
// 假设qualityOrderCode已经定义或者可以通过某种方式获取到
var warehouseStorageCode = [[${warehouseStorageOrder.warehouseStorageCode}]]; // 这里需要实际赋值,比如从前端某个地方读取
$.getJSON(prefix + "/storagePurchaseDetailList?warehouseStorageCode=" + warehouseStorageCode, function(data) {
for (var supplierCode in data) {
if (data.hasOwnProperty(supplierCode)) {
var supplierData = data[supplierCode];
createTableForSupplier(supplierCode, supplierData);
}
}
});
});
function createTableForSupplier(supplierCode, supplierData) {
var tableId = 'bootstrap-table-' + supplierCode.replace(/[^a-z0-9]/gi, '_').toLowerCase();
tableDatas.push(tableId);
var $tableWrapper = $('<div class="table-responsive mt-3"></div>');
// 确保supplierData至少有一条记录,并从中提取供应商详细信息
var supplierInfo = supplierData.length > 0 ? supplierData[0] : {}; // 默认为空对象,以防数据不存在
// 构建含有额外供应商信息的标题字符串
var headerTitle ='供应商'+'</br>'+supplierCode + ' - ' + (supplierInfo.supplierName || 'N/A');
var $header = $('<h4>' + headerTitle + '</h4>');
var $table = $('<table id="' + tableId + '" class="table table-striped table-bordered"></table>');
$table.bootstrapTable({
data: supplierData,
var options = {
modalName: "选择物料",
url: prefix + "/selectStorageChildMaterialList",
queryParams: queryParams,
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
pagination: false, // 设置不分页
columns: [{
checkbox: true
},
{
title: '供应商ID',
field: 'supplierCode',
title: '采购入库单子表id',
field: 'purchaseStorageChildId',
visible: false
},
{
title: '料号',
field: 'materialNo'
}, {
title: '物料名称',
field: 'materialName'
field: 'materialNo',
},
{
title: '物料类型',
field: 'materialType',
formatter: function (value, row, index) {
return $.table.selectDictLabel(materialTypeDatas, value);
}
title: '物料名称',
field: 'materialName',
},
{
title: '物料图片地址',
field: 'materialPhotourl',
},
{
title: '物料描述',
field: 'materialDescribe',
title: '物料型号',
field: 'materialModel',
},
{
title: '物料类型',
field: 'materialType',
formatter: function(value, row, index) {
return $.table.selectCategoryLabel(materialTypeDatas, value);
}
},
{
title: '物料品牌',
@ -199,100 +120,55 @@
{
title: '物料单位',
field: 'materialUnit',
formatter:function (value) {
return $.table.selectDictLabel(materialUnitDatas, value);
}
},
{
title: '物料描述',
field: 'materialDescribe',
},
{
title: '物料加工方式',
field: 'materialProcessMethod',
formatter: function (value, row, index) {
formatter:function (value) {
return $.table.selectDictLabel(processMethodDatas, value);
}
},
{
title: '通知已到货数',
field: 'notifyHasArrivedNum',
title: '物料入库部门',
field: 'materialDeptType',
formatter:function (value) {
return $.table.selectDictLabel(warehouseDeptDatas, value);
}
},
{
title: '已入库数',
field: 'hasStorageNum',
title: '通知已到货数量',
field: 'notifyHasArrivedNum',
},
{
title: '通知到货数',
field: 'notifyArriveNum',
title: '实际到货数量',
field: 'actualArriveNum',
},
]
});
$tableWrapper.append($header).append($table);
$('#tablesContainer').append($tableWrapper);
};
$.table.init(options);
})
function queryParams(params) {
var curParams = {
// 传递参数查询参数
warehouseStorageCode: purchaseStorage.warehouseStorageCode
};
return curParams;
}
//根据仓库ID查询仓库名称
$(document).ready(function() {
// 初始化时默认加载仓库ID列表
loadWarehouseCodes();
// 监听仓库ID下拉框的变化
$('#warehouseCode').on('change', function() {
var selectedWarehouseCode = $(this).val(); // 获取选中的仓库ID
if (selectedWarehouseCode) {
// 发起Ajax请求获取仓库名称
$.ajax({
type: 'GET',
url: ctx +'stock/stockInfo/getStockNameByWarehouseCode/' + selectedWarehouseCode,
dataType: 'json', // 假设返回的数据格式是JSON
success: function(data) {
console.log(data);
// 将获取到的仓库名称填充到输入框
if(data.data == null){
// 如果返回的数据有问题,可以给出提示或处理
$.modal.alertWarning('未能获取到仓库名称!');
}
$('input[name="warehouseName"]').val(data.data.stockname);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('Error:', textStatus, errorThrown);
$.modal.alertWarning('查询仓库名称时发生错误!');
}
});
} else {
// 如果没有选择仓库ID,清空仓库名称输入框
$('input[name="warehouseName"]').val('');
}
});
});
// 加载仓库Id列表函数
function loadWarehouseCodes() {
var url = ctx + 'stock/stockInfo/getAllWarehouseCode';
$.ajax({
type: 'GET', // 请求类型
url: url, // 后端接口URL
dataType: 'json', // 预期服务器返回的数据类型
success: function(data) {
if (data && Array.isArray(data)) {
var selectElement = $('#warehouseCode'); // 获取仓库编号下拉框元素
// 清空下拉框现有选项
selectElement.empty();
// 添加默认选项(如果需要)编辑时不需要添加默认选项
// selectElement.append('<option value="">所有</option>');
// 遍历返回的数据,添加为下拉框的选项
$.each(data, function(index, item) {
// 仓库ID
selectElement.append('<option value="' + item.stockNO + '">' + item.stockNO + '</option>');
});
// $('#warehouseCode').val(stockNO);
} else {
$.modal.errMsg("数据为空");
}
}
});
}
$("input[name='arrivedTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true,
}).datetimepicker("update", new Date());;
</script>
</body>

8
ruoyi-admin/src/main/resources/templates/purchase/purchaseStorage/purchaseStorage.html

@ -263,7 +263,7 @@
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.purchaseStorageId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a href="javascript:void(0)" onclick="detail(\'' + row.purchaseStorageId + '\')"><i class="fa fa-edit"></i>详情</a> ');
var actionLinks = actions.join('');
return $.table.dropdownToggle(actionLinks);
}
@ -271,6 +271,12 @@
};
$.table.init(options);
});
//详情
function detail(purchaseStorageId) {
var url = prefix + "/detail/" + purchaseStorageId;
$.modal.open("详情", url);
}
</script>
</body>
</html>
Loading…
Cancel
Save