/*
* Copyright 2016-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.pnoker.center.manager.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.pnoker.center.manager.entity.query.DevicePageQuery;
import io.github.pnoker.center.manager.mapper.DeviceMapper;
import io.github.pnoker.center.manager.service.*;
import io.github.pnoker.common.entity.common.Pages;
import io.github.pnoker.common.enums.MetadataCommandTypeEnum;
import io.github.pnoker.common.exception.*;
import io.github.pnoker.common.model.*;
import io.github.pnoker.common.utils.JsonUtil;
import io.github.pnoker.common.utils.PoiUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* DeviceService Impl
*
* @author pnoker
* @since 2022.1.0
*/
@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {
@Resource
private DeviceMapper deviceMapper;
@Resource
private DriverAttributeService driverAttributeService;
@Resource
private DriverAttributeConfigService driverAttributeConfigService;
@Resource
private PointAttributeService pointAttributeService;
@Resource
private PointAttributeConfigService pointAttributeConfigService;
@Resource
private ProfileService profileService;
@Resource
private PointService pointService;
@Resource
private ProfileBindService profileBindService;
@Resource
private NotifyService notifyService;
/**
* {@inheritDoc}
*/
@Override
public void add(Device entityDO) {
if (deviceMapper.insert(entityDO) < 1) {
throw new AddException("The device {} add failed", entityDO.getDeviceName());
}
addProfileBind(entityDO.getId(), entityDO.getProfileIds());
// 通知驱动新增
Device device = deviceMapper.selectById(entityDO.getId());
List<Profile> profiles = profileService.selectByDeviceId(entityDO.getId());
// ?/pnoker 同步给驱动的设备需要profile id set吗
device.setProfileIds(profiles.stream().map(Profile::getId).collect(Collectors.toSet()));
notifyService.notifyDriverDevice(MetadataCommandTypeEnum.ADD, device);
}
/**
* {@inheritDoc}
*/
@Override
@Transactional
public void delete(String id) {
Device device = selectById(id);
if (ObjectUtil.isNull(device)) {
throw new NotFoundException("The device does not exist");
}
if (!profileBindService.deleteByDeviceId(id)) {
throw new DeleteException("The profile bind delete failed");
}
if (deviceMapper.deleteById(id) < 1) {
throw new DeleteException("The device delete failed");
}
// 通知驱动删除设备
notifyService.notifyDriverDevice(MetadataCommandTypeEnum.DELETE, device);
}
/**
* {@inheritDoc}
*/
@Override
public void update(Device entityDO) {
selectById(entityDO.getId());
Set<String> newProfileIds = ObjectUtil.isNotNull(entityDO.getProfileIds()) ? entityDO.getProfileIds() : new HashSet<>();
Set<String> oldProfileIds = profileBindService.selectProfileIdsByDeviceId(entityDO.getId());
// 新增的模板
Set<String> add = new HashSet<>(newProfileIds);
add.removeAll(oldProfileIds);
// 删除的模板
Set<String> delete = new HashSet<>(oldProfileIds);
delete.removeAll(newProfileIds);
addProfileBind(entityDO.getId(), add);
delete.forEach(profileId -> profileBindService.deleteByDeviceIdAndProfileId(entityDO.getId(), profileId));
entityDO.setOperateTime(null);
if (deviceMapper.updateById(entityDO) < 1) {
throw new UpdateException("The device update failed");
}
Device select = deviceMapper.selectById(entityDO.getId());
select.setProfileIds(newProfileIds);
entityDO.setDeviceName(select.getDeviceName());
// 通知驱动更新设备
notifyService.notifyDriverDevice(MetadataCommandTypeEnum.UPDATE, select);
}
/**
* {@inheritDoc}
*/
@Override
public Device selectById(String id) {
Device device = deviceMapper.selectById(id);
if (ObjectUtil.isNull(device)) {
throw new NotFoundException();
}
device.setProfileIds(profileBindService.selectProfileIdsByDeviceId(id));
return device;
}
/**
* {@inheritDoc}
*/
@Override
public Device selectByName(String name, String tenantId) {
LambdaQueryWrapper<Device> queryWrapper = Wrappers.<Device>query().lambda();
queryWrapper.eq(Device::getDeviceName, name);
queryWrapper.eq(Device::getTenantId, tenantId);
queryWrapper.last("limit 1");
Device device = deviceMapper.selectOne(queryWrapper);
if (ObjectUtil.isNull(device)) {
throw new NotFoundException();
}
device.setProfileIds(profileBindService.selectProfileIdsByDeviceId(device.getId()));
return device;
}
/**
* {@inheritDoc}
*/
@Override
public List<Device> selectByDriverId(String driverId) {
DevicePageQuery devicePageQuery = new DevicePageQuery();
devicePageQuery.setDriverId(driverId);
List<Device> devices = deviceMapper.selectList(fuzzyQuery(devicePageQuery));
if (ObjectUtil.isNull(devices) || devices.isEmpty()) {
throw new NotFoundException();
}
devices.forEach(device -> device.setProfileIds(profileBindService.selectProfileIdsByDeviceId(device.getId())));
return devices;
}
/**
* {@inheritDoc}
*/
@Override
public List<Device> selectByProfileId(String profileId) {
return selectByIds(profileBindService.selectDeviceIdsByProfileId(profileId));
}
/**
* {@inheritDoc}
*/
@Override
public List<Device> selectByIds(Set<String> ids) {
List<Device> devices = deviceMapper.selectBatchIds(ids);
if (CollUtil.isEmpty(devices)) {
throw new NotFoundException();
}
devices.forEach(device -> device.setProfileIds(profileBindService.selectProfileIdsByDeviceId(device.getId())));
return devices;
}
/**
* {@inheritDoc}
*/
@Override
public Page<Device> list(DevicePageQuery queryDTO) {