diff --git a/fys-common/fys-common-log/src/main/java/com/fuyuanshen/common/log/enums/BusinessType.java b/fys-common/fys-common-log/src/main/java/com/fuyuanshen/common/log/enums/BusinessType.java index bcd0100..65963be 100644 --- a/fys-common/fys-common-log/src/main/java/com/fuyuanshen/common/log/enums/BusinessType.java +++ b/fys-common/fys-common-log/src/main/java/com/fuyuanshen/common/log/enums/BusinessType.java @@ -37,7 +37,7 @@ public enum BusinessType { EXPORT, /** - * 导入 + * */ IMPORT, diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppBusinessFileMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppBusinessFileMapper.xml index ffd045d..71cb53d 100644 --- a/fys-modules/fys-app/src/main/resources/mapper/app/AppBusinessFileMapper.xml +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppBusinessFileMapper.xml @@ -6,15 +6,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceAPPController.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceAPPController.java index bf01dd8..e99b139 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceAPPController.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceAPPController.java @@ -6,17 +6,17 @@ import com.fuyuanshen.common.core.validate.EditGroup; import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; import com.fuyuanshen.common.log.annotation.Log; import com.fuyuanshen.common.log.enums.BusinessType; -import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.bo.UserAppBo; -import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.service.AppUserService; -import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** * @Description: diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java index 2d22b9e..4b384fc 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java @@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fuyuanshen.common.core.domain.model.LoginUser; +import com.fuyuanshen.common.core.exception.BadRequestException; +import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.satoken.utils.AppLoginHelper; @@ -42,6 +44,7 @@ import com.fuyuanshen.system.domain.vo.SysOssVo; import com.fuyuanshen.system.service.ISysOssService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -54,6 +57,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Objects; /** * @Description: @@ -272,20 +276,23 @@ public class DeviceServiceImpl extends ServiceImpl impleme public void deleteAll(List ids) { List invalidIds = new ArrayList<>(); + for (Long id : ids) { + DeviceAssignments deviceAssignment = deviceAssignmentsMapper.selectById(id); + Device deviceType = deviceMapper.selectById(deviceAssignment.getDeviceId()); + + if (StringUtils.isNotEmpty(deviceAssignment.getAssigneeName())) { + throw new BadRequestException(deviceType.getDeviceName() + ":设备已分配,请先解绑设备!!!"); + } + + // 接收者 + if (Objects.equals(deviceAssignment.getAssigneeId(), deviceType.getOriginalOwnerId())) { + invalidIds.add(deviceAssignment.getDeviceId()); + } + + } + deviceAssignmentsMapper.deleteByIds(ids); - // - // for (Long id : ids) { - // - // Device deviceType = deviceMapper.selectById(id); - // if (deviceType == null || !Objects.equals(deviceType.getCurrentOwnerId(), LoginHelper.getUserId())) { - // invalidIds.add(id); - // } - // } - // if (!invalidIds.isEmpty()) { - // throw new RuntimeException("以下设备无法删除(ID 不存在或无权限): " + invalidIds); - // } - // - // deviceMapper.deleteByIds(ids); + deviceMapper.deleteByIds(invalidIds); } @@ -573,7 +580,6 @@ public class DeviceServiceImpl extends ServiceImpl impleme } - /** * 查询设备MAC号 * diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ReliableTextToBitmap.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ReliableTextToBitmap.java new file mode 100644 index 0000000..bde75c7 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/utils/c/ReliableTextToBitmap.java @@ -0,0 +1,239 @@ +package com.fuyuanshen.equipment.utils.c; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 可靠点阵生成工具 - 终极版 + * + * @author: 默苍璃 + * @date: 2025-07-15 + */ +public class ReliableTextToBitmap { + + public static void main(String[] args) throws IOException { + String unit = "繁體繁體繁體"; + String department = "A研B发C"; + String name = "12李34四56"; + + byte[] unitBytes = textToBitmapBytes(unit); + byte[] deptBytes = textToBitmapBytes(department); + byte[] nameBytes = textToBitmapBytes(name); + + generateCFile(unitBytes, deptBytes, nameBytes, "display_data.c"); + + // 生成预览图片 + generatePreviewImage(unitBytes, "unit_image.png"); + generatePreviewImage(deptBytes, "department_image.png"); + generatePreviewImage(nameBytes, "name_image.png"); + } + + // 专门生成预览图片的方法 + private static void generatePreviewImage(byte[] data, String filename) { + try { + BufferedImage image = convertByteArrayToImage(data, 12); + ImageIO.write(image, "PNG", new File(filename)); + System.out.println("成功生成预览图片: " + filename); + } catch (IOException e) { + System.err.println("图片生成失败: " + e.getMessage()); + } + } + + /** + * 可靠的字节数组转图像方法 + */ + public static BufferedImage convertByteArrayToImage(byte[] data, int height) { + if (data == null || data.length == 0) { + return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + } + + // 计算宽度 + int width = (data.length * 8) / height; + + // 创建RGB图像 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + // 设置白色背景 + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + image.setRGB(x, y, Color.WHITE.getRGB()); + } + } + + // 直接设置像素点 + int bitIndex = 0; + for (int i = 0; i < data.length; i++) { + int value = data[i] & 0xFF; + for (int bit = 7; bit >= 0; bit--) { // 高位在前 + boolean isBlack = ((value >> bit) & 1) == 1; + if (isBlack) { + int x = bitIndex % width; + int y = bitIndex / width; + if (y < height) { // 确保不越界 + image.setRGB(x, y, Color.BLACK.getRGB()); + } + } + bitIndex++; + } + } + + return image; + } + + /** + * 可靠的点阵生成方法 + */ + public static byte[] textToBitmapBytes(String text) { + if (text == null || text.isEmpty()) { + return new byte[0]; + } + + // 1. 创建画布 - 使用RGB类型避免问题 + Font font = new Font("宋体", Font.PLAIN, 12); + BufferedImage image = createTextImage(text, font); + + // 2. 直接提取点阵数据 + return extractBitmapData(image); + } + + /** + * 创建文本图像 - 最可靠的方法 + */ + private static BufferedImage createTextImage(String text, Font font) { + // 创建临时图像获取字体度量 + BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + Graphics2D tempG = tempImage.createGraphics(); + tempG.setFont(font); + FontMetrics metrics = tempG.getFontMetrics(); + + // 计算文本宽度 + int totalWidth = metrics.stringWidth(text); + + // 宽度对齐到8的倍数 + int width = (int) Math.ceil(totalWidth / 8.0) * 8; + int height = 12; + + // 创建RGB图像 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + + // 设置白色背景 + g.setColor(Color.WHITE); + g.fillRect(0, 0, width, height); + + // 设置黑色文本 + g.setColor(Color.BLACK); + g.setFont(font); + + // 关闭抗锯齿 - 确保清晰度 + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + + // 绘制文本 - 精确居中 + int y = (height - metrics.getHeight()) / 2 + metrics.getAscent(); + g.drawString(text, 0, y); + + g.dispose(); + tempG.dispose(); + + return image; + } + + /** + * 提取点阵数据 - 简单可靠的方法 + */ + private static byte[] extractBitmapData(BufferedImage image) { + int width = image.getWidth(); + int height = image.getHeight(); + + List byteList = new ArrayList<>(); + int currentByte = 0; + int bitCount = 0; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + // 获取像素颜色 + Color color = new Color(image.getRGB(x, y)); + + // 简单阈值判断 - 灰度小于128为黑色 + int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3; + boolean isBlack = gray < 128; + + // 高位优先打包 + currentByte = (currentByte << 1) | (isBlack ? 1 : 0); + bitCount++; + + if (bitCount == 8) { + byteList.add((byte) currentByte); + currentByte = 0; + bitCount = 0; + } + } + } + + // 处理最后不满8位的部分 + if (bitCount > 0) { + currentByte <<= (8 - bitCount); + byteList.add((byte) currentByte); + } + + return byteListToArray(byteList); + } + + private static byte[] byteListToArray(List byteList) { + byte[] result = new byte[byteList.size()]; + for (int i = 0; i < byteList.size(); i++) { + result[i] = byteList.get(i); + } + return result; + } + + public static void generateCFile(byte[] unit, byte[] department, byte[] name, String filename) throws IOException { + try (FileWriter writer = new FileWriter(filename)) { + writer.write("/**\n"); + writer.write(" * 点阵显示数据 - 可靠生成\n"); + writer.write(" * 宽度计算公式: width = (数组长度 * 8) / 12\n"); + writer.write(" */\n\n"); + writer.write("#include \n\n"); + + // 单位数据 + writer.write(String.format("// 单位: %d 字节, 宽度: %d 像素\n", + unit.length, (unit.length * 8) / 12)); + writer.write("const uint8_t unit[] = {\n "); + writeByteArray(writer, unit); + writer.write("\n};\n\n"); + + // 部门数据 + writer.write(String.format("// 部门: %d 字节, 宽度: %d 像素\n", + department.length, (department.length * 8) / 12)); + writer.write("const uint8_t department[] = {\n "); + writeByteArray(writer, department); + writer.write("\n};\n\n"); + + // 姓名数据 + writer.write(String.format("// 姓名: %d 字节, 宽度: %d 像素\n", + name.length, (name.length * 8) / 12)); + writer.write("const uint8_t name[] = {\n "); + writeByteArray(writer, name); + writer.write("\n};\n"); + } + } + + private static void writeByteArray(FileWriter writer, byte[] data) throws IOException { + for (int i = 0; i < data.length; i++) { + int value = data[i] & 0xFF; + writer.write(String.format("0x%02X", value)); + + if (i < data.length - 1) { + writer.write(", "); + if ((i + 1) % 12 == 0) writer.write("\n "); + } + } + } +} \ No newline at end of file