Browse Source

[fix] 工程管理

修改bom的前端列表的查询条件,去掉params
修改bom的实体类,toString方法错误问题
bom前端新增反向BOM按钮和方法
BOM后端新增反向bom查询接口,实现,更加前端传入的函数,查询其本身是否为BOM,如果是则收集,如果不是,按照一定条件继续向上查找,把查找到的bom数据都收集起来,直到没有父阶为止,并且使用set集合,去掉重重复的数据,自定义封装分页查询函数
新增 反向BOM查询方法,查询函数的物料号、bom号等都为精确查询
dev
liuxiaoxu 2 months ago
parent
commit
8728ffc397
  1. 20
      ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java
  2. 5
      ruoyi-admin/src/main/java/com/ruoyi/erp/domain/ErpBomVo.java
  3. 5
      ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java
  4. 8
      ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java
  5. 212
      ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java
  6. 63
      ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml
  7. 93
      ruoyi-admin/src/main/resources/templates/erp/bom/bom.html
  8. 1
      ruoyi-admin/src/main/resources/templates/erp/material/material.html

20
ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java

@ -77,6 +77,7 @@ public class ErpBomController extends BaseController
@ResponseBody
public TableDataInfo list(ErpBomVo erpBomVo,HttpServletRequest request)
{
erpBomVo.setParentId(0L);
SysUser curUser = ShiroUtils.getSysUser();
Long userId = curUser.getUserId();
Set<String> roleKeys = roleService.selectRoleKeys(userId);
@ -88,21 +89,10 @@ public class ErpBomController extends BaseController
@RequiresPermissions("erp:bom:list")
@PostMapping("/reverseList")
@ResponseBody
public TableDataInfo selectErpBomVoReverse(ErpBomVo erpBomVo,HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
String materialNo = String.valueOf(request.getSession().getAttribute("materialNo"));
map.put("materialNo", materialNo);
List<ErpBomVo> materialList = erpBomService.selectErpBomByMaterialNos(erpBomVo.getMaterialNo());
//将返回结果根据父节点进行排序
List<Long> parentIds = erpBomService.getAllParentIds(materialList);
Map<String, Object> map2 = new HashMap<>();
map2.put("parentIds", parentIds);
//查询所有上述父节点的值
List<ErpBomVo> list1 = erpBomService.selectSubBomsByParentMaterialNo(map2);
//转换为页面需要的格式数据
startPage();
List<ErpBomVo> list = erpBomService.selectErpBomListReverse(list1);
public TableDataInfo selectErpBomVoReverse(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
ErpBomVo erpBomVo, HttpServletRequest request) {
List<ErpBomVo> list = erpBomService.selectReverseErpBomList(erpBomVo, pageNum, pageSize);
return getDataTable(list);
}

5
ruoyi-admin/src/main/java/com/ruoyi/erp/domain/ErpBomVo.java

@ -107,7 +107,7 @@ public class ErpBomVo extends ErpBom{
@Override
public String toString() {
return "ErpMaterialVo{" +
return "ErpBomVo{" +
"applyUserName='" + applyUserName + '\'' +
", taskId='" + taskId + '\'' +
", taskName='" + taskName + '\'' +
@ -117,7 +117,6 @@ public class ErpBomVo extends ErpBom{
", todoUserId='" + todoUserId + '\'' +
", instanceTypeName='" + instanceTypeName + '\'' +
", keyword='" + keyword + '\'' +
"} " + super.toString();
'}';
}
}

5
ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java

@ -28,6 +28,11 @@ public interface ErpBomMapper
public List<ErpBomVo> selectErpBomList(ErpBomVo erpBomVo);
/**
* 反向BOM查询
* */
public List<ErpBomVo> selectReverseErpBomList(ErpBomVo erpBomVo);
/**
* 查询bom列表
*

8
ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java

@ -54,9 +54,6 @@ public interface IErpBomService
void collectParentIdsRecursively(List<Long> parents, Long currentId);
List<ErpBomVo> selectErpBomListReverse(List<ErpBomVo> erpBomVoList);
List<ErpBomVo> selectErpBomByMaterialNos(String materialNo);
List<ErpBomVo> selectErpBomlist();
@ -135,4 +132,9 @@ public interface IErpBomService
ErpBom selectErpBomByOneMaterialNo(String materialNo);
List<ErpBomVo> selectSubBomsByParentMaterialNo(Map<String, Object> params);
/**
* 查询反向BOM列表
* */
List<ErpBomVo> selectReverseErpBomList(ErpBomVo erpBomVo,Integer pageNum,Integer pageSize);
}

212
ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java

@ -1,6 +1,8 @@
package com.ruoyi.erp.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
@ -32,8 +34,11 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.*;
import java.util.stream.Collectors;
/**
* bomService业务层处理
@ -369,55 +374,184 @@ private ISysAttachService attachService;
}
}
}
/**
* 查询反向 BOM 列表并自动获取分页后的结果
*/
@Override
public List<ErpBomVo> selectErpBomListReverse(List<ErpBomVo> erpBomVoList)
{
List<ErpBomVo> returnList = new ArrayList<>();
for (ErpBomVo bomVo: erpBomVoList) {
SysUser sysUser = userMapper.selectUserByLoginName(bomVo.getCreateBy());
if (sysUser != null) {
bomVo.setCreateUserName(sysUser.getUserName());
public Page<ErpBomVo> selectReverseErpBomList(ErpBomVo erpBomVo, Integer pageNum, Integer pageSize) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 执行查询并自动获取分页后的结果
List<ErpBomVo> allBoms = erpBomMapper.selectReverseErpBomList(erpBomVo);
PageInfo<ErpBomVo> pageInfo = new PageInfo<>(allBoms);
// 创建一个映射来存储 BOM 和它的直接子项
Map<Long, ErpBomVo> bomMap = allBoms.stream()
.collect(Collectors.toMap(ErpBomVo::getId, bom -> bom));
// 使用 Set 来防止重复添加和避免无限循环
Set<Long> visited = new HashSet<>();
// 构建返回的结果列表
List<ErpBomVo> resultList = new ArrayList<>();
for (ErpBomVo bom : allBoms) {
if (!visited.contains(bom.getId())) {
ErpBomVo topParent = findTopMostParentBom(bom, bomMap, visited);
if (topParent != null && !resultList.contains(topParent)) {
resultList.add(topParent);
}
}
SysUser sysUser2 = userMapper.selectUserByLoginName(bomVo.getApplyUser());
if (sysUser2 != null) {
bomVo.setApplyUserName(sysUser2.getUserName());
}
// 对结果进行用户信息、任务状态等附加信息设置
for (ErpBomVo bomVo : resultList) {
setAdditionalInfo(bomVo);
}
// 创建一个新的分页对象来封装过滤后的结果
Page<ErpBomVo> returnPage = new Page<>(pageNum, pageSize);
returnPage.addAll(resultList);
returnPage.setTotal(pageInfo.getTotal()); // 设置总记录数
return returnPage;
}
/**
* 查找最顶层的 BOM即使不在初始 bomMap 中也会尝试查找
*/
private ErpBomVo findTopMostParentBom(ErpBomVo bom, Map<Long, ErpBomVo> bomMap, Set<Long> visited) {
Long currentId = bom.getId();
ErpBomVo currentBom = bomMap.get(currentId);
if (currentBom == null) {
// 如果当前 BOM 不在 bomMap 中,则尝试从数据库中加载
currentBom = erpBomMapper.selectErpBomById(currentId);
if (currentBom != null) {
bomMap.put(currentId, currentBom); // 将新找到的 BOM 添加到 bomMap 中
} else {
return null; // 如果找不到对应的 BOM,则停止查找
}
String instanceId = bomVo.getInstanceId();
// 当前环节
if (StringUtils.isNotBlank(instanceId)) {
List<Task> taskList = taskService.createTaskQuery()
.processInstanceId(instanceId)
// .singleResult();
.list(); // 例如请假会签,会同时拥有多个任务
if (!org.springframework.util.CollectionUtils.isEmpty(taskList)) {
TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);
String taskId = task.getId();
bomVo.setTaskId(taskId);
// 设置待办用户
List<String> todoUserList = todoItemMapper.selectUndealTodoUserList(taskId);
if(!org.springframework.util.CollectionUtils.isEmpty(taskList)){
bomVo.setTodoUserId(String.join(",",todoUserList));
}
if (task.getSuspensionState() == 2) {
bomVo.setTaskName("已挂起");
bomVo.setSuspendState("2");
} else {
bomVo.setTaskName(task.getName());
bomVo.setSuspendState("1");
}
}
// 首先找到0阶 BOM
ErpBomVo zeroLevelBom = findTopZeroLevelBom(currentBom, bomMap, visited);
if (zeroLevelBom == null) {
return null;
}
// 然后检查该0阶 BOM 是否为其他 BOM 的子项,如果是,继续向上追溯
ErpBomVo topParent = traceToTopParent(zeroLevelBom, bomMap, visited);
return topParent != null ? topParent : zeroLevelBom;
}
/**
* 查找最顶层的0阶 BOM即使不在初始 bomMap 中也会尝试查找
*/
private ErpBomVo findTopZeroLevelBom(ErpBomVo bom, Map<Long, ErpBomVo> bomMap, Set<Long> visited) {
Long currentId = bom.getId();
while (currentId != null && !visited.contains(currentId)) {
visited.add(currentId);
ErpBomVo currentBom = bomMap.get(currentId);
if (currentBom == null) {
// 如果当前 BOM 不在 bomMap 中,则尝试从数据库中加载
currentBom = erpBomMapper.selectErpBomById(currentId);
if (currentBom != null) {
bomMap.put(currentId, currentBom); // 将新找到的 BOM 添加到 bomMap 中
} else {
// 已办结或者已撤销
bomVo.setTaskName("已结束");
break; // 如果找不到对应的 BOM,则停止查找
}
}
if (currentBom != null && StringUtils.isNotEmpty(currentBom.getBomNo()) && (currentBom.getLevel() == null || currentBom.getLevel() != 1)) {
return currentBom; // 满足条件,返回当前 BOM
}
currentId = currentBom != null ? currentBom.getParentId() : null;
}
return null;
}
/**
* 追溯到最顶级的父级 BOM
*/
private ErpBomVo traceToTopParent(ErpBomVo bom, Map<Long, ErpBomVo> bomMap, Set<Long> visited) {
Long parentId = bom.getParentId();
while (parentId != null && !visited.contains(parentId)) {
visited.add(parentId);
ErpBomVo parentBom = bomMap.get(parentId);
if (parentBom == null) {
// 如果父级 BOM 不在 bomMap 中,则尝试从数据库中加载
parentBom = erpBomMapper.selectErpBomById(parentId);
if (parentBom != null) {
bomMap.put(parentId, parentBom); // 将新找到的 BOM 添加到 bomMap 中
} else {
break; // 如果找不到对应的父级 BOM,则停止查找
}
}
if (parentBom != null) {
bom = parentBom;
parentId = parentBom.getParentId();
} else {
bomVo.setTaskName("未启动");
break;
}
}
return bom;
}
/**
* 设置附加信息用户信息任务状态等
*/
private void setAdditionalInfo(ErpBomVo bomVo) {
SysUser sysUser = userMapper.selectUserByLoginName(bomVo.getCreateBy());
if (sysUser != null) {
bomVo.setCreateUserName(sysUser.getUserName());
}
SysUser sysUser2 = userMapper.selectUserByLoginName(bomVo.getApplyUser());
if (sysUser2 != null) {
bomVo.setApplyUserName(sysUser2.getUserName());
}
String instanceId = bomVo.getInstanceId();
// 当前环节
if (StringUtils.isNotBlank(instanceId)) {
List<Task> taskList = taskService.createTaskQuery()
.processInstanceId(instanceId)
.list();
if (!org.springframework.util.CollectionUtils.isEmpty(taskList)) {
TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);
String taskId = task.getId();
bomVo.setTaskId(taskId);
// 设置待办用户
List<String> todoUserList = todoItemMapper.selectUndealTodoUserList(taskId);
if(!org.springframework.util.CollectionUtils.isEmpty(todoUserList)){
bomVo.setTodoUserId(String.join(",",todoUserList));
}
if (task.getSuspensionState() == 2) {
bomVo.setTaskName("已挂起");
bomVo.setSuspendState("2");
} else {
bomVo.setTaskName(task.getName());
bomVo.setSuspendState("1");
}
} else {
// 已办结或者已撤销
bomVo.setTaskName("已结束");
}
} else {
bomVo.setTaskName("未启动");
}
if (bomVo.getAuditStatus() != null) {
if ("1".equals(bomVo.getAuditStatus())) {
bomVo.setTaskName("审核通过");
} else if ("2".equals(bomVo.getAuditStatus())) {
bomVo.setTaskName("审核拒绝");
}
returnList.add(bomVo);
}
Integer total = erpBomVoList.size();
return returnList;
}
@Override
public List<ErpBomVo> selectErpBomByMaterialNos(String materialNo) {
return erpBomMapper.selectErpBomByMaterialNos(materialNo);

63
ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml

@ -117,10 +117,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="createBy != null and createBy != ''"> and erp.create_by = #{createBy}</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''"> and erp.create_time between #{params.beginCreateTime} and #{params.endCreateTime}</if>
<if test="params.materialNo != null and params.materialNo != ''"> and erp.material_no like concat('%', #{params.materialNo}, '%')</if>
<if test="params.bomNo != null and params.bomNo != ''"> and erp.bom_no like concat('%', #{params.bomNo}, '%')</if>
<if test="materialNo != null and materialNo != ''"> and erp.material_no = #{materialNo}</if>
<if test="bomNo != null and bomNo != ''"> and erp.bom_no = #{bomNo}</if>
<if test="materialNo != null and materialNo != ''"> and erp.material_no like concat('%', #{materialNo}, '%')</if>
<if test="bomNo != null and bomNo != ''"> and erp.bom_no like concat('%', #{bomNo}, '%')</if>
<!-- <if test="materialNo != null and materialNo != ''"> and erp.material_no = #{materialNo}</if>-->
<!-- <if test="bomNo != null and bomNo != ''"> and erp.bom_no = #{bomNo}</if>-->
<if test="materialName != null and materialName != ''"> and erp.material_name like concat('%', #{materialName}, '%')</if>
<if test="auditStatus != null and auditStatus != ''"> and erp.audit_status = #{auditStatus}</if>
<if test="useStatus != null and useStatus != ''"> and erp.use_status = #{useStatus}</if>
@ -157,6 +157,61 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
order by erp.audit_status asc, erp.create_time desc
</select>
<select id="selectReverseErpBomList" parameterType="ErpBomVo" resultMap="ErpBomResult">
select erp.id, erp.del_flag, erp.create_by, erp.create_time, erp.update_by, erp.update_time
, erp.remark,erp.bom_no,erp.material_no,erp.material_name, erp.audit_status, erp.use_status
, erp.material_type, erp.process_method,erp.unit, erp.material_model, erp.brand, erp.`describe`,erp.warehouseDept,erp.engineer,
erp.use_num,erp.loss_rate, erp.parent_id, erp.`level`, erp.sort_no, erp.instance_id, erp.file_code,
erp.instance_type, processDict.dict_label as instance_type_name, erp.submit_instance_id,
erp.cancel_instance_id, erp.restore_instance_id,erp.apply_title,erp.apply_user,erp.apply_time
, file.url as photo_url,cate.name as material_type_name from erp_bom as erp
left join (
select id,material_no,material_name from erp_material
) erp_material
on erp.material_no = erp_material.material_no
left join(
select dict_value,dict_label from sys_dict_data
where dict_type = 'processType'
) processDict
on erp.instance_type = processDict.dict_value
left join (
select code,name from sys_category
where parent_id in(
select id from sys_category
where parent_id = (select id from sys_category where code = 'materialType') )
) cate
on erp.material_type = cate.code
left join (
select att.rel_id,file.url,min(file.create_time) as create_time from sys_attach as att
left join sys_attach_file as file
on att.id = file.attach_id
where att.source_type = 'erpMaterial' and att.source_sub_type = 'photo'
group by att.rel_id
) file
on erp_material.id = file.rel_id
<where>
<if test="createBy != null and createBy != ''"> and erp.create_by = #{createBy}</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''"> and erp.create_time between #{params.beginCreateTime} and #{params.endCreateTime}</if>
<if test="materialNo != null and materialNo != ''"> and erp.material_no = #{materialNo}</if>
<if test="bomNo != null and bomNo != ''"> and erp.bom_no = #{bomNo}</if>
<if test="materialName != null and materialName != ''"> and erp.material_name = #{materialName}</if>
<if test="auditStatus != null and auditStatus != ''"> and erp.audit_status = #{auditStatus}</if>
<if test="useStatus != null and useStatus != ''"> and erp.use_status = #{useStatus}</if>
<if test="materialType != null and materialType != ''"> and erp.material_type = #{materialType}</if>
<if test="processMethod != null and processMethod != ''"> and erp.process_method = #{processMethod}</if>
<if test="engineer != null and engineer != ''"> and erp.engineer = #{engineer}</if>
<if test="parentId != null "> and erp.parent_id = #{parentId}</if>
<if test="level != null "> and erp.level = #{level}</if>
<if test="sortNo != null "> and erp.sort_no = #{sortNo}</if>
</where>
order by erp.audit_status asc, erp.create_time desc
</select>
<select id="selectErpBomList1" resultMap="ErpBomResult">
select bom_no, id, create_by, create_time, update_by, update_time, remark,
material_no, material_name, material_type, process_method, unit, material_model,

93
ruoyi-admin/src/main/resources/templates/erp/bom/bom.html

@ -18,15 +18,15 @@
<ul>
<li>
<label>料号:</label>
<input type="text" id="selectMaterialNo" name="params[materialNo]"/>
<input type="text" name="materialNo"/>
</li>
<li>
<label>bom号:</label>
<input type="text" id="selectBomNo" name="params[bomNo]"/>
<input type="text" name="bomNo"/>
</li>
<li>
<label>物料名称:</label>
<input type="text" id="selectMaterialName" name="materialName"/>
<input type="text" name="materialName"/>
</li>
<li>
<label>物料类型:</label>
@ -76,12 +76,10 @@
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endCreateTime]"/>
</li>
<!--默认查询层级0-->
<input type="text" name="parentId" value="0" hidden/>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
<a class="btn btn-primary btn-rounded btn-sm" onclick="seachReverseBom()"><i class="fa fa-search"></i>反向BOM</a>
<a class="btn btn-primary btn-rounded btn-sm" onclick="searchReverseBom()"><i class="fa fa-search"></i>反向BOM</a>
</li>
</ul>
</div>
@ -748,22 +746,27 @@
}
});
}
function seachReverseBom(){
var url = prefix + '/reverseList';
//将获取的page类型数据放入bootstarpTable中
// 反向BOM搜索函数
function searchReverseBom() {
var formData = $('#formId').serializeArray(); // 获取表单数据并序列化为数组
// 获取当前表格的分页信息
var tableOptions = $("#bootstrap-table").bootstrapTable('getOptions');
formData.push({name: 'pageNum', value: tableOptions.pageNumber});
formData.push({name: 'pageSize', value: tableOptions.pageSize});
$.ajax({
type: "POST",
url: url,
data: {
'materialNo':$("#selectMaterialNo").val(),
'materialName':$("#selectMaterialName").val()
},
url: prefix + '/reverseList',
data: $.param(formData), // 将表单数据转换为字符串格式
contentType: "application/x-www-form-urlencoded", // 设置请求的内容类型
success: function (result) {
if (result.code == 0) {
$("#bootstrap-table").bootstrapTable('destroy');
$("#bootstrap-table").bootstrapTable( 'load',result.rows);
// 使用 bootstrap-table 的 load 方法更新表格数据
$("#bootstrap-table").bootstrapTable('load', result.rows);
// 更新分页信息(如果需要)
$("#bootstrap-table").bootstrapTable('load', { total: result.total-1 });
}
}
},
});
}
// 导出
@ -822,62 +825,6 @@
});
}
};
// 导入
// function importExcel(formId, width, height) {
// table.set();
// var currentId = $.common.isEmpty(formId) ? 'importTpl' : formId;
// var _width = $.common.isEmpty(width) ? "400" : width;
// var _height = $.common.isEmpty(height) ? "230" : height;
// layer.open({
// type: 1,
// area: [_width + 'px', _height + 'px'],
// fix: false,
// // 不固定
// maxmin: true,
// shade: 0.3,
// title: '导入' + table.options.modalName + '数据',
// content: $('#' + currentId).html(),
// btn: ['<i class="fa fa-check"></i> 导入', '<i class="fa fa-remove"></i> 取消'],
// // 弹层外区域关闭
// shadeClose: true,
// btn1: function(index, layero){
// var file = layero.find('#file').val();
// if (file == '' || (!$.common.endWith(file, '.xls') && !$.common.endWith(file, '.xlsx'))) {
// $.modal.msgWarning("请选择后缀为 “xls”或“xlsx”的文件。");
// return false;
// }
// var index = layer.load(2, {shade: false});
// $.modal.disable();
//
// // 获取CheckBox的状态
// var updateSupport = layero.find('#updateSupport').is(':checked');
//
// var formData = new FormData(layero.find('form')[0]);
// formData.append('updateSupport', updateSupport); // 添加CheckBox的状态到FormData
//
// $.ajax({
// url: table.options.importUrl,
// data: formData,
// cache: false,
// contentType: false,
// processData: false,
// type: 'POST',
// success: function (result) {
// layer.close(index);
// $.modal.enable();
//
// $.modal.closeAll();
// $.modal.alertSuccess(result);
// $.table.refresh();
// },
// error: function (result){
// layer.close(index);
// $.modal.alertError(result);
// }
// });
// }
// });
// }
</script>
</body>
<!-- 导入区域 -->

1
ruoyi-admin/src/main/resources/templates/erp/material/material.html

@ -342,7 +342,6 @@
$.modal.open("作废", url);
})
}
</script>
</body>
</html>
Loading…
Cancel
Save