Commit 378a769f by HlQ

[add]

1.添加设备管理模块
2.工单管理添加编辑接口
[chg] 代码优化
1 parent 85f852be
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.dto.DeviceDTO;
import vion.service.IDeviceService;
import vion.vo.DeviceVO;
import java.util.List;
/**
* 设备管理
*/
@RestController
@RequestMapping("/api/device")
@RequiredArgsConstructor
public class DeviceController {
private final IDeviceService deviceService;
@GetMapping
@SaCheckPermission(value = "device:list", orRole = "admin")
public Page<DeviceVO> list(DeviceDTO dto) {
return deviceService.list(dto);
}
@GetMapping("/{id}")
@SaCheckPermission(value = "device:query", orRole = "admin")
public DeviceVO getById(@PathVariable Long id) {
return deviceService.getById(id);
}
@PostMapping
@SaCheckPermission(value = "device:edit", orRole = "admin")
public String update(@RequestBody List<DeviceDTO> dtoList) {
return deviceService.update(dtoList);
}
@PostMapping("/single")
@SaCheckPermission(value = "device:save", orRole = "admin")
public String save(@RequestBody DeviceDTO dto) {
return deviceService.save(dto);
}
@PostMapping("/batch")
@SaCheckPermission(value = "device:saveBatch", orRole = "admin")
public String saveBatch(@RequestBody List<DeviceDTO> dtoList) {
return deviceService.saveBatch(dtoList);
}
}
......@@ -96,7 +96,7 @@ public class FileController {
}
@PostMapping("/file/{id}")
@SaCheckPermission(value = "file:update", orRole = "admin")
@SaCheckPermission(value = "file:edit", orRole = "admin")
public String updateFile(@PathVariable Long id, @RequestBody FileInfoDTO dto) {
Assert.notNull(dto.getUpdFlag(), "更新标识符不能为空!");
return fileService.lambdaUpdate()
......
......@@ -60,6 +60,12 @@ public class TaskController {
return taskService.circTask(data);
}
@PostMapping("/task/{id}")
@SaCheckPermission(value = "task:edit", orRole = "admin")
public String updById(@PathVariable Long id, TaskDTO data) {
return taskService.updById(id, data);
}
@GetMapping("/faultLogs")
@SaCheckPermission(value = "task:log:list", orRole = "admin")
public List<FaultLog> getFaultLogById(Long storeId, Long taskId) {
......
package vion.dto;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Getter
@Setter
public class DeviceDTO extends BaseDTO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 合同名称
*/
private String contractName;
/**
* 设备序列号
*/
private String serialNum;
/**
* 设备mac地址
*/
private String mac;
/**
* 设备id
*/
private String deviceId;
/**
* 物料编号
*/
private String materialNum;
/**
* 生产部门
*/
private String prodSector;
/**
* 状态:入库1、出库2、维修3、借测4、废弃5
*/
private Integer status;
/**
* 入库日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date recDate;
/**
* 备注
*/
private String remark;
/**
* 当前操作人
*/
private Long userId;
}
\ No newline at end of file
package vion.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import vion.model.DeviceLog;
/**
* @author HlQ
* @date 2024/8/12
*/
public interface DeviceLogMapper extends BaseMapper<DeviceLog> {
}
\ No newline at end of file
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Device;
/**
* @author HlQ
* @date 2024/8/12
*/
public interface DeviceMapper extends MPJBaseMapper<Device> {
}
\ No newline at end of file
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.DeviceDTO;
import vion.vo.DeviceVO;
import java.util.Date;
/**
* 设备表
*/
@Data
@TableName(value = "tbl_device")
@AutoMappers({
@AutoMapper(target = DeviceVO.class),
@AutoMapper(target = DeviceDTO.class),
})
public class Device {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 合同编号
*/
@TableField(value = "contract_no", condition = SqlCondition.LIKE)
private String contractNo;
/**
* 设备序列号
*/
@TableField(value = "serial_num", condition = SqlCondition.LIKE)
private String serialNum;
/**
* 设备mac地址
*/
@TableField(value = "mac", condition = SqlCondition.LIKE)
private String mac;
/**
* 设备id
*/
@TableField(value = "device_id", condition = SqlCondition.LIKE)
private String deviceId;
/**
* 物料编号
*/
@TableField(value = "material_num", condition = SqlCondition.LIKE)
private String materialNum;
/**
* 生产部门
*/
@TableField(value = "prod_sector")
private String prodSector;
/**
* 状态:入库、出库、维修、借测、废弃
*/
@TableField(value = "\"status\"")
private Integer status;
/**
* 入库日期
*/
@TableField(value = "rec_date")
private Date recDate;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
\ No newline at end of file
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* @author HlQ
* @date 2024/8/12
*/
/**
* 设备变更日志表
*/
@Data
@TableName(value = "tbl_device_log")
public class DeviceLog {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 设备表的主键id
*/
@TableField(value = "device_id")
private Long deviceId;
/**
* 操作人
*/
@TableField(value = "\"operator\"")
private Long operator;
/**
* 操作内容
*/
@TableField(value = "content")
private String content;
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}
\ No newline at end of file
package vion.service;
import com.baomidou.mybatisplus.extension.service.IService;
import vion.model.DeviceLog;
/**
* @author HlQ
* @date 2024/8/12
*/
public interface IDeviceLogService extends IService<DeviceLog>{
}
package vion.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.DeviceDTO;
import vion.model.Device;
import vion.vo.DeviceVO;
import java.util.List;
/**
* @author HlQ
* @date 2024/8/12
*/
public interface IDeviceService extends MPJBaseService<Device> {
Page<DeviceVO> list(DeviceDTO dto);
DeviceVO getById(Long id);
String update(List<DeviceDTO> dtoList);
String save(DeviceDTO dto);
String saveBatch(List<DeviceDTO> dtoList);
}
......@@ -18,6 +18,8 @@ public interface ITaskService extends MPJBaseService<Task> {
Long circTask(TaskDTO data);
String updById(Long id, TaskDTO data);
String batchIns(List<TaskDTO> data);
TaskVO getTaskByUuid(String uuid);
......
package vion.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import vion.mapper.DeviceLogMapper;
import vion.model.DeviceLog;
import vion.service.IDeviceLogService;
/**
* @author HlQ
* @date 2024/8/12
*/
@Service
public class DeviceLogServiceImpl extends ServiceImpl<DeviceLogMapper, DeviceLog> implements IDeviceLogService {
}
package vion.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.dto.DeviceDTO;
import vion.mapper.DeviceMapper;
import vion.model.Contract;
import vion.model.Device;
import vion.model.DeviceLog;
import vion.service.IDeviceLogService;
import vion.service.IDeviceService;
import vion.vo.DeviceVO;
import java.util.List;
/**
* @author HlQ
* @date 2024/8/12
*/
@Service
@RequiredArgsConstructor
public class IDeviceServiceImpl extends MPJBaseServiceImpl<DeviceMapper, Device> implements IDeviceService {
private final IDeviceLogService deviceLogService;
private final Converter converter;
@Override
public Page<DeviceVO> list(DeviceDTO dto) {
var wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Device.class))
.selectAll(Device.class)
.selectAs(Contract::getName, DeviceVO::getContractName)
.leftJoin(Contract.class, Contract::getContractNo, Device::getContractNo)
.like(Contract::getName, dto.getContractName())
.orderByDesc(Device::getRecDate);
return this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), DeviceVO.class, wrapper);
}
@Override
public DeviceVO getById(Long id) {
var wrapper = new MPJLambdaWrapper<Device>()
.selectAll(Device.class)
.selectAs(Contract::getName, DeviceVO::getContractName)
.selectCollection(DeviceLog.class, DeviceVO::getLogList)
.leftJoin(DeviceLog.class, DeviceLog::getDeviceId, Device::getId)
.leftJoin(Contract.class, Contract::getContractNo, Device::getContractNo)
.orderByDesc(Device::getRecDate);
return this.selectJoinOne(DeviceVO.class, wrapper);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String update(List<DeviceDTO> dtoList) {
if (this.updateBatchById(converter.convert(dtoList, Device.class))) {
var logList = dtoList.stream()
.map(dto -> {
var deviceLog = new DeviceLog();
deviceLog.setDeviceId(dto.getId());
deviceLog.setOperator(dto.getUserId());
deviceLog.setContent(getStatusStr(dto.getStatus()));
return deviceLog;
}).toList();
deviceLogService.saveBatch(logList);
return "更新成功";
}
return "更新失败";
}
@Override
public String save(DeviceDTO dto) {
// 只有出库才允许单个设备录入
if (ObjUtil.notEquals(dto.getStatus(), 2)) {
return "该设备状态限制,不支持录入";
}
var device = converter.convert(dto, Device.class);
if (this.save(device)) {
var deviceLog = new DeviceLog();
deviceLog.setDeviceId(device.getId());
deviceLog.setOperator(dto.getUserId());
deviceLog.setContent(getStatusStr(dto.getStatus()));
deviceLogService.save(deviceLog);
return "保存成功";
}
return "保存失败";
}
@Override
@Transactional(rollbackFor = Exception.class)
public String saveBatch(List<DeviceDTO> dtoList) {
if (CollUtil.isEmpty(dtoList)) {
return "录入设备为空";
}
var userId = dtoList.getFirst().getUserId();
var deviceList = converter.convert(dtoList, Device.class);
if (this.saveBatch(deviceList)) {
var logList = deviceList.stream()
.map(d -> {
var deviceLog = new DeviceLog();
deviceLog.setDeviceId(d.getId());
deviceLog.setOperator(userId);
deviceLog.setContent(getStatusStr(d.getStatus()));
return deviceLog;
}).toList();
deviceLogService.saveBatch(logList);
return "保存成功";
}
return "保存失败";
}
private String getStatusStr(Integer status) {
return switch (status) {
case 1 -> "设备:入库";
case 2 -> "设备:出库";
case 3 -> "设备:维修";
case 4 -> "设备:借测";
case 5 -> "设备:废弃";
default -> "未知操作";
};
}
}
......@@ -29,6 +29,7 @@ import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vion.constant.RedisKeyEnum;
import vion.dto.TaskDTO;
import vion.mapper.TaskMapper;
......@@ -64,8 +65,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
@Override
public Page<TaskVO> getTaskList(TaskDTO data) {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
var taskIdSet = getTaskIdSet(userVO);
var taskIdSet = getTaskIdSet();
var wrapper = new MPJLambdaWrapper<>(converter.convert(data, Task.class))
.selectAll(Task.class)
......@@ -96,10 +96,11 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
/**
* 根据当前登录用户,判断其权限和其参与过的工单,获取工单id集合
*
* @param userVO 当前登录用户
* @return java.util.Set<java.lang.Long>
*/
private Set<Long> getTaskIdSet(UserVO userVO) {
private Set<Long> getTaskIdSet() {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
Set<Long> taskIdSet = SetUtil.zero();
Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
......@@ -155,13 +156,29 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
handleTaskTemp(data);
Task task = prepareTask(data, user, store);
sendNotifications(task, user, store);
handleFiles(data, task, user);
handleFiles(data.getFiles(), task, user);
return task.getId();
/**
* fixme
* 1.修改工单的所属项目,工单的日志和文件查询不到
* 2.任然会推送一次钉钉提醒
*/
}
@Override
@Transactional(rollbackFor = Exception.class)
public String updById(Long id, TaskDTO data) {
var taskId = data.getId();
var curTask = this.getById(taskId);
Task task = converter.convert(data, Task.class);
var updFlag = this.updateById(task);
handleFiles(data.getFiles(), task, (UserVO) StpUtil.getTokenSession().get("curLoginUser"));
if (updFlag
&& ObjUtil.isNotNull(data.getStoreId())
&& ObjUtil.notEquals(data.getStoreId(), curTask.getStoreId())) {
faultLogService.lambdaUpdate().set(FaultLog::getStoreId, data.getStoreId()).eq(FaultLog::getTaskId, taskId).update();
fileService.lambdaUpdate().set(FileInfo::getStoreId, data.getStoreId()).eq(FileInfo::getSourceId, taskId).update();
return "更新工单及关联数据成功";
} else if (updFlag) {
return "更新成功";
} else {
return "更新失败";
}
}
/**
......@@ -337,19 +354,19 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
/**
* 文件处理
*
* @param data 前端传参
* @param files 文件列表
* @param task 工单
* @param user 当前登录用户
*/
private void handleFiles(TaskDTO data, Task task, UserVO user) {
Opt.ofNullable(data.getFiles())
private void handleFiles(MultipartFile[] files, Task task, UserVO user) {
Opt.ofNullable(files)
.ifPresent(fileList ->
Arrays.stream(fileList).forEach(infile -> {
String orgName = infile.getOriginalFilename();
String mainName = FileNameUtil.mainName(orgName);
String fileExt = FileNameUtil.extName(orgName);
String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmssSSS"), fileExt);
String path = fileUrl + FileUtil.FILE_SEPARATOR + data.getStoreId() + FileUtil.FILE_SEPARATOR + task.getId() + FileUtil.FILE_SEPARATOR + filename;
String path = fileUrl + FileUtil.FILE_SEPARATOR + task.getStoreId() + FileUtil.FILE_SEPARATOR + task.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path);
try {
infile.transferTo(file);
......
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import vion.model.DeviceLog;
import java.util.Date;
import java.util.List;
@Getter
@Setter
public class DeviceVO {
private Long id;
/**
* 合同编号
*/
private String contractNo;
/**
* 合同名称
*/
private String contractName;
/**
* 设备序列号
*/
private String serialNum;
/**
* 设备mac地址
*/
private String mac;
/**
* 设备id
*/
private String deviceId;
/**
* 物料编号
*/
private String materialNum;
/**
* 生产部门
*/
private String prodSector;
/**
* 状态:入库、出库、维修、借测、废弃
*/
private Integer status;
/**
* 入库日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date recDate;
/**
* 备注
*/
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
private List<DeviceLog> logList;
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!