问题修改

This commit is contained in:
jiang 2026-01-28 09:57:30 +08:00
parent 9f1896245e
commit f11d76b238
23 changed files with 933 additions and 110 deletions

View File

@ -60,4 +60,10 @@ public class Equipment {
* 所属公司
*/
private String deptId;
private String maStatus;
private String typeId;
}

View File

@ -6,9 +6,12 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.bonus.common.core.text.Convert;
import com.bonus.common.core.utils.ServletUtils;
import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import com.bonus.common.security.utils.SecurityUtils;
@ -19,7 +22,9 @@ import com.bonus.material.devchange.service.MaDevInfoServiceImpl;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.domain.vo.DevMergeVo;
import com.bonus.system.api.domain.SysUser;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
@ -175,12 +180,35 @@ public class MaDevInfoController extends BaseController {
@ApiOperation("导出设备信息Excel")
@PostMapping("/export")
public void export(MaDevInfo o, HttpServletResponse response) throws IOException {
// 1. 查询所有符合条件的数据忽略分页
List<MaDevInfoXlsx> dataList = service.export(o);
com.bonus.common.core.utils.poi.ExcelUtil<MaDevInfoXlsx> util = new ExcelUtil<MaDevInfoXlsx>(MaDevInfoXlsx.class);
util.exportExcel(response, dataList, "装备台账");
List<MaDevInfoXlsx> exportList;
// 1. 从请求中获取分页参数兼容前端GET/POST传参项目通用ServletUtils工具
Integer pageNum = Convert.toInt(ServletUtils.getParameter("pageNum"));
Integer pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"));
// 2. 核心判断分页参数是否有效非空+大于0有效则启动分页
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
startPage(); // 仅当分页参数有效时启动分页查询当前页
}
// 3. 查询数据service层无需修改分页插件自动判断是否分页
List<MaDevInfoXlsx> list = service.export(o);
TableDataInfo dataTable = getDataTable(list);
// 4. 根据分页参数获取对应导出数据
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
// 有有效分页参数 导出当前页取分页后的rows
exportList = (List<MaDevInfoXlsx>) dataTable.getRows();
} else {
// 无分页参数/参数无效 导出全部直接使用全量查询结果
exportList = list;
}
// 5. 项目通用Excel工具导出保持原有逻辑
com.bonus.common.core.utils.poi.ExcelUtil<MaDevInfoXlsx> util = new ExcelUtil<>(MaDevInfoXlsx.class);
util.exportExcel(response, exportList, "装备台账");
}
}

View File

@ -184,8 +184,8 @@ public class MaDevInfoXlsx {
/**
* 资产原值
*/
@Excel(name = "资产原值(元)")
@ApiModelProperty(value = "资产原值(元)")
@Excel(name = "资产原值(元)")
@ApiModelProperty(value = "资产原值(元)")
private BigDecimal originalValue;
/**

View File

@ -4,6 +4,7 @@ import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.material.deptConfig.domain.Equipment;
import com.bonus.material.device.domain.IotDto;
import com.bonus.material.device.domain.vo.IotRecordVo;
import com.bonus.material.device.domain.vo.IotVo;
@ -47,6 +48,7 @@ public class IotMachineController extends BaseController {
/**
* 添加或者修改设备
*
* @param iotDto
* @return
*/
@ -62,11 +64,12 @@ public class IotMachineController extends BaseController {
/**
* 删除设备
*
* @param iotId
* @return
*/
@ApiOperation(value = "删除设备")
@DeleteMapping("/deleteById/{iotId}")
@PostMapping("/deleteById/{iotId}")
public AjaxResult deleteByIds(@PathVariable("iotId") Long iotId) {
log.info("删除设备传参:{}", iotId);
return iotMachineService.deleteById(iotId);
@ -74,6 +77,7 @@ public class IotMachineController extends BaseController {
/**
* 绑定设备
*
* @param iotDto
* @return
*/
@ -86,6 +90,7 @@ public class IotMachineController extends BaseController {
/**
* 解绑设备
*
* @param iotDto
* @return
*/
@ -98,6 +103,7 @@ public class IotMachineController extends BaseController {
/**
* 根据iot设备获取绑定记录分页
*
* @param iotDto
* @return
*/
@ -112,6 +118,7 @@ public class IotMachineController extends BaseController {
/**
* 导出绑定记录
*
* @param response
* @param iotDto
*/
@ -153,4 +160,19 @@ public class IotMachineController extends BaseController {
log.info("报警记录接口:{}", iotDto);
return AjaxResult.success();
}
@ApiOperation("报警记录")
@GetMapping("/getEquipment")
public TableDataInfo getEquipment(Equipment equipment) {
startPage();
List<Equipment> list = iotMachineService.getEquipment(equipment);
return getDataTable(list);
}
@ApiOperation(value = "订单确认--驳回")
@GetMapping("/getCategoryList")
public AjaxResult getCategoryList(String keyWord) {
return iotMachineService.getCategoryList();
}
}

View File

@ -13,37 +13,51 @@ import java.util.Date;
@Data
public class IotDto {
/** iot设备ID */
/**
* iot设备ID
*/
@ApiModelProperty(value = "iot设备ID")
private Long id;
/** iot设备ID */
/**
* iot设备ID
*/
@ApiModelProperty(value = "iot设备ID")
private Long iotId;
/** 类型id */
/**
* 类型id
*/
@ApiModelProperty(value = "类型id")
private Long typeId;
@ApiModelProperty(value = "被绑定机具名称")
private String typeName;
/** 被绑定机具编号 */
/**
* 被绑定机具编号
*/
@ApiModelProperty(value = "被绑定机具编号")
private String maCode;
/** iot设备类型 */
/**
* iot设备类型
*/
@ApiModelProperty(value = "iot设备类型")
private String iotType;
@ApiModelProperty(value = "iot设备名称")
private String iotName;
/** iot设备编码 */
/**
* iot设备编码
*/
@ApiModelProperty(value = "iot设备编码")
private String iotCode;
/** iot设备状态 (0 在线, 1 下线)*/
/**
* iot设备状态 (0 在线 1 下线)
*/
@ApiModelProperty(value = "iot设备状态 (0 在线, 1 下线)")
private int iotStatus;
@ -56,32 +70,54 @@ public class IotDto {
@ApiModelProperty(value = "备注")
private String remark;
/** 创建人 */
/**
* 创建人
*/
@ApiModelProperty(value = "创建人")
private String createBy;
/** 创建时间 */
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/** 更新人 */
/**
* 更新人
*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/** 更新时间 */
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间")
private Date updateTime;
/** 绑定人 */
/**
* 绑定人
*/
@ApiModelProperty(value = "绑定人")
private String binder;
/** 解绑人 */
/**
* 解绑人
*/
@ApiModelProperty(value = "解绑人")
private String unBinder;
/** 关键字 */
/**
* 关键字
*/
@ApiModelProperty(value = "关键字")
private String keyWord;
private String maId;
private String type;
private String proName;
private String maStatus;
}

View File

@ -68,4 +68,12 @@ public class IotVo {
@ApiModelProperty(value = "备注")
private String remark;
private String maId;
private String type;
private String proName;
private String maStatus;
}

View File

@ -1,11 +1,13 @@
package com.bonus.material.device.mapper;
import com.bonus.material.deptConfig.domain.Equipment;
import com.bonus.material.device.domain.IotDto;
import com.bonus.material.device.domain.vo.IotRecordVo;
import com.bonus.material.device.domain.vo.IotVo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
/**
@ -106,4 +108,8 @@ public interface IotMachineMapper {
* @return
*/
List<IotVo> getInfoList(String maCode);
List<Equipment> getEquipment(Equipment equipment);
List<Map<String, Object>> getCategoryList();
}

View File

@ -1,6 +1,7 @@
package com.bonus.material.device.service;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.deptConfig.domain.Equipment;
import com.bonus.material.device.domain.IotDto;
import com.bonus.material.device.domain.vo.IotRecordVo;
import com.bonus.material.device.domain.vo.IotVo;
@ -63,4 +64,7 @@ public interface IotMachineService {
*/
List<IotRecordVo> getRecordList(IotDto iotDto);
List<Equipment> getEquipment(Equipment equipment);
AjaxResult getCategoryList();
}

View File

@ -3,6 +3,7 @@ package com.bonus.material.device.service.impl;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.common.enums.ExceptionEnum;
import com.bonus.material.deptConfig.domain.Equipment;
import com.bonus.material.device.domain.IotDto;
import com.bonus.material.device.domain.vo.IotRecordVo;
import com.bonus.material.device.domain.vo.IotVo;
@ -14,6 +15,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
/**
@ -231,4 +233,21 @@ public class IotMachineServiceImpl implements IotMachineService {
}
return iotMachineMapper.getRecordList(iotDto);
}
/**
* @param equipment
* @return
*/
@Override
public List<Equipment> getEquipment(Equipment equipment) {
return iotMachineMapper.getEquipment(equipment);
}
/**
* @return
*/
@Override
public AjaxResult getCategoryList() {
return AjaxResult.success(iotMachineMapper.getCategoryList());
}
}

View File

@ -0,0 +1,91 @@
package com.bonus.material.menuCollect.controller;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.menuCollect.service.MenuCollectService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 菜单收藏表 控制器
* 匹配项目原有接口风格RestController + 固定前缀 + 注解规范 + 依赖注入方式
*/
@RestController
@RequestMapping("/menuCollect")
public class MenuCollectController extends BaseController {
@Resource
private MenuCollectService menuCollectService;
/**
* 新增菜单收藏
*
* @param menuId 菜单ID
* @return 操作结果
*/
@ApiOperation(value = "新增菜单收藏")
@PostMapping("/add")
public AjaxResult add(@RequestParam Long menuId) {
return menuCollectService.add(menuId);
}
/**
* 取消菜单收藏物理删除匹配表设计要求
*
* @param menuId 菜单ID
* @return 操作结果
*/
@ApiOperation(value = "取消菜单收藏")
@PostMapping("/delete")
public AjaxResult delete(@RequestParam Long menuId) {
return menuCollectService.delete(menuId);
}
/**
* 校验用户是否已收藏某菜单核心查询收藏前置判断
*
* @param menuId 菜单ID
* @return 收藏状态true-已收藏false-未收藏
*/
@ApiOperation(value = "校验菜单收藏状态")
@GetMapping("/checkCollect")
public AjaxResult checkCollect(@RequestParam Long menuId) {
return menuCollectService.checkCollect(menuId);
}
/**
* 查询用户所有收藏菜单
*
* @return 收藏菜单列表
*/
@ApiOperation(value = "查询用户收藏菜单列表")
@GetMapping("/listByUser")
public AjaxResult listByUser() {
return menuCollectService.listByUser();
}
/**
* 统计某菜单的收藏人数
*
* @param menuId 菜单ID
* @return 收藏人数
*/
@ApiOperation(value = "统计菜单收藏人数")
@GetMapping("/countByMenu")
public AjaxResult countByMenu(@RequestParam Long menuId) {
return menuCollectService.countByMenu(menuId);
}
/**
* 批量取消用户所有收藏
*
* @return 操作结果
*/
@ApiOperation(value = "批量取消用户所有收藏")
@PostMapping("/batchDeleteByUser")
public AjaxResult batchDeleteByUser() {
return menuCollectService.batchDeleteByUser();
}
}

View File

@ -0,0 +1,31 @@
package com.bonus.material.menuCollect.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 菜单收藏实体类对应表 sys_menu_collect
* 字段与表完全一致类型匹配 MySQL 5.x 建表语句无冗余字段
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MenuCollect {
private Long id;
private Long userId;
private Long menuId;
private Date collectTime;
private String menuName;
// 最终拼接后的标准路由返回给前端
private String fullRoutePath;
// 新增临时属性 - 菜单原始pathSQL查询结果不返回前端
private String menuPath;
// 新增临时属性 - 菜单父级IDSQL查询结果不返回前端
private Long menuParentId;
}

View File

@ -0,0 +1,60 @@
package com.bonus.material.menuCollect.mapper;
import com.bonus.material.menuCollect.domain.MenuCollect;
import com.bonus.system.api.domain.SysMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 菜单收藏 Mapper 接口操作 sys_menu_collect
* 基于 MyBatis 注解/XML 通用规范参数绑定使用 @Param支持单表核心操作
*/
public interface MenuCollectMapper {
/**
* 新增菜单收藏collect_time 数据库自动填充无需传入
* @param menuCollect 收藏实体仅需 userIdmenuId
* @return 受影响行数
*/
int insertMenuCollect(MenuCollect menuCollect);
/**
* 物理删除指定收藏用户ID+菜单ID 精准删除
* @param userId 用户ID
* @param menuId 菜单ID
* @return 受影响行数
*/
int deleteByUserAndMenu(@Param("userId") Long userId, @Param("menuId") Long menuId);
/**
* 批量物理删除用户所有收藏
* @param userId 用户ID
* @return 受影响行数
*/
int deleteBatchByUserId(@Param("userId") Long userId);
/**
* 校验收藏状态查询是否存在指定用户+菜单的收藏记录
* @param userId 用户ID
* @param menuId 菜单ID
* @return 收藏记录数0=未收藏1=已收藏
*/
int checkCollect(@Param("userId") Long userId, @Param("menuId") Long menuId);
/**
* 根据用户ID查询所有收藏菜单
* @param userId 用户ID
* @return 收藏菜单列表含菜单ID收藏时间等
*/
List<MenuCollect> selectListByUserId(@Param("userId") Long userId);
/**
* 统计指定菜单的收藏人数
* @param menuId 菜单ID
* @return 收藏总人数
*/
int selectCollectCountByMenuId(@Param("menuId") Long menuId);
List<SysMenu> selectAllMenu();
}

View File

@ -0,0 +1,56 @@
package com.bonus.material.menuCollect.service;
import com.bonus.common.core.web.domain.AjaxResult;
/**
* 菜单收藏 业务层接口
*/
public interface MenuCollectService {
/**
* 新增菜单收藏
*
* @param menuId 菜单ID
* @return AjaxResult
*/
AjaxResult add(Long menuId);
/**
* 取消菜单收藏物理删除
*
* @param menuId 菜单ID
* @return AjaxResult
*/
AjaxResult delete(Long menuId);
/**
* 校验用户是否已收藏某菜单
*
* @param menuId 菜单ID
* @return AjaxResult
*/
AjaxResult checkCollect(Long menuId);
/**
* 查询用户所有收藏菜单
*
* @return AjaxResult
*/
AjaxResult listByUser();
/**
* 统计菜单收藏人数
*
* @param menuId 菜单ID
* @return AjaxResult
*/
AjaxResult countByMenu(Long menuId);
/**
* 批量取消用户所有收藏
*
* @return AjaxResult
*/
AjaxResult batchDeleteByUser();
}

View File

@ -0,0 +1,206 @@
package com.bonus.material.menuCollect.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.menuCollect.domain.MenuCollect;
import com.bonus.material.menuCollect.mapper.MenuCollectMapper;
import com.bonus.material.menuCollect.service.MenuCollectService;
import com.bonus.system.api.domain.SysMenu;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 菜单收藏 Service 实现类
* 实现业务逻辑参数校验异常捕获结果封装适配项目原有 AjaxResult 规范
*/
@Service
public class MenuCollectServiceImpl implements MenuCollectService {
// 与原有代码一致使用 @Resource 依赖注入 Mapper
@Resource
private MenuCollectMapper menuCollectMapper;
/**
* 新增菜单收藏
*/
@Override
public AjaxResult add(Long menuId) {
// 1. 参数非空校验基础校验避免空指针
Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
try {
MenuCollect menuCollect = new MenuCollect();
menuCollect.setUserId(userId);
menuCollect.setMenuId(menuId);
// 3. 执行插入
menuCollectMapper.insertMenuCollect(menuCollect);
return AjaxResult.success("收藏成功");
} catch (DuplicateKeyException e) {
// 4. 捕获唯一索引冲突异常重复收藏
return AjaxResult.error("已收藏该菜单,无需重复收藏");
} catch (Exception e) {
// 5. 通用异常捕获保证接口健壮性
e.printStackTrace();
return AjaxResult.error("收藏失败,请稍后重试");
}
}
/**
* 取消菜单收藏物理删除
*/
@Override
public AjaxResult delete(Long menuId) {
// 参数非空校验
Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
try {
// 执行精准删除
int rows = menuCollectMapper.deleteByUserAndMenu(userId, menuId);
if (rows > 0) {
return AjaxResult.success("取消收藏成功");
} else {
return AjaxResult.error("未找到该收藏记录,取消失败");
}
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("取消收藏失败,请稍后重试");
}
}
/**
* 校验用户是否已收藏某菜单
*/
@Override
public AjaxResult checkCollect(Long menuId) {
// 参数非空校验
Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
try {
// 查询记录数0=未收藏1=已收藏
int count = menuCollectMapper.checkCollect(userId, menuId);
// 返回布尔状态方便前端判断
return AjaxResult.success(count > 0);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("校验收藏状态失败,请稍后重试");
}
}
@Override
public AjaxResult listByUser() {
// 1. 获取当前登录用户ID参数校验
Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
if (userId == null || userId <= 0) {
return AjaxResult.error("用户ID不合法");
}
try {
// 2. 基础查询仅查收藏列表基础信息无拼接MyBatis无任何异常
List<MenuCollect> collectList = menuCollectMapper.selectListByUserId(userId);
if (CollectionUtil.isEmpty(collectList)) {
return AjaxResult.success(Collections.emptyList()); // 空列表直接返回
}
// 3. 一次性查询所有菜单转为Mapkey=menuIdvalue=SysMenu避免循环查库
List<SysMenu> allMenuList = menuCollectMapper.selectAllMenu();
Map<Long, SysMenu> menuMap = allMenuList.stream()
.collect(Collectors.toMap(SysMenu::getMenuId, menu -> menu, (k1, k2) -> k1));
// 4. 核心遍历收藏列表Java层面拼接多级路由
collectList.forEach(collect -> {
String fullRoute = buildMenuRoute(collect.getMenuId(), collect.getMenuPath(), menuMap);
collect.setFullRoutePath(fullRoute); // 设置最终拼接的路由
// 清空临时属性可选避免返回前端多余字段
collect.setMenuPath(null);
collect.setMenuParentId(null);
});
// 5. 返回结果fullRoutePath即为标准的equipment/search/category格式
return AjaxResult.success(collectList);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询收藏列表失败,请稍后重试");
}
}
/**
* 统计菜单收藏人数
*/
@Override
public AjaxResult countByMenu(Long menuId) {
// 参数非空校验
if (menuId == null) {
return AjaxResult.error("菜单ID不能为空");
}
try {
// 统计收藏人数
int count = menuCollectMapper.selectCollectCountByMenuId(menuId);
return AjaxResult.success(count);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("统计收藏人数失败,请稍后重试");
}
}
/**
* 批量取消用户所有收藏
*/
@Override
public AjaxResult batchDeleteByUser() {
Long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
try {
// 执行批量删除
int rows = menuCollectMapper.deleteBatchByUserId(userId);
return AjaxResult.success("批量取消收藏成功,共删除" + rows + "条记录");
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("批量取消收藏失败,请稍后重试");
}
}
/**
* 递归拼接菜单多级路由核心方法
* @param currentMenuId 当前菜单ID
* @param currentPath 当前菜单原始path
* @param menuMap 所有菜单的Map集合key=menuId
* @return 标准路由equipment/search/category
*/
private String buildMenuRoute(Long currentMenuId, String currentPath, Map<Long, SysMenu> menuMap) {
// 1. 标准化当前path去除首尾/空值处理
String standardCurrentPath = StrUtil.trim(currentPath, '/');
if (StrUtil.isBlank(standardCurrentPath)) {
standardCurrentPath = "";
}
// 2. 获取当前菜单的父级ID
SysMenu currentMenu = menuMap.get(currentMenuId);
if (currentMenu == null || currentMenu.getParentId() == 0) {
// 无父级/顶级菜单parent_id=0直接返回当前标准化path
return standardCurrentPath;
}
// 3. 递归查询父级菜单的路由
SysMenu parentMenu = menuMap.get(currentMenu.getParentId());
if (parentMenu == null) {
// 父级菜单不存在脏数据返回当前标准化path
return standardCurrentPath;
}
String parentRoute = buildMenuRoute(parentMenu.getMenuId(), parentMenu.getPath(), menuMap);
// 4. 拼接父级路由和当前路由父级/当前如equipment/search + category equipment/search/category
if (StrUtil.isBlank(parentRoute)) {
return standardCurrentPath;
}
if (StrUtil.isBlank(standardCurrentPath)) {
return parentRoute;
}
return StrUtil.format("{}/{}", parentRoute, standardCurrentPath);
}
}

View File

@ -1,5 +1,7 @@
package com.bonus.material.toolLedger.controller;
import com.bonus.common.core.text.Convert;
import com.bonus.common.core.utils.ServletUtils;
import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult;
@ -15,6 +17,7 @@ import com.bonus.material.toolLedger.domain.ToolLedgerEntity;
import com.bonus.material.toolLedger.service.ToolLedgerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -145,19 +148,42 @@ public class ToolLedgerController extends BaseController {
}
/**
* 导出
*
* @param response
* @param entity
*/
@PostMapping("/export")
@SysLog(title = "编码工具台账", businessType = OperaType.EXPORT, logType = 0, module = "编码工具台账", details = "编码工具台账")
public void export(HttpServletResponse response, ToolLedgerEntity entity) {
List<ToolLedgerEntity> exportList;
// 1. 从请求中获取分页参数兼容前端GET/POST传参项目通用ServletUtils工具
Integer pageNum = Convert.toInt(ServletUtils.getParameter("pageNum"));
Integer pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"));
// 2. 核心判断分页参数是否有效非空+大于0有效则启动分页
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
startPage(); // 仅当分页参数有效时启动分页查询当前页
}
// 3. 查询数据service层无需修改分页插件自动判断是否分页
List<ToolLedgerEntity> list = toolLedgerService.export(entity);
TableDataInfo dataTable = getDataTable(list);
// 4. 根据分页参数获取对应导出数据
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
// 有有效分页参数 导出当前页取分页后的rows
exportList = (List<ToolLedgerEntity>) dataTable.getRows();
} else {
// 无分页参数/参数无效 导出全部直接使用全量查询结果
exportList = list;
}
try {
List<ToolLedgerEntity> list = toolLedgerService.listCode(entity);
ExcelUtil<ToolLedgerEntity> util = new ExcelUtil<ToolLedgerEntity>(ToolLedgerEntity.class);
util.exportExcel(response,list,"编码工具台账");
util.exportExcel(response, exportList, "编码工具台账");
} catch (Exception e) {
logger.error(e.toString(), e);
}
@ -165,22 +191,47 @@ public class ToolLedgerController extends BaseController {
/**
* 导出
*
* @param response
* @param entity
*/
@PostMapping("/exportAll")
@SysLog(title = "工具台账", businessType = OperaType.EXPORT, logType = 0, module = "工具台账", details = "工具台账")
public void export(HttpServletResponse response, ToolLedgerAllEntity entity) {
List<ToolLedgerAllEntity> exportList;
// 1. 从请求中获取分页参数兼容前端GET/POST传参项目通用ServletUtils工具
Integer pageNum = Convert.toInt(ServletUtils.getParameter("pageNum"));
Integer pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"));
// 2. 核心判断分页参数是否有效非空+大于0有效则启动分页
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
startPage(); // 仅当分页参数有效时启动分页查询当前页
}
// 3. 查询数据service层无需修改分页插件自动判断是否分页
List<ToolLedgerAllEntity> list = toolLedgerService.list(entity);
TableDataInfo dataTable = getDataTable(list);
// 4. 根据分页参数获取对应导出数据
if (ObjectUtils.isNotEmpty(pageNum) && ObjectUtils.isNotEmpty(pageSize)
&& pageNum > 0 && pageSize > 0) {
// 有有效分页参数 导出当前页取分页后的rows
exportList = (List<ToolLedgerAllEntity>) dataTable.getRows();
} else {
// 无分页参数/参数无效 导出全部直接使用全量查询结果
exportList = list;
}
exportList.stream()
.forEach(item -> {
String code = item.getManageMode();
String name = "0".equals(code) ? "编码工具" : "1".equals(code) ? "数量工具" : "未知管理模式";
item.setManageMode(name);
});
try {
List<ToolLedgerAllEntity> list = toolLedgerService.list(entity);
list.stream()
.forEach(item -> {
String code = item.getManageMode();
String name = "0".equals(code) ? "编码工具" : "1".equals(code) ? "数量工具" : "未知管理模式";
item.setManageMode(name);
});
ExcelUtil<ToolLedgerAllEntity> util = new ExcelUtil<ToolLedgerAllEntity>(ToolLedgerAllEntity.class);
util.exportExcel(response,list,"工具台账");
util.exportExcel(response, exportList, "编码工具台账");
} catch (Exception e) {
logger.error(e.toString(), e);
}

View File

@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
@ -46,9 +47,9 @@ public class ToolLedgerServiceImpl implements ToolLedgerService {
// && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
// entity.setCompanyId(deptId);
// }
if(ADMIN_ID.equals(userId)){
if (ADMIN_ID.equals(userId)) {
entity.setCompanyId(null);
}else{
} else {
entity.setCompanyId(deptId);
}
return mapper.list(entity);
@ -174,4 +175,21 @@ public class ToolLedgerServiceImpl implements ToolLedgerService {
}
return mapper.getToolByOrder(entity);
}
/**
* @param entity
* @return
*/
@Override
public List<ToolLedgerEntity> export(ToolLedgerEntity entity) {
Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
Long userId = SecurityUtils.getLoginUser().getUserid();
if (ADMIN_ID.equals(userId)) {
// 管理员可查看所有数据
entity.setCompanyId(null);
} else {
entity.setCompanyId(deptId);
}
return mapper.listCode(entity);
}
}

View File

@ -33,4 +33,6 @@ public interface ToolLedgerService {
List<ToolLedgerEntity> getToolByPro(ToolLedgerEntity entity);
List<ToolLedgerEntity> getToolByOrder(ToolLedgerEntity entity);
List<ToolLedgerEntity> export(ToolLedgerEntity entity);
}

View File

@ -679,7 +679,7 @@
AND mdi.change_status=#{status}
</if>
</where>
order by mdi.create_time desc
</select>
<select id="getField" resultType="com.bonus.material.device.domain.vo.DevInfoPropertyVo">
select sef.id AS id,

View File

@ -34,6 +34,7 @@
insert into iot_machine_bind
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="iotId != null">iot_id,</if>
<if test="maId != null and maId != ''">ma_id,</if>
<if test="typeName != null and typeName != ''">type_name,</if>
<if test="maCode != null and maCode != ''">ma_code,</if>
<if test="binder != null">binder,</if>
@ -41,6 +42,7 @@
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="iotId != null">#{iotId},</if>
<if test="maId != null and maId != ''">#{maId},</if>
<if test="typeName != null and typeName != ''">#{typeName},</if>
<if test="maCode != null and maCode != ''">#{maCode},</if>
<if test="binder != null">#{binder},</if>
@ -88,29 +90,33 @@
im.iot_manager AS iotManager,
im.address AS address,
im.bind_status AS bindStatus,
MAX(imb.bind_time) AS bindTime,
imb.bind_time AS bindTime,
imb.unbind_time AS unBindTime,
mdi.device_name AS typeName,
mdi.code AS maCode,
imb.id AS id,
im.remark AS remark,
CASE
WHEN MAX(imb.bind_time) IS NOT NULL THEN imb.unbind_time
ELSE NULL
END AS unBindTime,
CASE
WHEN MAX(imb.bind_time) IS NOT NULL AND im.bind_status = '0'
THEN imb.type_name
ELSE NULL
END AS typeName,
CASE
WHEN MAX(imb.bind_time) IS NOT NULL AND im.bind_status = '0'
THEN imb.ma_code
ELSE NULL
END AS maCode,
CASE
WHEN MAX(imb.bind_time) IS NOT NULL THEN imb.id
ELSE NULL
END AS id,
im.remark AS remark
WHEN mtv.actual_level = 5 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx,
mtv.childGx, mtv.devCategory, mtv.devSubcategory)
WHEN mtv.actual_level = 6 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx,
mtv.devCategory, mtv.devSubcategory, mtv.devName)
ELSE CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx, mtv.devCategory, mtv.devSubcategory)
END AS type,
jsp.pro_name AS proName,
mdi.ma_status AS maStatus
FROM
iot_machine im
LEFT JOIN iot_machine_bind imb on im.id = imb.iot_id
LEFT JOIN iot_machine_bind imb ON im.id = imb.iot_id
-- 核心条件匹配当前iot_id的最大绑定时间需替换为实际绑定时间字段名
AND imb.bind_time = (
SELECT MAX(t.bind_time)
FROM iot_machine_bind t
WHERE t.iot_id = imb.iot_id
) and imb.unbind_time is null
LEFT JOIN ma_dev_info mdi on mdi.ma_id = imb.ma_id
LEFT JOIN ma_type_view mtv on mtv.typeId = mdi.type_id
LEFT JOIN jj_sing_project jsp ON jsp.pro_code = mdi.on_project
WHERE
im.del_flag = '0'
<if test="keyWord != null and keyWord != ''">
@ -222,5 +228,78 @@
unbinder is null and unbind_time is null
AND ma_code = #{maCode}
</select>
<select id="getEquipment" resultType="com.bonus.material.deptConfig.domain.Equipment">
SELECT t.id,
t.category,
t.num,
t.type,
t.name,
t.specificationModel,
t.deviceCode,
t.originalEncoding,
t.proName,
t.maStatus
FROM (
SELECT mdi.ma_id AS id,
'0' AS category,
1 AS num,
CASE
WHEN mtv.actual_level = 5 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx,
mtv.childGx, mtv.devCategory, mtv.devSubcategory)
WHEN mtv.actual_level = 6 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx,
mtv.devCategory, mtv.devSubcategory, mtv.devName)
ELSE CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx, mtv.devCategory, mtv.devSubcategory)
END AS type,
mdi.device_name AS name,
mdi.item_type_model AS specificationModel,
mdi.code AS deviceCode,
mdi.identify_code AS originalEncoding,
jsp.pro_name AS proName,
mdi.ma_status AS maStatus,
mdi.type_id AS typeId,
imb.id AS imbId
FROM ma_dev_info mdi
LEFT JOIN ma_type_view mtv ON mtv.typeId = mdi.type_id
LEFT JOIN jj_sing_project jsp ON jsp.pro_code = mdi.on_project
LEFT JOIN iot_machine_bind imb ON imb.ma_id = mdi.ma_id AND imb.unbind_time is null
WHERE is_active = '1'
and entry_status = '1'
and ma_status != 99)t
<where>
t.imbId is null
<if test="name != null and name != ''">
AND t.name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="specificationModel != null and specificationModel != ''">
AND t.specificationModel LIKE CONCAT('%', #{specificationModel}, '%')
</if>
<if test="originalEncoding != null and originalEncoding != ''">
AND t.originalEncoding LIKE CONCAT('%', #{originalEncoding}, '%')
</if>
<if test="deviceCode != null and deviceCode != ''">
AND t.deviceCode LIKE CONCAT('%', #{deviceCode}, '%')
</if>
<if test="category != null and category != ''">
AND t.category = #{category}
</if>
<if test="typeId != null and typeId != ''">
AND t.typeId = #{typeId}
</if>
</where>
</select>
<select id="getCategoryList" resultType="java.util.Map">
-- 原SQL的第一部分设备5/6级节点
SELECT mtv.typeId AS typeId,
'0' AS type,
CASE
WHEN mtv.actual_level = 5 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx,
mtv.childGx, mtv.devCategory, mtv.devSubcategory)
WHEN mtv.actual_level = 6 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx,
mtv.devCategory, mtv.devSubcategory, mtv.devName)
ELSE CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx, mtv.devCategory, mtv.devSubcategory)
END AS equipmentName,
'施工装备' as devType
FROM ma_type_view mtv
</select>
</mapper>

View File

@ -464,49 +464,81 @@
</where>
</select>
<select id="getOwnEquipmentList" resultType="com.bonus.material.deptConfig.domain.Equipment">
SELECT mdi.ma_id AS id,
'0' AS category,
1 AS num,
CASE
WHEN mtv.actual_level = 5 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx,
mtv.childGx, mtv.devCategory, mtv.devSubcategory)
WHEN mtv.actual_level = 6 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx,
mtv.devCategory, mtv.devSubcategory, mtv.devName)
ELSE CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx, mtv.devCategory, mtv.devSubcategory)
END AS type,
mdi.device_name AS name,
mdi.item_type_model AS specificationModel,
mdi.code AS deviceCode,
mdi.identify_code AS originalEncoding
SELECT t.id,
t.category,
t.num,
t.type,
t.name,
t.specificationModel,
t.deviceCode,
t.originalEncoding
FROM (SELECT mdi.ma_id AS id,
'0' AS category,
1 AS num,
CASE
WHEN mtv.actual_level = 5 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx,
mtv.childGx, mtv.devCategory, mtv.devSubcategory)
WHEN mtv.actual_level = 6 THEN CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx,
mtv.devCategory, mtv.devSubcategory, mtv.devName)
ELSE CONCAT_WS('-', mtv.proType, mtv.mainGx, mtv.childGx, mtv.devCategory, mtv.devSubcategory)
END AS type,
mdi.device_name AS name,
mdi.item_type_model AS specificationModel,
mdi.code AS deviceCode,
mdi.identify_code AS originalEncoding
FROM ma_dev_info mdi
LEFT JOIN ma_type_view mtv ON mtv.typeId = mdi.type_id
LEFT JOIN ma_type_view mtv ON mtv.typeId = mdi.type_id
WHERE (mdi.on_company = #{deptId} OR mdi.on_company IN (SELECT t.dept_id
FROM sys_dept t
WHERE find_in_set(#{deptId},
ancestors)))
and is_active = '1'
and entry_status = '1'
and ma_status != 99
FROM sys_dept t
WHERE find_in_set(#{deptId},
ancestors)))
and is_active = '1'
and entry_status = '1'
and ma_status != 99
UNION ALL
SELECT tl.id AS id,
'1' AS category,
(tl.total_num - tl.scrap_num) AS num,
CONCAT_WS('-', tt4.type_name, tt3.type_name, tt2.type_name, tt1.type_name) AS type,
tt1.type_name AS name,
tt.type_name AS specificationModel,
tl.tool_code AS deviceCode,
tl.identify_code AS originalEncoding
SELECT tl.id AS id,
'1' AS category,
(tl.total_num - tl.scrap_num) AS num,
CONCAT_WS('-', tt4.type_name, tt3.type_name, tt2.type_name, tt1.type_name) AS type,
tt1.type_name AS name,
tt.type_name AS specificationModel,
tl.tool_code AS deviceCode,
tl.identify_code AS originalEncoding
FROM tool_ledger tl
LEFT JOIN tool_type tt ON tt.type_id = tl.type_id
LEFT JOIN tool_type tt1 ON tt.parent_id = tt1.type_id
LEFT JOIN tool_type tt2 ON tt1.parent_id = tt2.type_id
LEFT JOIN tool_type tt3 ON tt2.parent_id = tt3.type_id
LEFT JOIN tool_type tt4 ON tt3.parent_id = tt4.type_id
LEFT JOIN tool_type tt ON tt.type_id = tl.type_id
LEFT JOIN tool_type tt1 ON tt.parent_id = tt1.type_id
LEFT JOIN tool_type tt2 ON tt1.parent_id = tt2.type_id
LEFT JOIN tool_type tt3 ON tt2.parent_id = tt3.type_id
LEFT JOIN tool_type tt4 ON tt3.parent_id = tt4.type_id
WHERE tt.`level` = 5
AND (tl.company_id = #{deptId} OR tl.company_id IN (SELECT t.dept_id
FROM sys_dept t
WHERE find_in_set(#{deptId},
ancestors)))
AND (tl.company_id = #{deptId} OR tl.company_id IN (SELECT t.dept_id
FROM sys_dept t
WHERE find_in_set(#{deptId},
ancestors)))) t
<where>
<if test="name != null and name != ''">
AND t.name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="specificationModel != null and specificationModel != ''">
AND t.specificationModel LIKE CONCAT('%', #{specificationModel}, '%')
</if>
<if test="originalEncoding != null and originalEncoding != ''">
AND t.originalEncoding LIKE CONCAT('%', #{originalEncoding}, '%')
</if>
<if test="deviceCode != null and deviceCode != ''">
AND t.deviceCode LIKE CONCAT('%', #{deviceCode}, '%')
</if>
<if test="category != null and category != ''">
AND t.category = #{category}
</if>
<if test="type != null and type != ''">
AND t.type = #{type}
</if>
</where>
<!-- 可选:添加排序 -->
ORDER BY t.category ASC, t.name ASC
</select>
<select id="getSharingEquipmentList" resultType="com.bonus.material.deptConfig.domain.Equipment">
SELECT md.id AS id,

View File

@ -0,0 +1,76 @@
<?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 接口全类名一致 -->
<mapper namespace="com.bonus.material.menuCollect.mapper.MenuCollectMapper">
<!-- 通用结果集映射(字段与实体属性对应,避免重复编写) -->
<resultMap id="BaseResultMap" type="com.bonus.material.menuCollect.domain.MenuCollect">
<!-- 原有字段映射保持不变 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="menu_id" property="menuId"/>
<result column="collect_time" property="collectTime"/>
<result column="menu_name" property="menuName"/>
<!-- 新增菜单原始path和父级ID用于Java拼接路由 -->
<result column="path" property="menuPath"/>
<result column="parent_id" property="menuParentId"/>
<!-- 保留fullRoutePath映射接收Java拼接后的最终路由 -->
<result column="full_route_path" property="fullRoutePath"/>
</resultMap>
<!-- 新增菜单收藏collect_time 数据库自动填充,无需插入 -->
<insert id="insertMenuCollect" parameterType="com.bonus.material.menuCollect.domain.MenuCollect">
INSERT INTO sys_menu_collect (user_id, menu_id)
VALUES (#{userId}, #{menuId})
</insert>
<!-- 物理删除用户ID+菜单ID 精准删除 -->
<delete id="deleteByUserAndMenu">
DELETE
FROM sys_menu_collect
WHERE user_id = #{userId}
AND menu_id = #{menuId}
</delete>
<!-- 批量物理删除根据用户ID删除所有收藏 -->
<delete id="deleteBatchByUserId">
DELETE
FROM sys_menu_collect
WHERE user_id = #{userId}
</delete>
<!-- 校验收藏状态:查询记录数 -->
<select id="checkCollect" resultType="int">
SELECT COUNT(1)
FROM sys_menu_collect
WHERE user_id = #{userId}
AND menu_id = #{menuId}
</select>
<!-- 根据用户ID查询收藏列表 -->
<select id="selectListByUserId" resultMap="BaseResultMap">
SELECT smc.id,
smc.user_id,
smc.menu_id,
smc.collect_time,
sm.menu_name,
sm.path, -- 仅查当前菜单的原始path用于Java拼接
sm.parent_id -- 仅查当前菜单的父级ID用于追溯上级
FROM sys_menu_collect smc
LEFT JOIN sys_menu sm ON smc.menu_id = sm.menu_id
WHERE smc.user_id = #{userId}
ORDER BY smc.collect_time DESC
</select>
<!-- 统计菜单收藏人数 -->
<select id="selectCollectCountByMenuId" resultType="int">
SELECT COUNT(DISTINCT user_id)
FROM sys_menu_collect
WHERE menu_id = #{menuId}
</select>
<select id="selectAllMenu" resultType="com.bonus.system.api.domain.SysMenu">
SELECT menu_id AS menuId, parent_id AS parentId, path AS path
FROM sys_menu
</select>
</mapper>

View File

@ -585,7 +585,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
SELECT DISTINCT
t.equipmentName,
t.devType,
-- 新增:高亮标记后的名称(关键字用{{}}包裹)
<if test="keyWord != null and keyWord != ''">
REPLACE(t.equipmentName, #{keyWord}, CONCAT('{{', #{keyWord}, '}}')) AS highlightEquipmentName
</if>
@ -593,7 +592,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t.equipmentName AS highlightEquipmentName
</if>
FROM (
-- 原SQL的第一部分设备5/6级节点
SELECT
CASE
WHEN mtv.actual_level = 5 THEN CONCAT_WS('>', mtv.proType, mtv.mainGx, mtv.childGx,mtv.devCategory,mtv.devSubcategory)
@ -606,14 +604,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-- 原SQL的第二部分工具4级节点
SELECT
CONCAT_WS('>', tt4.type_name,tt3.type_name, tt2.type_name, tt1.type_name) AS equipmentName,
if(tt.manage_type =0,'编码工具','数量工具') as devType
FROM tool_type tt
LEFT JOIN tool_type tt1 ON tt.parent_id = tt1.type_id
'工具' as devType
FROM tool_type tt1
LEFT JOIN tool_type tt2 ON tt1.parent_id = tt2.type_id
LEFT JOIN tool_type tt3 ON tt2.parent_id = tt3.type_id
LEFT JOIN tool_type tt4 ON tt3.parent_id = tt4.type_id
WHERE tt.LEVEL = 5
AND tt.del_flag ='0'
WHERE tt1.LEVEL = 4
AND tt1.del_flag ='0'
AND tt2.del_flag ='0'
AND tt3.del_flag ='0'

View File

@ -95,19 +95,15 @@
AND tt2.del_flag = '0'
AND tt3.del_flag = '0'
AND tt4.del_flag = '0'
AND tt.manage_type = #{manageMode}
<if test="typeId != null and typeId != ''">
AND (tt1.type_id = #{typeId} or tt2.type_id = #{typeId} or tt3.type_id =
#{typeId} or tt4.type_id =#{typeId})
</if>
<if test="manageMode != null and manageMode != ''">
AND tt.manage_type = #{manageMode}
</if>
<if test="propertyUnitId != null and propertyUnitId != ''">
AND tl.company_id = #{propertyUnitId}
AND tl.company_id = #{propertyUnitId}
</if>
<if test="companyId != null and companyId != 1 ">
AND tl.company_id in (
select dept_id from sys_dept where dept_id= #{companyId}
@ -204,8 +200,8 @@
tl.create_time AS createTime,
tl.update_time AS updateTime
FROM
tool_type tt
LEFT JOIN tool_ledger tl ON tl.type_id = tt.type_id
tool_ledger tl
LEFT JOIN tool_type tt ON tl.type_id = tt.type_id
LEFT JOIN sys_dept sd ON sd.dept_id = tl.company_id
LEFT JOIN ma_supplier ms ON ms.supplier_id = tl.supplier_id
-- 关联1级父节点直接父节点
@ -253,7 +249,7 @@
)
</if>
ORDER BY
tl.create_time DESC
tl.create_time DESC ,sd.dept_id DESC
</select>
<!--